Commit af87de2a authored by Killian Lufau's avatar Killian Lufau

Add testing of HMAC

parent 0f77428d
......@@ -2,6 +2,7 @@
import argparse, math, nemu, os, re, signal
import socket, subprocess, sys, time, weakref
from collections import defaultdict
from threading import Thread
IPTABLES = 'iptables'
SCREEN = 'screen'
VERBOSE = 4
......@@ -46,6 +47,8 @@ parser.add_argument('-d', '--duration', type = int,
help = 'time of the demo execution in seconds')
parser.add_argument('-p', '--ping', action = 'store_true',
help = 'execute ping utility')
parser.add_argument('-m', '--hmac', action = 'store_true',
help = 'execute HMAC test')
args = parser.parse_args()
def handler(signum, frame):
......@@ -259,6 +262,68 @@ if args.ping:
name = 'm' + machine.short if machine.short != 'R' else 'registry'
machine.screen('python ping.py {} {}'.format(name, ' '.join(ips)))
class testHMAC(Thread):
def run(self):
'''
# Starting from an empty HMAC conf, introduce new key on the network
# along with ignore_no_hmac option to see if machine 4 can join the
# network if it was down when the networks parameters were propagated
time.sleep(30)
test_hmac.killRe6st('m4')
registry.screen('wget 10.0.0.2/updateHMAC')
print 'Updated HMAC on registry, waiting for machines to get new conf'
time.sleep(30)
print 'Checking HMAC on machines, m4 is ignored..'
test_hmac.checkDB()
test_hmac.checkBabel()
re6stnet(machine4, 'm4', '-i%s' % m4_if_0.name)
print 'Started re6st on machine 4, waiting for it to get new conf'
time.sleep(30)
print 'Checking HMAC on machines...'
test_hmac.checkDB()
test_hmac.checkBabel()
# Remove ignore_no_hmac option
time.sleep(30)
registry.screen('wget 10.0.0.2/updateHMAC')
print 'Updated HMAC on registry, waiting for machines to get new conf..'
time.sleep(30)
print 'Checking HMAC on machines...'
test_hmac.checkDB()
test_hmac.checkBabel()
'''
# Test that machines can join the network (hence get the new config)
# when they reboot and that their hmac config is incompatible with
# the other machines. The conf at this point should only contain 1 hmac.
time.sleep(30)
test_hmac.killRe6st('m5')
registry.screen('wget 10.0.0.2/updateHMAC')
print 'Updated HMAC on registry, waiting for machines to get new conf..'
time.sleep(30)
print 'Checking HMAC on machine, m5 is ignored..'
test_hmac.checkDB()
test_hmac.checkBabel()
print 'Wait to make sure all nodes are ok before changing hmac again'
time.sleep(30)
registry.screen('wget 10.0.0.2/updateHMAC')
print 'Updated HMAC on registry, waiting for machines to get new conf..'
time.sleep(30)
print 'Checking HMAC on machines, m5 is ignored...'
test_hmac.checkDB()
test_hmac.checkBabel()
re6stnet(machine5, 'm5', '-i%s' % m5_if_0.name)
print 'Started re6st on machine 5, waiting for it to get new conf'
time.sleep(30)
print 'Checking HMAC on machines...'
test_hmac.checkDB()
test_hmac.checkBabel()
if args.hmac:
import test_hmac
testHMAC().start()
_ll = {}
def node_by_ll(addr):
try:
......
import sqlite3, subprocess
MACHINES = {'m1': '2001:db8:42:1::1', 'm2': '2001:db8:42:2::1',
'm3': '2001:db8:42:3::1', 'm4': '2001:db8:42:4::1',
'm5': '2001:db8:42:5::1', 'm6': '2001:db8:42:6::1',
'm7': '2001:db8:42:7::1', 'm8': '2001:db8:42:8::1',
'registry': '2001:db8:42::1'}
reg_db = sqlite3.connect('registry/registry.db', isolation_level=None,
check_same_thread=False)
reg_db.text_factory = str
network = '001000000000000100001101101110000000000001000010'
def getConfig(db, name):
r, = next(db.execute(
"SELECT value FROM config WHERE name=?", (name,)), (None,))
if r is not None:
r = str(r).encode('hex')
return r
def getCurrentHmacs():
true_hmacs = {'babel_hmac0': None, 'babel_hmac1': None, 'babel_hmac2': None}
for k in true_hmacs.keys():
true_hmacs[k] = getConfig(reg_db, k)
return true_hmacs
def killRe6st(machine):
p = subprocess.Popen(['pgrep', '-f', 'set ./py re6stnet @%s' %machine],
stdout=subprocess.PIPE)
ps_id = p.communicate()[0].split('\n', 1)[0]
if ps_id:
subprocess.Popen(['kill', ps_id])
print 'killed re6st on ' + machine
def checkDB(machines=MACHINES):
rc = True
true_hmacs = getCurrentHmacs()
for m in machines.keys():
db = sqlite3.connect('%s/cache.db' % m, isolation_level=None,
check_same_thread=False)
for k in true_hmacs.keys():
r = getConfig(db, k)
if not r and true_hmacs[k]:
print('missing %s in db of %s\n' % (k, m))
rc = False
elif r:
if true_hmacs[k] and true_hmacs[k] != r:
print('%s of %s is %s (!= %s\n)' % (k, m, r, true_hmacs[k]))
rc = False
elif not true_hmacs[k]:
print('db of %s should not contain %s\n' %(m, k))
rc = False
db.close()
if rc:
print('Databases OK')
return rc
def checkBabel(machines=MACHINES):
hmacs = getCurrentHmacs()
for k, v in hmacs.iteritems():
if v and v is not '':
hmacs[k] = '%064x' % int(bin(len(network))[2:].zfill(7) + network +
bin(int(v,16))[9+len(network):],2)
rc = True
ps = subprocess.Popen(['pgrep', '-a', 'babel'], stdout=subprocess.PIPE)
for p in (p for p in ps.communicate()[0].split('\n') if p):
for k, v in hmacs.iteritems():
k = k[6:]
if v and v is not '':
# should find key
if '%s value ' % k not in p:
print('missing %s in %s' % (k, p))
rc = False
elif p.split('%s value ' % k,1)[1].split()[0] != v:
print('%s should be %s in %s\n' % (k, v, p))
rc = False
b0 = 'babel_hmac0'; b1 = 'babel_hmac1'; b2 = 'babel_hmac2'
if ((k is hmacs[b0] and not hmacs[b1] and not hmacs[b2]) or
(k is hmacs[b0] and hmacs[b1] and not hmacs[b0]) or
(k is hmacs[b1] and hmacs[b2] and not hmacs[b0])):
if 'hmac %s' % k not in p:
print('Missing use of %s in %s\n' % (k, p))
rc = False
elif v is '':
# should find ignore_no_hmac
if 'ignore_no_hmac' not in p:
print('missing ignore_no_hmac in %s\n' % p)
rc = False
else:
# should not find key
if k in p:
print('%s should not be in %s\n' % (k, p))
rc = False
if rc:
print('Babel OK')
return rc
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment