networkclient
Packet manipulation

Data Structures

struct  radius_packet
 

Typedefs

typedef struct radius_packet RADIUS_PACKET
 
typedef int(* nr_packet_walk_func_t) (void *, const DICT_ATTR *, const uint8_t *, size_t)
 

Functions

int nr_packet_ok (RADIUS_PACKET *packet)
 
int nr_packet_ok_raw (const uint8_t *data, size_t sizeof_data)
 
ssize_t nr_packet_encode (RADIUS_PACKET *packet, const RADIUS_PACKET *original)
 
int nr_packet_decode (RADIUS_PACKET *packet, const RADIUS_PACKET *original)
 
int nr_packet_sign (RADIUS_PACKET *packet, const RADIUS_PACKET *original)
 
int nr_packet_verify (RADIUS_PACKET *packet, const RADIUS_PACKET *original)
 
int nr_packet_can_encode (RADIUS_PACKET *packet, const RADIUS_PACKET *original)
 
int nr_packet_walk (RADIUS_PACKET *packet, void *ctx, nr_packet_walk_func_t callback)
 
int nr_packet_response_ok (RADIUS_PACKET const *packet, RADIUS_PACKET const *response)
 

Detailed Description

These routines perform encoding and decoding of RADIUS packets.

Typedef Documentation

typedef int(* nr_packet_walk_func_t) (void *, const DICT_ATTR *, const uint8_t *, size_t)

A callback function used by nr_packet_walk().

The function should return 0 on success (i.e. keep walking), and otherwise a negative number indicating an error code (nr_error_t). That negative number will be used as the return code for nr_packet_walk().

typedef struct radius_packet RADIUS_PACKET

A structure which describes a RADIUS packet.

In general, it should not be necessary to refererence the elements of this structure.

Function Documentation

int nr_packet_can_encode ( RADIUS_PACKET packet,
const RADIUS_PACKET original 
)

See if a packet can be encoded.

This function is internal to the library.

Attention
This function should not be called.
Parameters
[in]packetThe RADIUS packet
[in]originalThe original request (if any)

References radius_packet::code, radius_packet::data, radius_packet::dst, radius_packet::id, radius_packet::length, NR_MAX_PACKET_CODE, nr_packet_codes, return_NR_ERR, radius_packet::sizeof_data, and radius_packet::src.

Referenced by nr_packet_encode(), nr_packet_init(), and nr_socket_send().

int nr_packet_decode ( RADIUS_PACKET packet,
const RADIUS_PACKET original 
)

Decodes a packet.

This function decodes a packet from the RADIUS_PACKET::data field into a sequence of VALUE_PAIR structures in the RADIUS_PACKET::vps list.

See also
nr_packet_encode() for the counterpart to this function
Parameters
[in]packetThe RADIUS packet to decode.
[in]originalThe original request, when decoding a response.
Returns
<0 on error, >= 0 on success.

References radius_packet::code, radius_packet::data, radius_packet::flags, radius_packet::id, radius_packet::length, value_pair::next, nr_attr2vp(), nr_debug_error, NR_MAX_ATTRIBUTES, NR_PACKET_DECODED, nr_packet_ok(), nr_vp_free(), return_NR_ERR, radius_packet::vector, and radius_packet::vps.

Referenced by main(), and nr_socket_recv_response().

Here is the call graph for this function:

ssize_t nr_packet_encode ( RADIUS_PACKET packet,
const RADIUS_PACKET original 
)

Encodes a packet.

This function encodes a packet using the fields of the RADIUS_PACKET structure. The RADIUS_PACKET::code and RADIUS_PACKET::id fields are used to fill in the relevant fields of the raw (encoded) packet. The RADIUS_PACKET::vps list is walked to encode the attributes. The packet is signed, if required.

The raw packet is placed into the RADIUS_PACKET::data field, up to RADIUS_PACKET::sizeof_data bytes. the RADIUS_PACKET::length field is updated with the length of the raw packet. This field is always less than, or equal to, the RADIUS_PACKET::size_data field. If there is insufficient room to store all of the attributes, then some attributes are silently discarded.

The RADIUS_PACKET::vector field is either calculated as part of the signing process, or is initialized by this function to be a random sequence of bytes. That field should therefore be left alone by the caller.

When the encoding has been successful, it sets the RADIUS_PACKET::encoded field to non-zero.

In addition, all required attribute "encryption" is performed.

User-Password. The vp_strvalue field is assumed to contain the "clear-text" version of the password. The encrypted version is calculated, and placed in the packet.

CHAP-Password. The vp_strvalue field is assumed to contain the "clear-text" version of the password. The encrypted version is calculated, and placed in the packet. If the RADIUS_PACKET::vps list contains a CHAP-Challenge attribute, it is used. Otherwise the RADIUS_PACKET::vector field is used a the challenge.

Message-Authenticator. The contents of the Message-Authenticator in the RADIUS_PACKET::vps list are ignored. Instead, a "place-holder" is put into the packt. Tthe correct value is calculated and placed into the packet by nr_packet_sign().

The RADIUS_PACKET::vps list is left untouched by this function, even when attribute encryption or signing is performed. Any VALUE_PAIR structures can therefore be taken from static "const" variables.

See also
nr_packet_decode() for the counterpart to this function
Parameters
[in]packetThe RADIUS packet to encode.
[in]originalThe original request, when encoding a response.
Returns
<0 on error, =0 for "insufficient room to encode the packet" >0 for "amount of data encoded"

References append_ma, radius_packet::data, radius_packet::flags, radius_packet::length, nr_packet_can_encode(), NR_PACKET_ENCODED, nr_packet_vps_append(), return_NR_ERR, and radius_packet::vps.

