Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scapy/layers/radius.py: 88%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

241 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Acknowledgment: Vincent Mauge <vmauge.nospam@nospam.gmail.com> 

5 

6""" 

7RADIUS (Remote Authentication Dial In User Service) 

8 

9To disable Radius-EAP defragmentation (True by default), you can use:: 

10 

11 conf.contribs.setdefault("radius", {}).setdefault("auto-defrag", False) 

12""" 

13 

14import struct 

15import hashlib 

16import hmac 

17from scapy.compat import orb, raw 

18from scapy.packet import Packet, Padding, bind_layers, bind_bottom_up 

19from scapy.fields import ByteField, ByteEnumField, IntField, StrLenField,\ 

20 XStrLenField, XStrFixedLenField, FieldLenField, PacketLenField,\ 

21 PacketListField, IPField, MultiEnumField 

22from scapy.layers.inet import UDP 

23from scapy.layers.eap import EAP 

24from scapy.config import conf 

25from scapy.error import Scapy_Exception 

26 

27# https://www.iana.org/assignments/radius-types/radius-types.xhtml 

28_radius_attribute_types = { 

29 1: "User-Name", 

30 2: "User-Password", 

31 3: "CHAP-Password", 

32 4: "NAS-IP-Address", 

33 5: "NAS-Port", 

34 6: "Service-Type", 

35 7: "Framed-Protocol", 

36 8: "Framed-IP-Address", 

37 9: "Framed-IP-Netmask", 

38 10: "Framed-Routing", 

39 11: "Filter-Id", 

40 12: "Framed-MTU", 

41 13: "Framed-Compression", 

42 14: "Login-IP-Host", 

43 15: "Login-Service", 

44 16: "Login-TCP-Port", 

45 17: "Unassigned", 

46 18: "Reply-Message", 

47 19: "Callback-Number", 

48 20: "Callback-Id", 

49 21: "Unassigned", 

50 22: "Framed-Route", 

51 23: "Framed-IPX-Network", 

52 24: "State", 

53 25: "Class", 

54 26: "Vendor-Specific", 

55 27: "Session-Timeout", 

56 28: "Idle-Timeout", 

57 29: "Termination-Action", 

58 30: "Called-Station-Id", 

59 31: "Calling-Station-Id", 

60 32: "NAS-Identifier", 

61 33: "Proxy-State", 

62 34: "Login-LAT-Service", 

63 35: "Login-LAT-Node", 

64 36: "Login-LAT-Group", 

65 37: "Framed-AppleTalk-Link", 

66 38: "Framed-AppleTalk-Network", 

67 39: "Framed-AppleTalk-Zone", 

68 40: "Acct-Status-Type", 

69 41: "Acct-Delay-Time", 

70 42: "Acct-Input-Octets", 

71 43: "Acct-Output-Octets", 

72 44: "Acct-Session-Id", 

73 45: "Acct-Authentic", 

74 46: "Acct-Session-Time", 

75 47: "Acct-Input-Packets", 

76 48: "Acct-Output-Packets", 

77 49: "Acct-Terminate-Cause", 

78 50: "Acct-Multi-Session-Id", 

79 51: "Acct-Link-Count", 

80 52: "Acct-Input-Gigawords", 

81 53: "Acct-Output-Gigawords", 

82 54: "Unassigned", 

83 55: "Event-Timestamp", 

84 56: "Egress-VLANID", 

85 57: "Ingress-Filters", 

86 58: "Egress-VLAN-Name", 

87 59: "User-Priority-Table", 

88 60: "CHAP-Challenge", 

89 61: "NAS-Port-Type", 

90 62: "Port-Limit", 

91 63: "Login-LAT-Port", 

92 64: "Tunnel-Type", 

93 65: "Tunnel-Medium-Type", 

94 66: "Tunnel-Client-Endpoint", 

95 67: "Tunnel-Server-Endpoint", 

96 68: "Acct-Tunnel-Connection", 

97 69: "Tunnel-Password", 

98 70: "ARAP-Password", 

99 71: "ARAP-Features", 

100 72: "ARAP-Zone-Access", 

101 73: "ARAP-Security", 

102 74: "ARAP-Security-Data", 

103 75: "Password-Retry", 

104 76: "Prompt", 

105 77: "Connect-Info", 

106 78: "Configuration-Token", 

107 79: "EAP-Message", 

108 80: "Message-Authenticator", 

109 81: "Tunnel-Private-Group-ID", 

110 82: "Tunnel-Assignment-ID", 

111 83: "Tunnel-Preference", 

112 84: "ARAP-Challenge-Response", 

113 85: "Acct-Interim-Interval", 

114 86: "Acct-Tunnel-Packets-Lost", 

115 87: "NAS-Port-Id", 

116 88: "Framed-Pool", 

117 89: "CUI", 

118 90: "Tunnel-Client-Auth-ID", 

119 91: "Tunnel-Server-Auth-ID", 

120 92: "NAS-Filter-Rule", 

121 93: "Unassigned", 

122 94: "Originating-Line-Info", 

123 95: "NAS-IPv6-Address", 

124 96: "Framed-Interface-Id", 

125 97: "Framed-IPv6-Prefix", 

126 98: "Login-IPv6-Host", 

127 99: "Framed-IPv6-Route", 

128 100: "Framed-IPv6-Pool", 

129 101: "Error-Cause", 

130 102: "EAP-Key-Name", 

131 103: "Digest-Response", 

132 104: "Digest-Realm", 

133 105: "Digest-Nonce", 

134 106: "Digest-Response-Auth", 

135 107: "Digest-Nextnonce", 

136 108: "Digest-Method", 

137 109: "Digest-URI", 

138 110: "Digest-Qop", 

139 111: "Digest-Algorithm", 

140 112: "Digest-Entity-Body-Hash", 

141 113: "Digest-CNonce", 

142 114: "Digest-Nonce-Count", 

143 115: "Digest-Username", 

144 116: "Digest-Opaque", 

145 117: "Digest-Auth-Param", 

146 118: "Digest-AKA-Auts", 

147 119: "Digest-Domain", 

148 120: "Digest-Stale", 

149 121: "Digest-HA1", 

150 122: "SIP-AOR", 

151 123: "Delegated-IPv6-Prefix", 

152 124: "MIP6-Feature-Vector", 

153 125: "MIP6-Home-Link-Prefix", 

154 126: "Operator-Name", 

155 127: "Location-Information", 

156 128: "Location-Data", 

157 129: "Basic-Location-Policy-Rules", 

158 130: "Extended-Location-Policy-Rules", 

159 131: "Location-Capable", 

160 132: "Requested-Location-Info", 

161 133: "Framed-Management-Protocol", 

162 134: "Management-Transport-Protection", 

163 135: "Management-Policy-Id", 

164 136: "Management-Privilege-Level", 

165 137: "PKM-SS-Cert", 

166 138: "PKM-CA-Cert", 

167 139: "PKM-Config-Settings", 

168 140: "PKM-Cryptosuite-List", 

169 141: "PKM-SAID", 

170 142: "PKM-SA-Descriptor", 

171 143: "PKM-Auth-Key", 

172 144: "DS-Lite-Tunnel-Name", 

173 145: "Mobile-Node-Identifier", 

174 146: "Service-Selection", 

175 147: "PMIP6-Home-LMA-IPv6-Address", 

176 148: "PMIP6-Visited-LMA-IPv6-Address", 

177 149: "PMIP6-Home-LMA-IPv4-Address", 

178 150: "PMIP6-Visited-LMA-IPv4-Address", 

179 151: "PMIP6-Home-HN-Prefix", 

180 152: "PMIP6-Visited-HN-Prefix", 

181 153: "PMIP6-Home-Interface-ID", 

182 154: "PMIP6-Visited-Interface-ID", 

183 155: "PMIP6-Home-IPv4-HoA", 

184 156: "PMIP6-Visited-IPv4-HoA", 

185 157: "PMIP6-Home-DHCP4-Server-Address", 

186 158: "PMIP6-Visited-DHCP4-Server-Address", 

187 159: "PMIP6-Home-DHCP6-Server-Address", 

188 160: "PMIP6-Visited-DHCP6-Server-Address", 

189 161: "PMIP6-Home-IPv4-Gateway", 

190 162: "PMIP6-Visited-IPv4-Gateway", 

191 163: "EAP-Lower-Layer", 

192 164: "GSS-Acceptor-Service-Name", 

193 165: "GSS-Acceptor-Host-Name", 

194 166: "GSS-Acceptor-Service-Specifics", 

195 167: "GSS-Acceptor-Realm-Name", 

196 168: "Framed-IPv6-Address", 

197 169: "DNS-Server-IPv6-Address", 

198 170: "Route-IPv6-Information", 

199 171: "Delegated-IPv6-Prefix-Pool", 

200 172: "Stateful-IPv6-Address-Pool", 

201 173: "IPv6-6rd-Configuration", 

202 174: "Allowed-Called-Station-Id", 

203 175: "EAP-Peer-Id", 

204 176: "EAP-Server-Id", 

205 177: "Mobility-Domain-Id", 

206 178: "Preauth-Timeout", 

207 179: "Network-Id-Name", 

208 180: "EAPoL-Announcement", 

209 181: "WLAN-HESSID", 

210 182: "WLAN-Venue-Info", 

211 183: "WLAN-Venue-Language", 

212 184: "WLAN-Venue-Name", 

213 185: "WLAN-Reason-Code", 

214 186: "WLAN-Pairwise-Cipher", 

215 187: "WLAN-Group-Cipher", 

216 188: "WLAN-AKM-Suite", 

217 189: "WLAN-Group-Mgmt-Cipher", 

218 190: "WLAN-RF-Band", 

219 191: "Unassigned", 

220} 

221 

222 

223class RadiusAttribute(Packet): 

224 """ 

225 Implements a RADIUS attribute (RFC 2865). Every specific RADIUS attribute 

226 class should inherit from this one. 

227 """ 

228 

229 name = "Radius Attribute" 

230 fields_desc = [ 

231 ByteEnumField("type", 1, _radius_attribute_types), 

232 FieldLenField("len", None, "value", "B", 

233 adjust=lambda pkt, x: len(pkt.value) + 2), 

234 StrLenField("value", "", length_from=lambda pkt: pkt.len - 2) 

235 ] 

236 

237 registered_attributes = {} 

238 

239 @classmethod 

240 def register_variant(cls): 

241 """ 

242 Registers the RADIUS attributes defined in this module. 

243 """ 

244 

245 if hasattr(cls, "val"): 

246 cls.registered_attributes[cls.val] = cls 

247 else: 

248 cls.registered_attributes[cls.type.default] = cls 

249 

250 @classmethod 

251 def dispatch_hook(cls, _pkt=None, *args, **kargs): 

252 """ 

253 Returns the right RadiusAttribute class for the given data. 

254 """ 

255 

256 if _pkt: 

257 attr_type = orb(_pkt[0]) 

258 return cls.registered_attributes.get(attr_type, cls) 

259 return cls 

260 

261 def post_build(self, p, pay): 

262 length = self.len 

263 if length is None: 

264 length = len(p) 

265 p = p[:1] + struct.pack("!B", length) + p[2:] 

266 return p 

267 

268 def guess_payload_class(self, _): 

269 return Padding 

270 

271 

272class _SpecificRadiusAttr(RadiusAttribute): 

273 """ 

274 Class from which every "specific" RADIUS attribute defined in this module 

275 inherits. 

276 """ 

277 

278 __slots__ = ["val"] 

279 match_subclass = True 

280 

281 def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 

282 super(_SpecificRadiusAttr, self).__init__( 

283 _pkt, 

284 post_transform, 

285 _internal, 

286 _underlayer, 

287 **fields 

288 ) 

289 self.fields["type"] = self.val 

290 name_parts = self.__class__.__name__.split('RadiusAttr_') 

291 if len(name_parts) < 2: 

292 raise Scapy_Exception( 

293 "Invalid class name: {}".format(self.__class__.__name__) 

294 ) 

295 self.name = name_parts[1].replace('_', '-') 

296 

297 

298# 

299# RADIUS attributes which values are 4 bytes integers 

300# 

301 

302class _RadiusAttrIntValue(_SpecificRadiusAttr): 

303 """ 

304 Implements a RADIUS attribute which value field is 4 bytes long integer. 

305 """ 

306 

307 fields_desc = [ 

308 ByteEnumField("type", 5, _radius_attribute_types), 

309 ByteField("len", 6), 

310 IntField("value", 0) 

311 ] 

312 

313 

314class RadiusAttr_User_Name(_SpecificRadiusAttr): 

315 """RFC 2865""" 

316 val = 1 

317 

318 

319class RadiusAttr_NAS_Port(_RadiusAttrIntValue): 

320 """RFC 2865""" 

321 val = 5 

322 

323 

324class RadiusAttr_Framed_MTU(_RadiusAttrIntValue): 

325 """RFC 2865""" 

326 val = 12 

327 

328 

329class RadiusAttr_Login_TCP_Port(_RadiusAttrIntValue): 

330 """RFC 2865""" 

331 val = 16 

332 

333 

334class RadiusAttr_Session_Timeout(_RadiusAttrIntValue): 

335 """RFC 2865""" 

336 val = 27 

337 

338 

339class RadiusAttr_Idle_Timeout(_RadiusAttrIntValue): 

340 """RFC 2865""" 

341 val = 28 

342 

343 

344class RadiusAttr_Framed_AppleTalk_Link(_RadiusAttrIntValue): 

345 """RFC 2865""" 

346 val = 37 

347 

348 

349class RadiusAttr_Framed_AppleTalk_Network(_RadiusAttrIntValue): 

350 """RFC 2865""" 

351 val = 38 

352 

353 

354class RadiusAttr_Acct_Delay_Time(_RadiusAttrIntValue): 

355 """RFC 2866""" 

356 val = 41 

357 

358 

359class RadiusAttr_Acct_Input_Octets(_RadiusAttrIntValue): 

360 """RFC 2866""" 

361 val = 42 

362 

363 

364class RadiusAttr_Acct_Output_Octets(_RadiusAttrIntValue): 

365 """RFC 2866""" 

366 val = 43 

367 

368 

369class RadiusAttr_Acct_Session_Time(_RadiusAttrIntValue): 

370 """RFC 2866""" 

371 val = 46 

372 

373 

374class RadiusAttr_Acct_Input_Packets(_RadiusAttrIntValue): 

375 """RFC 2866""" 

376 val = 47 

377 

378 

379class RadiusAttr_Acct_Output_Packets(_RadiusAttrIntValue): 

380 """RFC 2866""" 

381 val = 48 

382 

383 

384class RadiusAttr_Acct_Link_Count(_RadiusAttrIntValue): 

385 """RFC 2866""" 

386 val = 51 

387 

388 

389class RadiusAttr_Acct_Input_Gigawords(_RadiusAttrIntValue): 

390 """RFC 2869""" 

391 val = 52 

392 

393 

394class RadiusAttr_Acct_Output_Gigawords(_RadiusAttrIntValue): 

395 """RFC 2869""" 

396 val = 53 

397 

398 

399class RadiusAttr_Egress_VLANID(_RadiusAttrIntValue): 

400 """RFC 4675""" 

401 val = 56 

402 

403 

404class RadiusAttr_Port_Limit(_RadiusAttrIntValue): 

405 """RFC 2865""" 

406 val = 62 

407 

408 

409class RadiusAttr_ARAP_Security(_RadiusAttrIntValue): 

410 """RFC 2869""" 

411 val = 73 

412 

413 

414class RadiusAttr_Password_Retry(_RadiusAttrIntValue): 

415 """RFC 2869""" 

416 val = 75 

417 

418 

419class RadiusAttr_Tunnel_Preference(_RadiusAttrIntValue): 

420 """RFC 2868""" 

421 val = 83 

422 

423 

424class RadiusAttr_Acct_Interim_Interval(_RadiusAttrIntValue): 

425 """RFC 2869""" 

426 val = 85 

427 

428 

429class RadiusAttr_Acct_Tunnel_Packets_Lost(_RadiusAttrIntValue): 

430 """RFC 2867""" 

431 val = 86 

432 

433 

434class RadiusAttr_Management_Privilege_Level(_RadiusAttrIntValue): 

435 """RFC 5607""" 

436 val = 136 

437 

438 

439class RadiusAttr_Mobility_Domain_Id(_RadiusAttrIntValue): 

440 """RFC 7268""" 

441 val = 177 

442 

443 

444class RadiusAttr_Preauth_Timeout(_RadiusAttrIntValue): 

445 """RFC 7268""" 

446 val = 178 

447 

448 

449class RadiusAttr_WLAN_Venue_Info(_RadiusAttrIntValue): 

450 """RFC 7268""" 

451 val = 182 

452 

453 

454class RadiusAttr_WLAN_Reason_Code(_RadiusAttrIntValue): 

455 """RFC 7268""" 

456 val = 185 

457 

458 

459class RadiusAttr_WLAN_Pairwise_Cipher(_RadiusAttrIntValue): 

460 """RFC 7268""" 

461 val = 186 

462 

463 

464class RadiusAttr_WLAN_Group_Cipher(_RadiusAttrIntValue): 

465 """RFC 7268""" 

466 val = 187 

467 

468 

469class RadiusAttr_WLAN_AKM_Suite(_RadiusAttrIntValue): 

470 """RFC 7268""" 

471 val = 188 

472 

473 

474class RadiusAttr_WLAN_Group_Mgmt_Cipher(_RadiusAttrIntValue): 

475 """RFC 7268""" 

476 val = 189 

477 

478 

479class RadiusAttr_WLAN_RF_Band(_RadiusAttrIntValue): 

480 """RFC 7268""" 

481 val = 190 

482 

483 

484# 

485# RADIUS attributes which values are string (displayed as hex) 

486# 

487 

488class _RadiusAttrHexStringVal(_SpecificRadiusAttr): 

489 """ 

490 Implements a RADIUS attribute which value field is a string that will be 

491 as a hex string. 

492 """ 

493 

494 __slots__ = ["val"] 

495 

496 def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 

497 super(_RadiusAttrHexStringVal, self).__init__( 

498 _pkt, 

499 post_transform, 

500 _internal, 

501 _underlayer, 

502 **fields 

503 ) 

504 self.fields["type"] = self.val 

505 name_parts = self.__class__.__name__.split('RadiusAttr_') 

506 if len(name_parts) < 2: 

507 raise Scapy_Exception( 

508 "Invalid class name: {}".format(self.__class__.__name__) 

509 ) 

510 self.name = name_parts[1].replace('_', '-') 

511 

512 fields_desc = [ 

513 ByteEnumField("type", 24, _radius_attribute_types), 

514 FieldLenField( 

515 "len", 

516 None, 

517 "value", 

518 "B", 

519 adjust=lambda p, x: len(p.value) + 2 

520 ), 

521 XStrLenField("value", "", length_from=lambda p: p.len - 2 if p.len else 0) # noqa: E501 

522 ] 

523 

524 

525class RadiusAttr_User_Password(_RadiusAttrHexStringVal): 

526 """RFC 2865""" 

527 val = 2 

528 

529 

530class RadiusAttr_State(_RadiusAttrHexStringVal): 

531 """RFC 2865""" 

532 val = 24 

533 

534 

535def prepare_packed_data(radius_packet, packed_req_authenticator): 

536 """ 

537 Pack RADIUS data prior computing the authentication MAC 

538 """ 

539 

540 packed_hdr = struct.pack("!B", radius_packet.code) 

541 packed_hdr += struct.pack("!B", radius_packet.id) 

542 packed_hdr += struct.pack("!H", radius_packet.len) 

543 

544 packed_attrs = b'' 

545 for attr in radius_packet.attributes: 

546 packed_attrs += raw(attr) 

547 

548 return packed_hdr + packed_req_authenticator + packed_attrs 

549 

550 

551class RadiusAttr_Message_Authenticator(_RadiusAttrHexStringVal): 

552 """RFC 2869""" 

553 val = 80 

554 

555 fields_desc = [ 

556 ByteEnumField("type", 24, _radius_attribute_types), 

557 FieldLenField( 

558 "len", 

559 18, 

560 "value", 

561 "B", 

562 ), 

563 XStrFixedLenField("value", "\x00" * 16, length=16) 

564 ] 

565 

566 @staticmethod 

567 def compute_message_authenticator(radius_packet, packed_req_authenticator, 

568 shared_secret): 

569 """ 

570 Computes the "Message-Authenticator" of a given RADIUS packet. 

571 (RFC 2869 - Page 33) 

572 """ 

573 

574 attr = radius_packet[RadiusAttr_Message_Authenticator] 

575 attr.value = bytearray(attr.len - 2) 

576 data = prepare_packed_data(radius_packet, packed_req_authenticator) 

577 radius_hmac = hmac.new(shared_secret, data, hashlib.md5) 

578 

579 return radius_hmac.digest() 

580 

581# 

582# RADIUS attributes which values are IPv4 prefixes 

583# 

584 

585 

586class _RadiusAttrIPv4AddrVal(_SpecificRadiusAttr): 

587 """ 

588 Implements a RADIUS attribute which value field is an IPv4 address. 

589 """ 

590 

591 __slots__ = ["val"] 

592 

593 fields_desc = [ 

594 ByteEnumField("type", 4, _radius_attribute_types), 

595 ByteField("len", 6), 

596 IPField("value", "0.0.0.0") 

597 ] 

598 

599 

600class RadiusAttr_NAS_IP_Address(_RadiusAttrIPv4AddrVal): 

601 """RFC 2865""" 

602 val = 4 

603 

604 

605class RadiusAttr_Framed_IP_Address(_RadiusAttrIPv4AddrVal): 

606 """RFC 2865""" 

607 val = 8 

608 

609 

610class RadiusAttr_Framed_IP_Netmask(_RadiusAttrIPv4AddrVal): 

611 """RFC 2865""" 

612 val = 9 

613 

614 

615class RadiusAttr_Login_IP_Host(_RadiusAttrIPv4AddrVal): 

616 """RFC 2865""" 

617 val = 14 

618 

619 

620class RadiusAttr_Framed_IPX_Network(_RadiusAttrIPv4AddrVal): 

621 """RFC 2865""" 

622 val = 23 

623 

624 

625class RadiusAttr_PMIP6_Home_LMA_IPv4_Address(_RadiusAttrIPv4AddrVal): 

626 """RFC 6572""" 

627 val = 149 

628 

629 

630class RadiusAttr_PMIP6_Visited_LMA_IPv4_Address(_RadiusAttrIPv4AddrVal): 

631 """RFC 6572""" 

632 val = 150 

633 

634 

635class RadiusAttr_PMIP6_Home_DHCP4_Server_Address(_RadiusAttrIPv4AddrVal): 

636 """RFC 6572""" 

637 val = 157 

638 

639 

640class RadiusAttr_PMIP6_Visited_DHCP4_Server_Address(_RadiusAttrIPv4AddrVal): 

641 """RFC 6572""" 

642 val = 158 

643 

644 

645class RadiusAttr_PMIP6_Home_IPv4_Gateway(_RadiusAttrIPv4AddrVal): 

646 """RFC 6572""" 

647 val = 161 

648 

649 

650class RadiusAttr_PMIP6_Visited_IPv4_Gateway(_RadiusAttrIPv4AddrVal): 

651 """RFC 6572""" 

652 val = 162 

653 

654 

655# See IANA registry "RADIUS Types" 

