Skip to content

Commit

Permalink
Fixed interface index fetch; debug printing; cynthiao changes
Browse files Browse the repository at this point in the history
  • Loading branch information
daveti committed Jul 15, 2016
1 parent f7d2c2a commit cd1f49a
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 35 deletions.
2 changes: 2 additions & 0 deletions NDprotector/Address.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def __init__(self,interface=None,\
self.__sec = ord(socket.inet_pton(\
socket.AF_INET6,self.__address)[8]) >> 5

print "About to invoke CGAverify in Address.py, check 1" # jochoi: debug
if not CGAverify(self.__address, CGAParams(modifier=modifier, prefix=self.__prefix, \
ccount = self.__collcount, pubkey = self.__pubkey, \
ext = ext)):
Expand Down Expand Up @@ -341,6 +342,7 @@ def do_dad(self):
if packet.haslayer(ICMPv6ND_NS) and address == "::":
address = packet.tgt
# CGA address check
print "About to invoke CGAverify in Address.py, check 2" # jochoi: debug
if not CGAverify(address,packet[CGAParams]):
warn("one packet with an invalid CGA address was received during the DAD procedure\n")
continue
Expand Down
38 changes: 36 additions & 2 deletions NDprotector/In.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""this module processes all the in-going packets by using nfqueue"""
from socket import AF_INET6
import sys
import ctypes # jochoi: import to use if_indextoname
import ctypes.util # jochoi: import to use if_indextoname

libc = ctypes.CDLL(ctypes.util.find_library('c')) # jochoi: needed for if_indextoname

from NDprotector.Log import warn

Expand All @@ -21,6 +25,18 @@
except ImportError:
pass

# jochoi: begin if_indextoname to replace get_if_list function
def if_indextoname(index):
if not isinstance(index, int):
raise TypeError ('provided index should be an int value');
libc.if_indextoname.argtypes = [ctypes.c_uint32, ctypes.c_char_p]
libc.if_indextoname.restype = ctypes.c_char_p
ifname = ctypes.create_string_buffer(32)
ifname = libc.if_indextoname (index, ifname)
if not ifname:
raise RuntimeError ("Invalid index")
return ifname
# jochoi: end if_indextoname

def callback(i, payload):
"""a callback function called on each ingoing packets"""
Expand All @@ -36,21 +52,36 @@ def callback(i, payload):
signalgs = []
verifalgs = []

print "In.py | Interface index is : %s" % payload.get_indev() # jochoi: debug
print "In.py | Interface name is : %s" % if_indextoname(payload.get_indev()) # jochoi: debug

# may be buggy due to the order of get_if_list()
# (in that case, we could use the if_nametoindex() )
interface = get_if_list()[ payload.get_indev() - 1]
# interface = get_if_list()[ payload.get_indev() - 1]
interface = if_indextoname(payload.get_indev()) # jochoi: edit

nc = NeighCache()

if packet.haslayer(ICMPv6ND_NS) \
or packet.haslayer(ICMPv6ND_NA):

# jochoi: begin debug to match arpsec02 printout
if packet.haslayer(ICMPv6ND_NS):
print "In.py | Received NS message"
else:
print "In.py | Received NA message"

print "In.py | Source address: %s" % packet[IPv6].src
print "In.py | Target address: %s" % packet[IPv6].tgt
# jochoi: end debug to match arpsec02

secured = False
try:
address = packet[IPv6].src
# we can receive messages from other node performing a DAD
if address == "::":
address = packet.tgt
print "In.py | About to invoke CGAverify, check 1" # jochoi: debug
cga_prop = CGAverify(address,packet.getlayer(CGAParams))
if not cga_prop:
warn("an ingoing packet has failed CGA verification test\n")
Expand All @@ -60,6 +91,7 @@ def callback(i, payload):
# Timestamp and Nonce verification are performed in the NC
# FIXME: this is not "good", we are subject to a DoS attack here

print "In.py | CGAverify successful" # jochoi: debug
list_of_pubkeys = CGAPKExtListtoPubKeyList(packet[CGAParams].ext)
list_of_pubkeys.insert(0,packet[CGAParams].pubkey)
pubkey = list_of_pubkeys[packet[ICMPv6NDOptUSSig].pos]
Expand All @@ -79,6 +111,7 @@ def callback(i, payload):
warn("an ingoing packet has failed Universal Signature verification\n")
else:
secured = True
print "In.py | Set secured to TRUE" # jochoi: debug

except AttributeError:
warn("An unsecured packet passed\n")
Expand Down Expand Up @@ -200,7 +233,8 @@ def callback(i, payload):
and pubkey.modulusLen <= NDprotector.max_RSA_key_size))\
or\
(NDprotector.ECCsupport and isinstance(pubkey, ECCkey)):


print "About to invoke CGAverify in In.py, check 2" # jochoi: debug
if CGAverify(packet[IPv6].src,packet.getlayer(CGAParams)) and \
packet[ICMPv6NDOptUSSig].keyh == pkhash and \
packet[ICMPv6NDOptUSSig].verify_sig(pubkey):
Expand Down
58 changes: 33 additions & 25 deletions NDprotector/Out.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,33 @@ def callback(i,payload):
or packet.haslayer(ICMPv6ND_NA):

for addr in configured_addresses:
print "Out.py | addr in config %s" % str(addr) # jochoi: debug
print "Out.py | source address %s" % packet[IPv6].src # jochoi: debug
if str(addr) == packet[IPv6].src:
print "Out.py | addr in config matches packet source address" # jochoi: debug
if packet.haslayer(ICMPv6ND_NS):
nonce = "".join([ chr(random.randrange(255)) for i in range(6)])
nc.record_nonce_out(packet[IPv6].src,packet[IPv6].dst,nonce)
else:
nonce = nc.pop_nonce_out(packet[IPv6].src,packet[IPv6].dst)
data = addr.sign(data,nonce=nonce)
warn("signing a NS or NA message\n")
# jochoi: split warning for NS and NA messages
# warn("signing a NS or NA message\n")
if packet.haslayer(ICMPv6ND_NS):
warn("signing a NS message\n")
else:
warn("signing a NA message\n")
payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecured packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return
else:
warn("dropping one unsecured packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecured packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0 # added return 0
else:
warn("dropping one unsecured packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
elif packet.haslayer(ICMPv6ND_RS):
if NDprotector.is_router == False:
if packet[IPv6].src == "::" :
Expand All @@ -69,15 +77,15 @@ def callback(i,payload):
data = addr.sign(data,nonce=nonce)
payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(data), len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
else:
# a router does not send this kind of messages
payload.set_verdict(nfqueue.NF_DROP)
Expand All @@ -97,15 +105,15 @@ def callback(i,payload):
data = addr.sign(data,nonce=nonce)
payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
else:
# a host does not send RA messages
payload.set_verdict(nfqueue.NF_DROP)
Expand Down
50 changes: 48 additions & 2 deletions bench/benchCGA.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from scapy6send.cert import *
from scapy6send.scapy6 import *
from NDprotector.Tool import PubKeyListtoCGAPKExtList
from math import * # cynthiao

sigtypeID = 9
extrakeynum =3
Expand Down Expand Up @@ -80,7 +81,7 @@ def gen_cga(key):
ext = PubKeyListtoCGAPKExtList([ key for i in range(extrakeynum)]) )

def bench_single_ecc():
for i in range(10000):
for i in range(100):
k = compute_key()
# computes a CGA address
before = time.time()
Expand Down Expand Up @@ -127,11 +128,56 @@ def bench_single_ecc():
f.write("sign_verif_time = " + repr(sign_verif_time) + "\n")

f.close()

# cynthiao additions :: added min, max, standard deviation

print "==CGA GENERATION TIMES=="
print "min CGA generation time: " + str(min(cga_gen_time))
print "max CGA generation time: " + str(max(cga_gen_time))
print "mean CGA generation time: " + str(sum(cga_gen_time) / len(cga_gen_time))

def average(cga_gen_time): return sum(cga_gen_time) * 1.0 / len(cga_gen_time)
avg = average(cga_gen_time)
variance = map(lambda x: (x - avg)**2, cga_gen_time)
average(variance)
stdGenDev = math.sqrt(average(variance))
print "deviation of CGA generation time: " + str(stdGenDev)

print "==CGA VERIFICATION TIMES=="
print "min CGA verification time: " + str(min(cga_verif_time))
print "max CGA verification time: " + str(max(cga_verif_time))
print "mean CGA verification time: " + str(sum(cga_verif_time) / len(cga_verif_time))

def average(cga_verif_time): return sum(cga_verif_time) * 1.0 / len(cga_verif_time)
avg = average(cga_verif_time)
variance = map(lambda x: (x - avg)**2, cga_verif_time)
average(variance)
stdVerDev = math.sqrt(average(variance))
print "deviation of CGA verification time: " + str(stdVerDev)

print "==SIGNATURE GENERATION TIMES=="
print "min Signature generation time: " + str(min(sign_gen_time))
print "max Signature generation time: " + str(max(sign_gen_time))
print "mean Signature generation time: " + str(sum(sign_gen_time) / len(sign_gen_time))

def average(sign_gen_time): return sum(sign_gen_time) * 1.0 / len(sign_gen_time)
avg = average(sign_gen_time)
variance = map(lambda x: (x - avg)**2, sign_gen_time)
average(variance)
stdSigDev = math.sqrt(average(variance))
print "deviation of Signature generation time: " + str(stdSigDev)

print "==SIGNATURE VERIFICATION TIMES=="
print "min Signature verification time: " + str(min(sign_verif_time))
print "max Signature verification time: " + str(max(sign_verif_time))
print "mean Signature verification time: " + str(sum(sign_verif_time) / len(sign_verif_time))

def average(sign_verif_time): return sum(sign_verif_time) * 1.0 / len(sign_verif_time)
avg = average(sign_verif_time)
variance = map(lambda x: (x - avg)**2, sign_verif_time)
average(variance)
stdSigVerDev = math.sqrt(average(variance))
print "deviation of Signature verification time: " + str(stdSigVerDev)

# prof = cProfile.run("bench_single_ecc()","%d-key-ecc.prof" % extrakeynum)


Expand Down
14 changes: 8 additions & 6 deletions examples/sendd.conf.host
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ NDprotector.mixed_mode = False

# allow NDprotector to flush all the IPv6 addresses on all interfaces
# (so that only CGA are on the interfaces)
NDprotector.flush_interfaces = True
NDprotector.flush_interfaces = False

# /!\ Beware:
# force test on X.509 IP Address extension
Expand All @@ -53,7 +53,7 @@ NDprotector.default_sec_value = 1
# If True, the programm automotaticlally assign addresses on the interfaces
# the program will also clean up and destroy unused addresses
# If set to False, the user must to the address assignement manually
NDprotector.assign_addresses = True
NDprotector.assign_addresses = False


# Default key size for RSA keys
Expand All @@ -70,7 +70,7 @@ NDprotector.max_RSA_key_size = 2048

# Path to the default Public Key used for Stateless Address Autoconfiguration
# if None is provided, generate a new RSA Public Key for new addresses
NDprotector.default_publickey = None
NDprotector.default_publickey = "/root/git/NDprotector/publicKeyB.pem"
# NDprotector.default_publickey = "/etc/NDprotector/mypublickey.pem"

# Path to the trust anchor
Expand Down Expand Up @@ -107,9 +107,11 @@ NDprotector.configured_addresses = \
# ext = None ),

# list of configured prefixes where autoconfiguration will be applied
Address(interface = "eth0",
prefix = "fe80::",
key = "/root/git/NDprotector/examples/test/test_key.pem"), # if ommited, uses the key pointed by default_publickey
# Address(interface = "eth0",
Address(interface = "eth1",
prefix = "2001:db8:0:100::",
key = "/root/git/NDprotector/privateKeyB.pem",
modifier = 50), # if ommited, uses the key pointed by default_publickey
# or fallback (when default_publickey is None) and the program will compute a new RSA key
# Address(interface = "eth0", # for example this one will build it's own key
# prefix = "2001::",
Expand Down

0 comments on commit cd1f49a

Please sign in to comment.