pyrad.packet – packet encoding and decoding

class pyrad.packet.Packet(code=0, id=None, secret=b'', authenticator=None, **attributes)[source]

Packet acts like a standard python map to provide simple access to the RADIUS attributes. Since RADIUS allows for repeated attributes the value will always be a sequence. pyrad makes sure to preserve the ordering when encoding and decoding packets.

There are two ways to use the map interface: if attribute names are used pyrad takes care of en-/decoding data. If the attribute type number (or a vendor ID/attribute type tuple for vendor attributes) is used you work with the raw data.

Attributes with the has_tag flag (RFC 2868) take a tag after the name, for example pkt['Tunnel-Type:1']. Without a tag the values of all tags are returned.

Normally you will not use this class directly, but one of the AuthPacket, AcctPacket or CoAPacket classes.

AddAttribute(key, value)[source]

Add an attribute to the packet. The values are appended to existing values of the attribute. Raw values of attributes which are not in the dictionary are set with pkt[code] = [value] instead.

Parameters:
  • key (string) – attribute name, with an optional tag for attributes with the has_tag flag ('Tunnel-Type:1')

  • value (depends on type of attribute) – value or list of values

static CreateAuthenticator()[source]

Create a packet authenticator. All RADIUS packets contain a sixteen byte authenticator which is used to authenticate replies from the RADIUS server and in the password hiding algorithm. This function returns a suitable random string that can be used as an authenticator.

Returns:

valid packet authenticator

Return type:

bytes

CreateID()[source]

Create a packet ID. All RADIUS requests have an ID which is used to identify a request. This is used to detect retries and replay attacks. This function returns a suitable random number that can be used as ID.

Returns:

ID number

Return type:

integer

CreateReply(**attributes)[source]

Create a new packet as a reply to this one. This method makes sure the authenticator and secret are copied over to the new instance.

DecodePacket(packet)[source]

Initialize the object from raw packet data. Decode a packet as received from the network.

Parameters:

packet (bytes) – raw packet

ReplyPacket()[source]

Create a ready-to-transmit reply packet. Returns a RADIUS packet which can be directly transmitted to a RADIUS client. This differs from RequestPacket() in how the authenticator is calculated.

Returns:

raw packet

Return type:

bytes

SaltCrypt(value)[source]

Encrypt a value with the salt encryption of RFC 2868 section 3.5 (attributes with encrypt=2).

Parameters:

value (str or bytes) – plaintext value

Returns:

encrypted value including salt

Return type:

bytes

Raises:

ValueError – if the value is longer than 255 octets

SaltDecrypt(value)[source]

Decrypt a value encrypted with the salt encryption of RFC 2868 section 3.5 (attributes with encrypt=2).

Parameters:

value (bytes) – encrypted value including salt

Returns:

decrypted value

Return type:

bytes

VerifyReply(reply, rawreply=None, enforce_ma=False)[source]

Verify that a reply belongs to this request. Checks the packet ID and the response authenticator and, as countermeasure against the BlastRADIUS attack (CVE-2024-3596), the Message-Authenticator and the Proxy-State attributes.

Parameters:
  • reply (pyrad.packet.Packet) – reply packet

  • rawreply (bytes) – reply as received from the network, defaults to the raw packet the reply was decoded from

  • enforce_ma (bool) – require a Message-Authenticator in replies to Access-Request and Status-Server packets

Returns:

True if the reply is valid else False

Return type:

bool

add_message_authenticator()[source]

Add a Message-Authenticator (RFC 2869 section 5.14) as first attribute, as recommended as countermeasure against the BlastRADIUS attack (CVE-2024-3596). The value is calculated when the packet is encoded.

get(key, failobj=None)[source]

Return the value for key if key is in the dictionary, else default.

has_key(key)

True if the dictionary has the specified key, else False.

keys() → a set-like object providing a view on D's keys[source]
verify_message_authenticator(secret=None, original_authenticator=None, original_code=None)[source]

Verify packet Message-Authenticator.

To verify a received reply, the authenticator and code of the request must be passed as original_authenticator and original_code.

Returns:

False if verification failed else True

Return type:

boolean

class pyrad.packet.AuthPacket(code=1, id=None, secret=b'', authenticator=None, auth_type='pap', **attributes)[source]

RADIUS authentication packets. This class is a specialization of the generic Packet class for Access-Request, Status-Server and their replies.

CreateReply(**attributes)[source]

Create a new packet as a reply to this one. This method makes sure the authenticator and secret are copied over to the new instance.

PwCrypt(password)[source]

Obfuscate password. RADIUS hides passwords in packets by using an algorithm based on the MD5 hash of the packet authenticator and RADIUS secret. If no authenticator has been set before calling PwCrypt one is created automatically. Changing the authenticator after setting a password that has been encrypted using this function will not work.

Parameters:

password (str or bytes) – plaintext password

Returns:

obfuscated version of the password

Return type:

bytes

Raises:

ValueError – if the password is longer than 128 octets

PwDecrypt(password)[source]

De-Obfuscate a RADIUS password. RADIUS hides passwords in packets by using an algorithm based on the MD5 hash of the packet authenticator and RADIUS secret. This function reverses the obfuscation process.

The password is decoded as UTF-8, the encoding RFC 2865 uses for text; invalid UTF-8 sequences (for example if the secret is wrong) are ignored.

Parameters:

password (bytes) – obfuscated form of password

Returns:

plaintext password

Return type:

str

RequestPacket()[source]

Create a ready-to-transmit authentication request packet. Return a RADIUS packet which can be directly transmitted to a RADIUS server.

Returns:

raw packet

Return type:

bytes

VerifyAuthRequest()[source]

Check whether the authenticator is an accounting-style request authenticator: the MD5 hash of the packet header, 16 zero octets, the attributes and the secret (as for Accounting-Request, RFC 2866 section 3).

This is not a verification of Access-Request packets: their Request Authenticator is a random number (RFC 2865 section 3), so this check fails for them. Use verify_message_authenticator to authenticate an Access-Request or Status-Server packet with a Message-Authenticator.

Returns:

True if verification passed else False

Return type:

boolean

VerifyChapPasswd(userpwd)[source]

Verify the CHAP-Password of an Access-Request (RFC 2865 section 2.2). The CHAP-Challenge attribute is used as challenge if present, else the request authenticator.

Parameters:

userpwd (str or bytes) – plaintext password

Returns:

True if the password matches else False, also if there is no CHAP-Password attribute

Return type:

bool

class pyrad.packet.AcctPacket(code=4, id=None, secret=b'', authenticator=None, **attributes)[source]

RADIUS accounting packets. This class is a specialization of the generic Packet class for accounting packets.

CreateReply(**attributes)[source]

Create a new packet as a reply to this one. This method makes sure the authenticator and secret are copied over to the new instance.

RequestPacket()[source]

Create a ready-to-transmit accounting request packet. Return a RADIUS packet which can be directly transmitted to a RADIUS server.

A Status-Server packet (RFC 5997 section 3) gets a random Request Authenticator, like an Access-Request, and a Message-Authenticator unless message_authenticator is set to False.

Returns:

raw packet

Return type:

bytes

VerifyAcctRequest()[source]

Verify request authenticator.

The Request Authenticator of a Status-Server packet is random (RFC 5997 section 3), for these packets the Message-Authenticator is verified instead, and a packet without one fails verification.

Returns:

True if verification passed else False

Return type:

boolean

class pyrad.packet.CoAPacket(code=43, id=None, secret=b'', authenticator=None, **attributes)[source]

RADIUS CoA packets. This class is a specialization of the generic Packet class for CoA packets.

CreateReply(**attributes)[source]

Create a new packet as a reply to this one. This method makes sure the authenticator and secret are copied over to the new instance.

RequestPacket()[source]

Create a ready-to-transmit CoA request packet. Return a RADIUS packet which can be directly transmitted to a RADIUS server.

Returns:

raw packet

Return type:

bytes

VerifyCoARequest()[source]

Verify request authenticator.

Returns:

True if verification passed else False

Return type:

boolean

class pyrad.packet.PacketError[source]

Constants

The pyrad.packet module defines several common constants that are useful when dealing with RADIUS packets.

The following packet codes are defined:

Constant name

Value

AccessRequest

1

AccessAccept

2

AccessReject

3

AccountingRequest

4

AccountingResponse

5

AccessChallenge

11

StatusServer

12

StatusClient

13

DisconnectRequest

40

DisconnectACK

41

DisconnectNAK

42

CoARequest

43

CoAACK

44

CoANAK

45