656_radius_attrs_values = { 

657 # Service-Type 

658 6: 

659 { 

660 1: "Login", 

661 2: "Framed", 

662 3: "Callback Login", 

663 4: "Callback Framed", 

664 5: "Outbound", 

665 6: "Administrative", 

666 7: "NAS Prompt", 

667 8: "Authenticate Only", 

668 9: "Callback NAS Prompt", 

669 10: "Call Check", 

670 11: "Callback Administrative", 

671 12: "Voice", 

672 13: "Fax", 

673 14: "Modem Relay", 

674 15: "IAPP-Register", 

675 16: "IAPP-AP-Check", 

676 17: "Authorize Only", 

677 18: "Framed-Management", 

678 19: "Additional-Authorization" 

679 }, 

680 

681 # Framed-Protocol 

682 7: 

683 { 

684 1: "PPP", 

685 2: "SLIP", 

686 3: "AppleTalk Remote Access Protocol (ARAP)", 

687 4: "Gandalf proprietary SingleLink/MultiLink protocol", 

688 5: "Xylogics proprietary IPX/SLIP", 

689 6: "X.75 Synchronous", 

690 7: "GPRS PDP Context" 

691 }, 

692 

693 # Framed-Routing 

694 10: 

695 { 

696 0: "None", 

697 1: "Send routing packets", 

698 2: "Listen for routing packets", 

699 3: "Send and Listen" 

700 }, 

701 

702 # Framed-Compression 

703 13: 

704 { 

705 0: "None", 

706 1: "VJ TCP/IP header compression", 

707 2: "IPX header compression", 

708 3: "Stac-LZS compression" 

709 }, 

710 

711 # Login-Service 

712 15: 

713 { 

714 0: "Telnet", 

715 1: "Rlogin", 

716 2: "TCP Clear", 

717 3: "PortMaster (proprietary)", 

718 4: "LAT", 

719 5: "X25-PAD", 

720 6: "X25-T3POS", 

721 7: "Unassigned", 

722 8: "TCP Clear Quiet (suppresses any NAS-generated connect string)" 

723 }, 

724 

725 # Termination-Action 

726 29: 

727 { 

728 0: "Default", 

729 1: "RADIUS-Request" 

730 }, 

731 

732 # Acct-Status-Type 

733 40: 

734 { 

735 1: "Start", 

736 2: "Stop", 

737 3: "Interim-Update", 

738 4: "Unassigned", 

739 5: "Unassigned", 

740 6: "Unassigned", 

741 7: "Accounting-On", 

742 8: "Accounting-Off", 

743 9: "Tunnel-Start", 

744 10: "Tunnel-Stop", 

745 11: "Tunnel-Reject", 

746 12: "Tunnel-Link-Start", 

747 13: "Tunnel-Link-Stop", 

748 14: "Tunnel-Link-Reject", 

749 15: "Failed" 

750 }, 

751 

752 # Acct-Authentic 

753 45: 

754 { 

755 1: "RADIUS", 

756 2: "Local", 

757 3: "Remote", 

758 4: "Diameter" 

759 }, 

760 

761 # Acct-Terminate-Cause 

762 49: 

763 { 

764 1: "User Request", 

765 2: "Lost Carrier", 

766 3: "Lost Service", 

767 4: "Idle Timeout", 

768 5: "Session Timeout", 

769 6: "Admin Reset", 

770 7: "Admin Reboot", 

771 8: "Port Error", 

772 9: "NAS Error", 

773 10: "NAS Request", 

774 11: "NAS Reboot", 

775 12: "Port Unneeded", 

776 13: "Port Preempted", 

777 14: "Port Suspended", 

778 15: "Service Unavailable", 

779 16: "Callback", 

780 17: "User Error", 

781 18: "Host Request", 

782 19: "Supplicant Restart", 

783 20: "Reauthentication Failure", 

784 21: "Port Reinitialized", 

785 22: "Port Administratively Disabled", 

786 23: "Lost Power", 

787 }, 

788 

789 # NAS-Port-Type 

790 61: 

791 { 

792 0: "Async", 

793 1: "Sync", 

794 2: "ISDN Sync", 

795 3: "ISDN Async V.120", 

796 4: "ISDN Async V.110", 

797 5: "Virtual", 

798 6: "PIAFS", 

799 7: "HDLC Clear Channel", 

800 8: "X.25", 

801 9: "X.75", 

802 10: "G.3 Fax", 

803 11: "SDSL - Symmetric DSL", 

804 12: "ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation", # noqa: E501 

805 13: "ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone", 

806 14: "IDSL - ISDN Digital Subscriber Line", 

807 15: "Ethernet", 

808 16: "xDSL - Digital Subscriber Line of unknown type", 

809 17: "Cable", 

810 18: "Wireles - Other", 

811 19: "Wireless - IEEE 802.11", 

812 20: "Token-Ring", 

813 21: "FDDI", 

814 22: "Wireless - CDMA2000", 

815 23: "Wireless - UMTS", 

816 24: "Wireless - 1X-EV", 

817 25: "IAPP", 

818 26: "FTTP - Fiber to the Premises", 

819 27: "Wireless - IEEE 802.16", 

820 28: "Wireless - IEEE 802.20", 

821 29: "Wireless - IEEE 802.22", 

822 30: "PPPoA - PPP over ATM", 

823 31: "PPPoEoA - PPP over Ethernet over ATM", 

824 32: "PPPoEoE - PPP over Ethernet over Ethernet", 

825 33: "PPPoEoVLAN - PPP over Ethernet over VLAN", 

826 34: "PPPoEoQinQ - PPP over Ethernet over IEEE 802.1QinQ", 

827 35: "xPON - Passive Optical Network", 

828 36: "Wireless - XGP", 

829 37: "WiMAX Pre-Release 8 IWK Function", 

830 38: "WIMAX-WIFI-IWK: WiMAX WIFI Interworking", 

831 39: "WIMAX-SFF: Signaling Forwarding Function for LTE/3GPP2", 

832 40: "WIMAX-HA-LMA: WiMAX HA and or LMA function", 

833 41: "WIMAX-DHCP: WIMAX DHCP service", 

834 42: "WIMAX-LBS: WiMAX location based service", 

835 43: "WIMAX-WVS: WiMAX voice service" 

836 }, 

837 

838 # Tunnel-Type 

839 64: 

840 { 

841 1: "Point-to-Point Tunneling Protocol (PPTP)", 

842 2: "Layer Two Forwarding (L2F)", 

843 3: "Layer Two Tunneling Protocol (L2TP)", 

844 4: "Ascend Tunnel Management Protocol (ATMP)", 

845 5: "Virtual Tunneling Protocol (VTP)", 

846 6: "IP Authentication Header in the Tunnel-mode (AH)", 

847 7: "IP-in-IP Encapsulation (IP-IP)", 

848 8: "Minimal IP-in-IP Encapsulation (MIN-IP-IP)", 

849 9: "IP Encapsulating Security Payload in the Tunnel-mode (ESP)", 

850 10: "Generic Route Encapsulation (GRE)", 

851 11: "Bay Dial Virtual Services (DVS)", 

852 12: "IP-in-IP Tunneling", 

853 13: "Virtual LANs (VLAN)" 

854 }, 

855 

856 # Tunnel-Medium-Type 

857 65: 

858 { 

859 1: "IPv4 (IP version 4)", 

860 2: "IPv6 (IP version 6)", 

861 3: "NSAP", 

862 4: "HDLC (8-bit multidrop)", 

863 5: "BBN 1822", 

864 6: "802", 

865 7: "E.163 (POTS)", 

866 8: "E.164 (SMDS, Frame Relay, ATM)", 

867 9: "F.69 (Telex)", 

868 10: "X.121 (X.25, Frame Relay)", 

869 11: "IPX", 

870 12: "Appletalk", 

871 13: "Decnet IV", 

872 14: "Banyan Vine", 

873 15: "E.164 with NSAP format subaddress" 

874 }, 

875 

876 # ARAP-Zone-Access 

877 72: 

878 { 

879 1: "Only allow access to default zone", 

880 2: "Use zone filter inclusively", 

881 3: "Not used", 

882 4: "Use zone filter exclusively" 

883 }, 

884 

885 # Prompt 

886 76: 

887 { 

888 0: "No Echo", 

889 1: "Echo" 

890 }, 

891 

892 # Error-Cause Attribute 

893 101: 

894 { 

895 201: "Residual Session Context Removed", 

896 202: "Invalid EAP Packet (Ignored)", 

897 401: "Unsupported Attribute", 

898 402: "Missing Attribute", 

899 403: "NAS Identification Mismatch", 

900 404: "Invalid Request", 

901 405: "Unsupported Service", 

902 406: "Unsupported Extension", 

903 407: "Invalid Attribute Value", 

904 501: "Administratively Prohibited", 

905 502: "Request Not Routable (Proxy)", 

906 503: "Session Context Not Found", 

907 504: "Session Context Not Removable", 

908 505: "Other Proxy Processing Error", 

909 506: "Resources Unavailable", 

910 507: "Request Initiated", 

911 508: "Multiple Session Selection Unsupported", 

912 509: "Location-Info-Required", 

913 601: "Response Too Big" 

914 }, 

915 

916 # Operator Namespace Identifier - Attribute 126 

917 126: 

918 { 

919 0x30: "TADIG", 

920 0x31: "REALM", 

921 0x32: "E212", 

922 0x33: "ICC", 

923 0xFF: "Reserved" 

924 }, 

925 

926 # Basic-Location-Policy-Rules 

927 129: 

928 { 

929 0: "Retransmission allowed", 

930 }, 

931 

932 # Location-Capable 

933 131: 

934 { 

935 1: "CIVIC_LOCATION", 

936 2: "GEO_LOCATION", 

937 4: "USERS_LOCATION", 

938 8: "NAS_LOCATION" 

939 }, 

940 

941 # Framed-Management-Protocol 

942 133: 

943 { 

944 1: "SNMP", 

945 2: "Web-based", 

946 3: "NETCONF", 

947 4: "FTP", 

948 5: "TFTP", 

949 6: "SFTP", 

950 7: "RCP", 

951 8: "SCP" 

952 }, 

953 

954 # Management-Transport-Protection 

955 134: 

956 { 

957 1: "No-Protection", 

958 2: "Integrity-Protection", 

959 3: "Integrity-Confidentiality-Protection", 

960 }, 

961} 

