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>
32 #define RADIUS_AUTH_VECTOR_OFFSET 4
33 #define RADIUS_HEADER_LENGTH 20
34 #define RADIUS_MAX_STRING_LENGTH 253
35 #define RADIUS_MAX_TUNNEL_PASSWORD_LENGTH 249
36 #define RADIUS_AUTH_VECTOR_LENGTH 16
37 #define RADIUS_MESSAGE_AUTHENTICATOR_LENGTH 16
38 #define RADIUS_MAX_PASS_LENGTH 256
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))
97 #define flag_has_tag(_flags) (!(_flags)->extra && (((_flags)->subtype == FLAG_HAS_TAG) || ((_flags)->subtype == FLAG_TAGGED_TUNNEL_PASSWORD)))
98 #define flag_concat(_flags) (!(_flags)->extra && (_flags)->subtype == FLAG_CONCAT)
99 #define flag_abinary(_flags) (!(_flags)->extra && (_flags)->subtype == FLAG_ABINARY)
100 #define flag_encrypted(_flags) (!(_flags)->extra && (_flags)->subtype >= FLAG_TAGGED_TUNNEL_PASSWORD)
101 #define flag_extended(_flags) (!(_flags)->extra && (((_flags)->subtype == FLAG_EXTENDED_ATTR) || (_flags)->subtype == FLAG_LONG_EXTENDED_ATTR))
102 #define flag_long_extended(_flags) (!(_flags)->extra && (_flags)->subtype == FLAG_LONG_EXTENDED_ATTR)
103 #define flag_tunnel_password(_flags) (!(_flags)->extra && (((_flags)->subtype == FLAG_ENCRYPT_TUNNEL_PASSWORD) || ((_flags)->subtype == FLAG_TAGGED_TUNNEL_PASSWORD)))
179 uint8_t *packet,
size_t packet_len,
183 uint8_t *packet,
size_t packet_len,
209 #define fr_packet_log_hex(_log, _packet) _fr_packet_log_hex(_log, _packet, __FILE__, __LINE__)
234 void *packet_ctx) CC_HINT(
nonnull);
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
static fr_internal_encode_ctx_t encode_ctx
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
@ FLAG_CONCAT
the attribute is concatenated
@ FLAG_NONE
No extra flags.
@ FLAG_ENCRYPT_ASCEND_SECRET
Encrypt attribute ascend style.
@ FLAG_ENCRYPT_TUNNEL_PASSWORD
Encrypt attribute RFC 2868 style.
@ FLAG_ENCRYPT_USER_PASSWORD
Encrypt attribute RFC 2865 style.
@ FLAG_TAGGED_TUNNEL_PASSWORD
the attribute has a tag and is encrypted
@ FLAG_HAS_TAG
the attribute has a tag
@ FLAG_EXTENDED_ATTR
the attribute is an extended attribute
@ FLAG_ABINARY
the attribute is in "abinary" format
@ FLAG_LONG_EXTENDED_ATTR
the attribute is a long extended attribute
fr_fast_rand_t rand_ctx
for tunnel passwords
bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_ma, decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_ma))
Verify a request / response packet.
bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_ma, decode_fail_t *reason))
See if the data pointed to by PTR is a valid RADIUS packet.
uint64_t my_proxy_state
if so, this is its value
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
int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret))
Sign a previously encoded packet.
ssize_t fr_radius_ascend_secret(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, uint8_t const *vector)
Do Ascend-Send / Recv-Secret calculation.
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)
int fr_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.
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len))
Sign a previously encoded packet.
bool add_proxy_state
do we add a Proxy-State?
bool disallow_tunnel_passwords
not all packets can have tunnel passwords
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.
uint8_t const * end
end of the packet
ssize_t fr_radius_encode(uint8_t *packet, size_t packet_len, uint8_t const *original, char const *secret, size_t secret_len, int code, int id, fr_pair_list_t *vps)
Encode VPS into a raw RADIUS packet.
int fr_radius_global_init(void)
int fr_packet_send(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret))
Reply to the request.
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
uint8_t tag
current tag for encoding
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)
TALLOC_CTX * tag_root_ctx
Where to allocate new tag attributes.
#define RADIUS_AUTH_VECTOR_LENGTH
size_t fr_radius_request_name_table_len
ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
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.
@ DECODE_FAIL_INVALID_ATTRIBUTE
@ DECODE_FAIL_ATTRIBUTE_UNDERFLOW
@ DECODE_FAIL_MIN_LENGTH_FIELD
@ DECODE_FAIL_HEADER_OVERFLOW
@ DECODE_FAIL_ATTRIBUTE_TOO_SHORT
@ DECODE_FAIL_ATTRIBUTE_OVERFLOW
@ DECODE_FAIL_TOO_MANY_ATTRIBUTES
@ DECODE_FAIL_MIN_LENGTH_PACKET
@ DECODE_FAIL_MIN_LENGTH_MISMATCH
@ DECODE_FAIL_MA_INVALID_LENGTH
@ DECODE_FAIL_UNKNOWN_PACKET_CODE
bool verify
can skip verify for dynamic clients
void fr_radius_global_free(void)
uint32_t acct_delay_time
additional time to add to acct_delay_time
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[]
int salt_offset
for tunnel passwords
ssize_t fr_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_encode_dbuff(fr_dbuff_t *dbuff, uint8_t const *original, char const *secret, UNUSED size_t secret_len, int code, int id, fr_pair_list_t *vps)
bool tunnel_password_zeros
check for trailing zeros on decode
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]
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_ma)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
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.
int fr_radius_allow_reply(int code, bool allowed[static FR_RADIUS_CODE_MAX])
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 size_t char fr_sbuff_t size_t inlen
static size_t char ** out