26#include <freeradius-devel/radius/defs.h>
27#include <freeradius-devel/util/packet.h>
28#include <freeradius-devel/util/rand.h>
29#include <freeradius-devel/util/log.h>
30#include <freeradius-devel/util/dbuff.h>
31#include <freeradius-devel/io/test_point.h>
33#define RADIUS_AUTH_VECTOR_OFFSET 4
34#define RADIUS_HEADER_LENGTH 20
35#define RADIUS_MAX_STRING_LENGTH 253
36#define RADIUS_MAX_TUNNEL_PASSWORD_LENGTH 249
37#define RADIUS_AUTH_VECTOR_LENGTH 16
38#define RADIUS_MESSAGE_AUTHENTICATOR_LENGTH 16
39#define RADIUS_MAX_ATTRIBUTES 255
40#define RADIUS_MAX_PACKET_SIZE 4096
42#define RADIUS_VENDORPEC_USR 429
43#define RADIUS_VENDORPEC_LUCENT 4846
44#define RADIUS_VENDORPEC_STARENT 8164
51#define FR_RADIUS_PACKET_CODE_VALID(_x) ((_x > 0) && (_x < FR_RADIUS_CODE_MAX))
53#define AUTH_PASS_LEN (RADIUS_AUTH_VECTOR_LENGTH)
55#define FR_TUNNEL_FR_ENC_LENGTH(_x) (2 + 1 + _x + PAD(_x + 1, 16))
152#ifdef NAS_VIOLATES_RFC
153 bool allow_vulnerable_clients;
180typedef enum : int8_t {
214 "%s is not a RADIUS attribute, it is from the \"%s\" dictionary",
218 if (!
fr_cond_assert_msg(flags,
"%s is not a RADIUS attribute, it has no protocol extension",
219 da->name))
return &no_flags;
278 bool require_message_authenticator,
bool limit_proxy_state) CC_HINT(
nonnull (1,3));
284 char const *
secret,
size_t secret_len,
uint8_t const *vector);
291 uint8_t *packet,
size_t packet_len,
295 uint8_t *packet,
size_t packet_len,
321#define fr_packet_log_hex(_log, _packet) _fr_packet_log_hex(_log, _packet, __FILE__, __LINE__)
static int packet_ctx
the tests pass only the address of packet_ctx
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
fr_radius_packet_code_t
RADIUS packet codes.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
fr_dict_protocol_t const * fr_dict_protocol(fr_dict_t const *dict)
Return the protocol descriptor for the dictionary.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
static fr_internal_encode_ctx_t encode_ctx
bool fr_radius_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
fr_dict_protocol_t libfreeradius_radius_dict_protocol
unsigned int has_tag
Attribute has a tag.
bool secure_transport
for TLS
ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
fr_radius_tag_ctx_t ** tags
for decoding tagged attributes
ssize_t fr_radius_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret))
Encode a packet.
ssize_t fr_radius_ascend_secret(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, size_t secret_len, uint8_t const *vector)
Do Ascend-Send / Recv-Secret calculation.
fr_fast_rand_t rand_ctx
for tunnel passwords
fr_radius_ctx_t const * common
ssize_t fr_radius_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *list, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Create a "normal" fr_pair_t from the given data.
uint8_t request_code
original code for the request.
ssize_t fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Print an Ascend binary filter attribute to a string,.
ssize_t fr_radius_decode_simple(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, uint8_t const *vector, char const *secret))
Simple wrapper for callers who just need a shared secret.
uint8_t const * request_authenticator
unsigned int abinary
Attribute is in "abinary" format.
ssize_t fr_radius_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, fr_radius_decode_ctx_t *decode_ctx)
size_t fr_radius_limit_proxy_state_table_len
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len))
Sign a previously encoded packet.
fr_radius_attr_flags_encrypt_t
@ RADIUS_FLAG_ENCRYPT_INVALID
Invalid encryption flag.
@ RADIUS_FLAG_ENCRYPT_NONE
No encryption.
@ RADIUS_FLAG_ENCRYPT_USER_PASSWORD
Encrypt attribute RFC 2865 style.
@ RADIUS_FLAG_ENCRYPT_ASCEND_SECRET
Encrypt attribute ascend style.
@ RADIUS_FLAG_ENCRYPT_TUNNEL_PASSWORD
Encrypt attribute RFC 2868 style.
bool foreign
are we in a foreign protocol?
ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, fr_radius_decode_ctx_t *packet_ctx)
Convert TLVs to one or more VPs.
char const * fr_radius_decode_fail_reason[FR_RADIUS_FAIL_MAX+1]
static bool fr_radius_flag_long_extended(fr_dict_attr_t const *da)
size_t fr_radius_require_ma_table_len
int fr_radius_packet_send(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret))
Reply to the request.
bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
unsigned int concat
Attribute is concatenated.
uint8_t const * end
end of the packet
fr_radius_decode_fail_t
Failure reasons.
@ FR_RADIUS_FAIL_ATTRIBUTE_DECODE
@ FR_RADIUS_FAIL_UNEXPECTED_REQUEST_CODE
@ FR_RADIUS_FAIL_ATTRIBUTE_OVERFLOW
@ FR_RADIUS_FAIL_MA_INVALID_LENGTH
@ FR_RADIUS_FAIL_MIN_LENGTH_FIELD
@ FR_RADIUS_FAIL_INVALID_ATTRIBUTE
@ FR_RADIUS_FAIL_IO_ERROR
@ FR_RADIUS_FAIL_MAX_LENGTH_PACKET
@ FR_RADIUS_FAIL_MA_MISSING
@ FR_RADIUS_FAIL_TOO_MANY_ATTRIBUTES
@ FR_RADIUS_FAIL_UNEXPECTED_RESPONSE_CODE
@ FR_RADIUS_FAIL_UNKNOWN_PACKET_CODE
@ FR_RADIUS_FAIL_MIN_LENGTH_MISMATCH
@ FR_RADIUS_FAIL_NO_MATCHING_REQUEST
@ FR_RADIUS_FAIL_HEADER_OVERFLOW
@ FR_RADIUS_FAIL_MIN_LENGTH_PACKET
@ FR_RADIUS_FAIL_ATTRIBUTE_TOO_SHORT
@ FR_RADIUS_FAIL_MA_INVALID
@ FR_RADIUS_FAIL_PROXY_STATE_MISSING_MA
@ FR_RADIUS_FAIL_MA_TOO_MANY
int fr_radius_global_init(void)
bool limit_proxy_state
Don't allow Proxy-State in requests.
ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a data structure into a RADIUS attribute.
void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
uint8_t const * request_authenticator
static bool fr_radius_flag_extended(fr_dict_attr_t const *da)
uint8_t tag
current tag for encoding
unsigned int extended
Attribute is an extended attribute.
fr_radius_attr_flags_encrypt_t encrypt
Attribute is encrypted.
int fr_radius_decode_tlv_ok(uint8_t const *data, size_t length, size_t dv_type, size_t dv_length)
Check if a set of RADIUS formatted TLVs are OK.
bool require_message_authenticator
void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
int fr_radius_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret))
Sign a previously encoded packet.
TALLOC_CTX * tag_root_ctx
Where to allocate new tag attributes.
size_t fr_radius_request_name_table_len
int fr_radius_packet_verify(fr_packet_t *packet, fr_packet_t *original, char const *secret))
Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet.
ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
static fr_radius_attr_flags_encrypt_t fr_radius_flag_encrypted(fr_dict_attr_t const *da)
ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *parent, uint8_t const *data, size_t const attr_len, void *packet_ctx)
Create any kind of VP from the attribute contents.
int fr_radius_allow_reply(fr_radius_packet_code_t code, bool allowed[static FR_RADIUS_CODE_MAX])
static bool fr_radius_flag_has_tag(fr_dict_attr_t const *da)
bool verify
can skip verify for dynamic clients
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
fr_radius_ctx_t const * common
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_message_authenticator, bool limit_proxy_state))
Verify the signature of a request / response packet.
void fr_radius_global_free(void)
fr_radius_require_ma_t
Control whether Message-Authenticator is required in Access-Requests.
@ FR_RADIUS_REQUIRE_MA_NO
Do not require Message-Authenticator.
@ FR_RADIUS_REQUIRE_MA_YES
Require Message-Authenticator.
@ FR_RADIUS_REQUIRE_MA_AUTO
Only require Message-Authenticator if we've previously received a packet from this client with Messag...
unsigned int long_extended
Attribute is a long extended attribute.
fr_radius_limit_proxy_state_t
Control whether Proxy-State is allowed in Access-Requests.
@ FR_RADIUS_LIMIT_PROXY_STATE_NO
Do not limit Proxy-State.
@ FR_RADIUS_LIMIT_PROXY_STATE_AUTO
Do not allow Proxy-State unless:
@ FR_RADIUS_LIMIT_PROXY_STATE_YES
Limit Proxy-State.
fr_table_num_sorted_t const fr_radius_limit_proxy_state_table[]
fr_radius_decode_fail_t reason
reason for decode failure
ssize_t fr_radius_encode_abinary(fr_pair_t const *vp, fr_dbuff_t *dbuff)
Encode a string to abinary.
fr_table_num_sorted_t const fr_radius_request_name_table[]
fr_table_num_sorted_t const fr_radius_require_ma_table[]
static bool fr_radius_flag_abinary(fr_dict_attr_t const *da)
ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
static fr_radius_attr_flags_t const * fr_radius_attr_flags(fr_dict_attr_t const *da)
Return RADIUS-specific flags for a given attribute.
bool tunnel_password_zeros
check for trailing zeros on decode
bool add_proxy_state
do we add a Proxy-State?
static bool fr_radius_flag_concat(fr_dict_attr_t const *da)
bool seen_message_authenticator
void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code)
Basic validation of RADIUS packet header.
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
fr_pair_list_t * tag_root
Where to insert tag attributes.
Smaller fast random number generator.
Stores an attribute, a value and various bits of other data.
An element in a lexicographically sorted array of name to num mappings.
static fr_sbuff_err_t char size_t fr_sbuff_t * in
static fr_sbuff_err_t char ** out