962 

963 

964class _RadiusAttrIntEnumVal(_SpecificRadiusAttr): 

965 """ 

966 Implements a RADIUS attribute which value field is 4 bytes long integer. 

967 """ 

968 

969 __slots__ = ["val"] 

970 

971 fields_desc = [ 

972 ByteEnumField("type", 6, _radius_attribute_types), 

973 ByteField("len", 6), 

974 MultiEnumField( 

975 "value", 

976 0, 

977 _radius_attrs_values, 

978 depends_on=lambda p: p.type, 

979 fmt="I" 

980 ) 

981 ] 

982 

983 

984class RadiusAttr_Service_Type(_RadiusAttrIntEnumVal): 

985 """RFC 2865""" 

986 val = 6 

987 

988 

989class RadiusAttr_Framed_Protocol(_RadiusAttrIntEnumVal): 

990 """RFC 2865""" 

991 val = 7 

992 

993 

994class RadiusAttr_Acct_Status_Type(_RadiusAttrIntEnumVal): 

995 """RFC 2866""" 

996 val = 40 

997 

998 

999class RadiusAttr_Acct_Authentic(_RadiusAttrIntEnumVal): 

1000 """RFC 2866""" 

1001 val = 45 

1002 

1003 

1004class RadiusAttr_Acct_Terminate_Cause(_RadiusAttrIntEnumVal): 

1005 """RFC 2866""" 

1006 val = 49 

1007 

1008 

1009class RadiusAttr_NAS_Port_Type(_RadiusAttrIntEnumVal): 

1010 """RFC 2865""" 

1011 val = 61 

1012 

1013 

1014class _EAPPacketField(PacketLenField): 

1015 """ 

1016 Handles EAP-Message attribute value (the actual EAP packet). 

1017 """ 

1018 

1019 def m2i(self, pkt, m): 

1020 ret = None 

1021 eap_packet_len = struct.unpack("!H", m[2:4])[0] 

1022 if eap_packet_len < 254: 

1023 # If the EAP packet has not been fragmented, build a Scapy EAP 

1024 # packet from the data. 

1025 ret = EAP(m) 

1026 else: 

1027 ret = conf.raw_layer(m) 

1028 return ret 

1029 

1030 

1031class RadiusAttr_EAP_Message(RadiusAttribute): 

1032 """ 

1033 Implements the "EAP-Message" attribute (RFC 3579). 

1034 """ 

1035 name = "EAP-Message" 

1036 match_subclass = True 

1037 fields_desc = [ 

1038 ByteEnumField("type", 79, _radius_attribute_types), 

1039 FieldLenField( 

1040 "len", 

1041 None, 

1042 "value", 

1043 "B", 

1044 adjust=lambda pkt, x: x + 2 

1045 ), 

1046 _EAPPacketField("value", "", EAP, length_from=lambda p: p.len - 2) 

1047 ] 

1048 

1049 def post_dissect(self, s): 

1050 if not conf.contribs.get("radius", {}).get("auto-defrag", True): 