Referenced by nr_packet_sign().

Here is the call graph for this function:

int nr_packet_ok ( RADIUS_PACKET packet)

Verifies that a packet is "well formed".

This function performs basic validation to see if the packet is well formed. It is automatically called by nr_packet_decode().

Parameters
[in]packetA pointer to the RADIUS_PACKET data.
Returns
<0 means malformed, >= 0 means well-formed.

References radius_packet::data, radius_packet::flags, radius_packet::length, NR_PACKET_OK, nr_packet_ok_raw(), and return_NR_ERR.

Referenced by main(), nr_packet_decode(), nr_packet_verify(), nr_packet_walk(), nr_socket_recv(), and nr_socket_send_response().

Here is the call graph for this function:

int nr_packet_ok_raw ( const uint8_t *  data,
size_t  sizeof_data 
)

Verifies that a packet is "well formed".

This function performs basic validation to see if the packet is well formed. You should normally use nr_packet_ok() instead of this function.

Parameters
[in]dataA pointer to the raw packet data.
[in]sizeof_dataThe length of the raw packet data
Returns
<0 means malformed, >= 0 means well-formed.

References NR_MAX_PACKET_CODE, NR_MAX_PACKET_LEN, nr_packet_codes, and return_NR_ERR.

Referenced by nr_packet_ok().

int nr_packet_response_ok ( RADIUS_PACKET const *  packet,
RADIUS_PACKET const *  response 
)

Verify that a response matches a request.

It is used when receiving a response to a request. Only a few types of replies are allowed for each request. e.g. Accounting-Request packets can only recieve Accounting-Response replies.

If the response matches the request, the nr_packet_verify() function should be called to verify the packet signature. If the verification succeeds, then the ID can be released via the nr_track_id_release() function.

Parameters
[in]packetThe original request packet.
[in]responseThe packet which might match the request packet.
Returns
<0 for error, 0 for the response matches the request.

References radius_packet::code, radius_packet::id, PW_ACCESS_ACCEPT, PW_ACCESS_CHALLENGE, PW_ACCESS_REJECT, PW_ACCESS_REQUEST, PW_ACCOUNTING_REQUEST, PW_ACCOUNTING_RESPONSE, PW_COA_ACK, PW_COA_NAK, PW_COA_REQUEST, PW_DISCONNECT_ACK, PW_DISCONNECT_NAK, PW_DISCONNECT_REQUEST, PW_STATUS_SERVER, and return_NR_ERR.

Referenced by nr_socket_recv_response().

int nr_packet_sign ( RADIUS_PACKET packet,
const RADIUS_PACKET original 
)

Signs a packet so that it can be sent.

This function calculates the Message-Authenticator (if required), and signs the packet.

See also
nr_packet_verify() for the counterpart to this function
Parameters
[in]packetThe RADIUS packet to sign.
[in]originalThe original request, when signing a response.
Returns
<0 on error, >= 0 on success.

References radius_packet::attempts, radius_packet::code, radius_packet::data, radius_packet::flags, radius_packet::length, nr_debug_error, nr_hmac_md5(), NR_MD5_CTX, nr_MD5Final, nr_MD5Init, nr_MD5Update, nr_packet_encode(), NR_PACKET_ENCODED, NR_PACKET_SIGNED, PW_ACCESS_ACCEPT, PW_ACCESS_CHALLENGE, PW_ACCESS_REJECT, PW_ACCESS_REQUEST, PW_MESSAGE_AUTHENTICATOR, PW_STATUS_SERVER, return_NR_ERR, radius_packet::secret, radius_packet::sizeof_data, radius_packet::sizeof_secret, and radius_packet::vector.

Referenced by main(), nr_socket_send(), and nr_socket_send_response().

Here is the call graph for this function:

int nr_packet_verify ( RADIUS_PACKET packet,
const RADIUS_PACKET original 
)

Verifies that a packet is well-formed and contains the correct signature.

If "original" is specified, it also verifies that the packet is a response to the original request, and that it has the correct signature.

See also
nr_packet_sign() for the counterpart to this function
Parameters
[in]packetThe RADIUS packet to verify.
[in]originalThe original request, when verifying a response.
Returns
<0 on error, >= 0 on success.

References radius_packet::data, radius_packet::flags, radius_packet::length, nr_packet_ok(), NR_PACKET_VERIFIED, PW_MESSAGE_AUTHENTICATOR, return_NR_ERR, radius_packet::secret, and radius_packet::sizeof_secret.

Referenced by main(), and nr_socket_recv_response().

Here is the call graph for this function:

int nr_packet_walk ( RADIUS_PACKET packet,
void *  ctx,
nr_packet_walk_func_t  callback 
)

Walks over all attributes in a packet.

This function is an iterator which calls a user-supplied callback function for each attribute in the packet. It should be used instead of manually walking over the attributes. There are a number of odd corner cases when handling Vendor-Specific attributes, and it is easy to get those corner cases wrong.

This function iterates over all attributes, including nested VSAs. That is its main value.

Encrypted attributes such as User-Password are not decrypted.

Parameters
[in]packetThe packet containing the data
[in]ctxA user-supplied context. May be NULL
[in]callbackThe callback function where the information is passed.
Returns
<0 for error, 0 for success.

References radius_packet::data, nr_dict_vendor::length, radius_packet::length, nr_dict_vendor_byvalue(), nr_packet_ok(), nr_tlv_ok(), PW_VENDOR_SPECIFIC, return_NR_ERR, nr_dict_vendor::type, and nr_dict_vendor::vendor.

Here is the call graph for this function: