Ticket #121: radius_scapy.py

File radius_scapy.py, 7.0 kB (added by anonymous, 4 months ago)
Line 
1 #! /usr/bin/env python
2
3 """
4 Radius extension for Scapy <http://www.secdev.org/scapy>
5
6 This module provides Scapy layers for the Radius
7  protocol as defined in RFC 2865 and 2866 and other.
8
9 Copyright (c) 2008 MAUGE Vincent  :  vmauge.nospam[at]nospam.gmail.com
10         
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15         
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20 """
21
22 from scapy import *
23
24 class Radius_Attribute(Packet):
25     name = "Radius Attribute"
26     fields_desc = [
27         ByteEnumField("type",1,{ 1:"User-Name",
28                                  2:"User-Password",
29                                  3:"CHAP-Password",
30                                  4:"NAS-IP-Address",
31                                  5:"NAS-Port",
32                                  6:"Service-Type",
33                                  7:"Framed-Protocol",
34                                  8:"Framed-IP-Address",
35                                  9:"Framed-IP-Netmask",
36                                  10:"Framed-Routing",
37                                  11:"Filter-Id",
38                                  12:"Framed-MTU",
39                                  13:"Framed-Compression",
40                                  14:"Login-IP-Host",
41                                  15:"Login-Service",
42                                  16:"Login-TCP-Port",
43                                  17:"(unassigned)",
44                                  18:"Reply-Message",
45                                  19:"Callback-Number",
46                                  20:"Callback-Id",
47                                  21:"(unassigned)",
48                                  22:"Framed-Route",
49                                  23:"Framed-IPX-Network",
50                                  24:"State",
51                                  25:"Class",
52                                  26:"Vendor-Specific",
53                                  27:"Session-Timeout",
54                                  28:"Idle-Timeout",
55                                  29:"Termination-Action",
56                                  30:"Called-Station-Id",
57                                  31:"Calling-Station-Id",
58                                  32:"NAS-Identifier",
59                                  33:"Proxy-State",
60                                  34:"Login-LAT-Service",
61                                  35:"Login-LAT-Node",
62                                  36:"Login-LAT-Group",
63                                  37:"Framed-AppleTalk-Link",
64                                  38:"Framed-AppleTalk-Network",
65                                  39:"Framed-AppleTalk-Zone",
66                                  40:"Acct-Status-Type",
67                                  41:"Acct-Delay-Time",
68                                  42:"Acct-Input-Octets",
69                                  43:"Acct-Output-Octets",
70                                  44:"Acct-Session-Id",
71                                  45:"Acct-Authentic",
72                                  46:"Acct-Session-Time",
73                                  47:"Acct-Input-Packets",
74                                  48:"Acct-Output-Packets",
75                                  49:"Acct-Terminate-Cause",
76                                  50:"Acct-Multi-Session-Id",
77                                  51:"Acct-Link-Count",
78                                  60:"CHAP-Challenge",
79                                  61:"NAS-Port-Type",
80                                  62:"Port-Limit",
81                                  63:"Login-LAT-Port"}),
82         FieldLenField("len",None,"value","B", adjust=lambda pkt,x:x+2),
83         StrLenField("value",None,length_from= lambda pkt:pkt.len-2),]
84
85     def post_build(self, p, pay):
86         l = self.len
87         if l is None:
88             l = len(p)
89             p = p[:2]+struct.pack("!B",l)+p[4:]
90         return p
91        
92     def extract_padding(self, pay):
93         return "",pay
94                      
95
96
97 class My_Radius(Packet):
98     name = "My Radius"
99     fields_desc = [
100         ByteEnumField("code", 1, {1: "Access-Request",
101                                   2: "Access-Accept",
102                                   3: "Access-Reject",
103                                   4: "Accounting-Request",
104                                   5: "Accounting-Accept",
105                                   6: "Accounting-Status",
106                                   7: "Password-Request",
107                                   8: "Password-Ack",
108                                   9: "Password-Reject",
109                                   10: "Accounting-Message",
110                                   11: "Access-Challenge",
111                                   12: "Status-Server",
112                                   13: "Status-Client",
113                                   21: "Resource-Free-Request",
114                                   22: "Resource-Free-Response",
115                                   23: "Resource-Query-Request",
116                                   24: "Resource-Query-Response",
117                                   25: "Alternate-Resource-Reclaim-Request",
118                                   26: "NAS-Reboot-Request",
119                                   27: "NAS-Reboot-Response",
120                                   29: "Next-Passcode",
121                                   30: "New-Pin",
122                                   31: "Terminate-Session",
123                                   32: "Password-Expired",
124                                   33: "Event-Request",
125                                   34: "Event-Response",
126                                   40: "Disconnect-Request",
127                                   41: "Disconnect-ACK",
128                                   42: "Disconnect-NAK",
129                                   43: "CoA-Request",
130                                   44: "CoA-ACK",
131                                   45: "CoA-NAK",
132                                   50: "IP-Address-Allocate",
133                                   51: "IP-Address-Release",
134                                   253: "Experimental-use",
135                                   254: "Reserved",
136                                   255: "Reserved"} ),
137         ByteField("id", 0),
138         FieldLenField("len", None, "attributes", "H" , adjust= lambda pkt,x:len(x.value_pair)+20),
139         StrFixedLenField("authenticator","",16),
140         PacketListField("attributes",[],Radius_Attribute,length_from=lambda pkt:pkt.len-20),]
141
142     def post_build(self, p, pay):
143         p += pay
144         l = self.len
145         if l is None:
146             l = len(p)
147             p = p[:2]+struct.pack("!H",l)+p[4:]
148         return p
149
150 bind_layers( UDP, My_Radius, sport=1812 )
151 bind_layers( UDP, My_Radius, dport=1812 )
152 bind_layers( UDP, My_Radius, sport=1813 )
153 bind_layers( UDP, My_Radius, dport=1813 )
154
155
156
157 if __name__ == "__main__":
158     interact(mydict=globals(), mybanner="Radius extension 0.1")