1051 return s 

1052 if isinstance(self.value, conf.raw_layer): 

1053 # Defragment 

1054 x = s 

1055 buf = self.value.load 

1056 while x and struct.unpack("!B", x[:1])[0] == 79: 

1057 # Let's carefully avoid the infinite loop 

1058 length = struct.unpack("!B", x[1:2])[0] 

1059 if not length: 

1060 return s 

1061 buf, x = buf + x[2:length], x[length:] 

1062 if length < 254: 

1063 self.value = EAP(buf) 

1064 return x 

1065 return s 

1066 

1067 

1068class RadiusAttr_Vendor_Specific(RadiusAttribute): 

1069 """ 

1070 Implements the "Vendor-Specific" attribute, as described in RFC 2865. 

1071 """ 

1072 

1073 name = "Vendor-Specific" 

1074 match_subclass = True 

1075 fields_desc = [ 

1076 ByteEnumField("type", 26, _radius_attribute_types), 

1077 FieldLenField( 

1078 "len", 

1079 None, 

1080 "value", 

1081 "B", 

1082 adjust=lambda pkt, x: len(pkt.value) + 8 

1083 ), 

1084 IntField("vendor_id", 0), 

1085 ByteField("vendor_type", 0), 

1086 FieldLenField( 

1087 "vendor_len", 

1088 None, 

1089 "value", 

1090 "B", 

1091 adjust=lambda p, x: len(p.value) + 2 

1092 ), 

1093 StrLenField("value", "", length_from=lambda p: p.vendor_len - 2) 

1094 ] 

1095 

1096 

1097# See IANA RADIUS Packet Type Codes registry 

1098_packet_codes = { 

1099 1: "Access-Request", 

1100 2: "Access-Accept", 

1101 3: "Access-Reject", 

1102 4: "Accounting-Request", 

1103 5: "Accounting-Response", 

1104 6: "Accounting-Status (now Interim Accounting)", 

1105 7: "Password-Request", 

1106 8: "Password-Ack", 

1107 9: "Password-Reject", 

1108 10: "Accounting-Message", 

1109 11: "Access-Challenge", 

1110 12: "Status-Server (experimental)", 

1111 13: "Status-Client (experimental)", 

1112 21: "Resource-Free-Request", 

1113 22: "Resource-Free-Response", 

1114 23: "Resource-Query-Request", 

1115 24: "Resource-Query-Response", 

1116 25: "Alternate-Resource-Reclaim-Request", 

1117 26: "NAS-Reboot-Request", 

1118 27: "NAS-Reboot-Response", 

1119 28: "Reserved", 

1120 29: "Next-Passcode", 

1121 30: "New-Pin", 

1122 31: "Terminate-Session", 

1123 32: "Password-Expired", 

1124 33: "Event-Request", 

1125 34: "Event-Response", 

1126 40: "Disconnect-Request", 

1127 41: "Disconnect-ACK", 

1128 42: "Disconnect-NAK", 

1129 43: "CoA-Request", 

1130 44: "CoA-ACK", 

1131 45: "CoA-NAK", 

1132 50: "IP-Address-Allocate", 

1133 51: "IP-Address-Release", 

1134 52: "Protocol-Error", 

1135 250: "Experimental Use", 

1136 251: "Experimental Use", 

1137 252: "Experimental Use", 

1138 253: "Experimental Use", 

1139 254: "Reserved", 

1140 255: "Reserved" 

1141} 

1142 

1143 

1144class Radius(Packet): 

1145 """ 

1146 Implements a RADIUS packet (RFC 2865). 

1147 """ 

1148 

1149 name = "RADIUS" 

1150 fields_desc = [ 

1151 ByteEnumField("code", 1, _packet_codes), 

1152 ByteField("id", 0), 

1153 FieldLenField( 

1154 "len", 

1155 None, 

1156 "attributes", 

1157 "H", 

1158 adjust=lambda pkt, x: len(pkt.attributes) + 20 

1159 ), 

1160 XStrFixedLenField("authenticator", "", 16), 

1161 PacketListField( 

1162 "attributes", 

1163 [], 

1164 RadiusAttribute, 

1165 length_from=lambda pkt: pkt.len - 20 

1166 ) 

1167 ] 

1168 

1169 def compute_authenticator(self, packed_request_auth, shared_secret): 

1170 """ 

1171 Computes the authenticator field (RFC 2865 - Section 3) 

1172 """ 

1173 

1174 data = prepare_packed_data(self, packed_request_auth) 

1175 radius_mac = hashlib.md5(data + shared_secret) 

1176 return radius_mac.digest() 

1177 

1178 def post_build(self, p, pay): 

1179 p += pay 

1180 length = self.len 

1181 if length is None: 

1182 length = len(p) 

1183 p = p[:2] + struct.pack("!H", length) + p[4:] 

1184 return p 

1185 

1186 

1187bind_bottom_up(UDP, Radius, sport=1812) 

1188bind_bottom_up(UDP, Radius, dport=1812) 

1189bind_bottom_up(UDP, Radius, sport=1813) 

1190bind_bottom_up(UDP, Radius, dport=1813) 

1191bind_bottom_up(UDP, Radius, sport=3799) 

1192bind_bottom_up(UDP, Radius, dport=3799) 

1193bind_layers(UDP, Radius, sport=1812, dport=1812)