blob: 31be259849fd576c0a9974703c3f93d7f7e4f90a [file] [log] [blame]
A R Karthicka2e53d62016-02-19 17:38:30 -08001#### Authentication parameters
Chetan Gaonker35cb16f2016-03-02 03:05:28 -08002from scapy.all import *
A R Karthicka2e53d62016-02-19 17:38:30 -08003from socket import *
4from struct import *
A R Karthicka2e53d62016-02-19 17:38:30 -08005import sys
6from nose.tools import assert_equal, assert_not_equal, assert_raises, assert_true
7
8USER = "raduser"
9PASS = "radpass"
10WRONG_USER = "XXXX"
11WRONG_PASS = "XXXX"
12NO_USER = ""
13NO_PASS = ""
14DEV = "tap0"
15ETHERTYPE_PAE = 0x888e
16PAE_GROUP_ADDR = "\xff\xff\xff\xff\xff\xff"
17EAPOL_VERSION = 1
18EAPOL_EAPPACKET = 0
19EAPOL_START = 1
20EAPOL_LOGOFF = 2
21EAPOL_KEY = 3
22EAPOL_ASF = 4
23EAP_REQUEST = 1
24EAP_RESPONSE = 2
25EAP_SUCCESS = 3
26EAP_FAILURE = 4
27EAP_TYPE_ID = 1
28EAP_TYPE_MD5 = 4
29EAP_TYPE_MSCHAP = 26
30EAP_TYPE_TLS = 13
31cCertMsg = '\x0b\x00\x00\x03\x00\x00\x00'
32TLS_LENGTH_INCLUDED = 0x80
33
A R Karthicka2e53d62016-02-19 17:38:30 -080034class EapolPacket(object):
35
36 def __init__(self, intf = 'veth0'):
37 self.intf = intf
38 self.s = None
39 self.max_payload_size = 1600
40
41 def setup(self):
42 self.s = socket(AF_PACKET, SOCK_RAW, htons(ETHERTYPE_PAE))
43 self.s.bind((self.intf, ETHERTYPE_PAE))
44 self.mymac = self.s.getsockname()[4]
Chetan Gaonker35cb16f2016-03-02 03:05:28 -080045 self.llheader = Ether(dst = PAE_GROUP_ADDR, src = self.mymac, type = ETHERTYPE_PAE)
Chetan Gaonker5b366302016-03-21 16:18:21 -070046 self.recv_sock = L2Socket(iface = self.intf, type = ETHERTYPE_PAE)
A R Karthicka2e53d62016-02-19 17:38:30 -080047
48 def cleanup(self):
49 if self.s is not None:
50 self.s.close()
51 self.s = None
52
53 def eapol(self, req_type, payload=""):
Chetan Gaonker35cb16f2016-03-02 03:05:28 -080054 return EAPOL(version = EAPOL_VERSION, type = req_type)/payload
A R Karthicka2e53d62016-02-19 17:38:30 -080055
56 def eap(self, code, pkt_id, req_type=0, data=""):
Chetan Gaonker35cb16f2016-03-02 03:05:28 -080057 return EAP(code = code, id = pkt_id, type = req_type)/data
A R Karthicka2e53d62016-02-19 17:38:30 -080058
59 def eapTLS(self, code, pkt_id, flags = TLS_LENGTH_INCLUDED, data=""):
60 req_type = EAP_TYPE_TLS
61 if code in [EAP_SUCCESS, EAP_FAILURE]:
62 return pack("!BBH", code, pkt_id, 4)
63 else:
64 if flags & TLS_LENGTH_INCLUDED:
65 flags_dlen = pack("!BL", flags, len(data))
66 return pack("!BBHB", code, pkt_id, 5+len(flags_dlen)+len(data), req_type) + flags_dlen + data
67 flags_str = pack("!B", flags)
68 return pack("!BBHB", code, pkt_id, 5+len(flags_str)+len(data), req_type) + flags_str + data
69
70 def eapol_send(self, eapol_type, eap_payload):
Chetan Gaonker35cb16f2016-03-02 03:05:28 -080071 return sendp(self.llheader/self.eapol(eapol_type, eap_payload), iface=self.intf)
A R Karthicka2e53d62016-02-19 17:38:30 -080072
73 def eapol_recv(self):
74 p = self.s.recv(self.max_payload_size)[14:]
75 vers,pkt_type,eapollen = unpack("!BBH",p[:4])
76 print "Version %d, type %d, len %d" %(vers, pkt_type, eapollen)
77 assert_equal(pkt_type, EAPOL_EAPPACKET)
78 return p[4:]
79
Chetan Gaonker5b366302016-03-21 16:18:21 -070080 def eapol_scapy_recv(self, cb = None, lfilter = None, count = 1):
81 def eapol_default_cb(pkt): pass
82 if cb is None:
83 cb = eapol_default_cb
84 sniff(prn = cb, lfilter = lfilter, count = count, opened_socket = self.recv_sock)
85
A R Karthicka2e53d62016-02-19 17:38:30 -080086 def eapol_start(self):
87 eap_payload = self.eap(EAPOL_START, 2)
88 return self.eapol_send(EAPOL_START, eap_payload)
89
90 def eapol_id_req(self, pkt_id = 0, user = USER):
91 eap_payload = self.eap(EAP_RESPONSE, pkt_id, EAP_TYPE_ID, user)
92 return self.eapol_send(EAPOL_EAPPACKET, eap_payload)
93
Chetan Gaonker4a25e2b2016-03-04 14:45:15 -080094 def eap_md5_challenge_recv(self,rad_pwd):
95 PASS = rad_pwd
96 print 'Inside EAP MD5 Challenge Exchange'
97 p = self.s.recv(self.max_payload_size)[14:]
98 vers,pkt_type,eapollen = unpack("!BBH",p[:4])
99 print "EAPOL Version %d, type %d, len %d" %(vers, pkt_type, eapollen)
100 code, pkt_id, eaplen = unpack("!BBH", p[4:8])
101 print "EAP Code %d, id %d, len %d" %(code, pkt_id, eaplen)
102 assert_equal(code, EAP_REQUEST)
103 reqtype = unpack("!B", p[8:9])[0]
104 reqdata = p[9:4+eaplen]
105 print 'Request type is %d' %(reqtype)
106 assert_equal(reqtype, EAP_TYPE_MD5)
107 challenge=pack("!B",pkt_id)+PASS+reqdata[1:]
108 print "Generating md5 challenge for %s" % challenge
109 return (challenge,pkt_id)
110
111 def eap_Status(self):
112 print 'Inside EAP Status'
113 p = self.s.recv(self.max_payload_size)[14:]
114 code, id, eaplen = unpack("!BBH", p[4:8])
115 return code
116