From: Alan T. DeKok Date: Wed, 18 Dec 2024 16:03:39 +0000 (+0100) Subject: make decode_fail_t radius specific. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5a548f0d3212bd2e5bcd26d304bf8148b017262;p=thirdparty%2Ffreeradius-server.git make decode_fail_t radius specific. nothing else needs it, and it's full of RADIUS things --- diff --git a/src/bin/radclient-ng.c b/src/bin/radclient-ng.c index 55dfc93959f..8be4f61b752 100644 --- a/src/bin/radclient-ng.c +++ b/src/bin/radclient-ng.c @@ -1396,6 +1396,7 @@ int main(int argc, char **argv) .verify = { .require_message_authenticator = false, .max_attributes = RADIUS_MAX_ATTRIBUTES, + .max_packet_size = 4096, }, }; diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index 86b3f3a9b73..73344aa0c2d 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -1278,7 +1278,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt uint8_t version; /* IP header version */ bool response; /* Was it a response code */ - decode_fail_t reason; /* Why we failed decoding the packet */ + fr_radius_decode_fail_t reason; /* Why we failed decoding the packet */ static uint64_t captured = 0; rs_status_t status = RS_NORMAL; /* Any special conditions (RTX, Unlinked, ID-Reused) */ diff --git a/src/lib/io/test_point.h b/src/lib/io/test_point.h index 7587a6048c5..584bf1d74fc 100644 --- a/src/lib/io/test_point.h +++ b/src/lib/io/test_point.h @@ -19,26 +19,6 @@ #include "proto.h" #include "pair.h" -/** Failure reasons */ -typedef enum { - DECODE_FAIL_NONE = 0, - DECODE_FAIL_MIN_LENGTH_PACKET, - DECODE_FAIL_MIN_LENGTH_FIELD, - DECODE_FAIL_MIN_LENGTH_MISMATCH, - DECODE_FAIL_HEADER_OVERFLOW, - DECODE_FAIL_UNKNOWN_PACKET_CODE, - DECODE_FAIL_INVALID_ATTRIBUTE, - DECODE_FAIL_ATTRIBUTE_TOO_SHORT, - DECODE_FAIL_ATTRIBUTE_OVERFLOW, - DECODE_FAIL_MA_INVALID_LENGTH, - DECODE_FAIL_ATTRIBUTE_UNDERFLOW, - DECODE_FAIL_TOO_MANY_ATTRIBUTES, - DECODE_FAIL_MA_MISSING, - DECODE_FAIL_MA_INVALID, - DECODE_FAIL_UNKNOWN, - DECODE_FAIL_MAX -} decode_fail_t; - /** Allocate an encoder/decoder ctx * * @param[out] out Where the decoder context should be written. diff --git a/src/listen/radius/proto_radius_tcp.c b/src/listen/radius/proto_radius_tcp.c index dd0438cb9ef..f860ba14f02 100644 --- a/src/listen/radius/proto_radius_tcp.c +++ b/src/listen/radius/proto_radius_tcp.c @@ -106,7 +106,7 @@ static ssize_t mod_read(fr_listen_t *li, UNUSED void **packet_ctx, fr_time_t *re proto_radius_tcp_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_radius_tcp_thread_t); ssize_t data_size; size_t packet_len, in_buffer; - decode_fail_t reason; + fr_radius_decode_fail_t reason; /* * We may have read multiple packets in the previous read. In which case the buffer may already diff --git a/src/listen/radius/proto_radius_udp.c b/src/listen/radius/proto_radius_udp.c index dcf14e76f4e..7d964b3f570 100644 --- a/src/listen/radius/proto_radius_udp.c +++ b/src/listen/radius/proto_radius_udp.c @@ -122,7 +122,7 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time int flags; ssize_t data_size; size_t packet_len; - decode_fail_t reason; + fr_radius_decode_fail_t reason; *leftover = 0; /* always for UDP */ diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index dc0ce96c0ff..5b442d55232 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -258,7 +258,7 @@ static void conn_writable_status_check(UNUSED fr_event_list_t *el, UNUSED int f static int encode(rlm_radius_udp_t const *inst, request_t *request, udp_request_t *u, uint8_t id); -static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, +static fr_radius_decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, udp_handle_t *h, request_t *request, udp_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len); @@ -1112,7 +1112,7 @@ static int8_t request_prioritise(void const *one, void const *two) * - DECODE_FAIL_NONE on success. * - DECODE_FAIL_* on failure. */ -static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, +static fr_radius_decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, udp_handle_t *h, request_t *request, udp_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len) @@ -1936,7 +1936,7 @@ static void request_demux(UNUSED fr_event_list_t *el, trunk_connection_t *tconn, udp_request_t *u; udp_result_t *r; radius_track_entry_t *rr; - decode_fail_t reason; + fr_radius_decode_fail_t reason; uint8_t code = 0; fr_pair_list_t reply; diff --git a/src/modules/rlm_radius2/bio.c b/src/modules/rlm_radius2/bio.c index 3b6f1e8db34..d5e2eba0193 100644 --- a/src/modules/rlm_radius2/bio.c +++ b/src/modules/rlm_radius2/bio.c @@ -159,7 +159,7 @@ static void conn_writable_status_check(UNUSED fr_event_list_t *el, UNUSED int f static int encode(rlm_radius_t const *inst, request_t *request, bio_request_t *u, uint8_t id); -static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, +static fr_radius_decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, bio_handle_t *h, request_t *request, bio_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len); @@ -641,7 +641,7 @@ static void bio_error(fr_bio_t *bio) static fr_bio_verify_action_t rlm_radius_verify(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size) { - decode_fail_t failure; + fr_radius_decode_fail_t failure; size_t in_buffer = *size; bio_handle_t *h = verify_ctx; uint8_t const *hdr = data; @@ -1067,7 +1067,7 @@ static int8_t request_prioritise(void const *one, void const *two) * - DECODE_FAIL_NONE on success. * - DECODE_FAIL_* on failure. */ -static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, +static fr_radius_decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, bio_handle_t *h, request_t *request, bio_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len) @@ -1888,7 +1888,7 @@ static void request_demux(UNUSED fr_event_list_t *el, trunk_connection_t *tconn, bio_request_t *u; bio_result_t *r; radius_track_entry_t *rr; - decode_fail_t reason; + fr_radius_decode_fail_t reason; uint8_t code = 0; fr_pair_list_t reply; fr_pair_t *vp; diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index e8ad10c88ef..5fbeea61a17 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -513,13 +513,13 @@ int fr_radius_sign(uint8_t *packet, uint8_t const *vector, * - False on failure. */ bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, - uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason) + uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason) { uint8_t const *attr, *end; size_t totallen; bool seen_ma = false; uint32_t num_attributes; - decode_fail_t failure = DECODE_FAIL_NONE; + fr_radius_decode_fail_t failure = DECODE_FAIL_NONE; size_t packet_len = *packet_len_p; /* diff --git a/src/protocols/radius/bio.c b/src/protocols/radius/bio.c index 4fcfc3e03d0..0e639eae56f 100644 --- a/src/protocols/radius/bio.c +++ b/src/protocols/radius/bio.c @@ -31,16 +31,22 @@ RCSID("$Id$") */ fr_bio_verify_action_t fr_radius_bio_verify(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size) { - decode_fail_t failure; + fr_radius_decode_fail_t failure; size_t in_buffer = *size; fr_radius_bio_verify_t *uctx = verify_ctx; uint8_t const *hdr = data; + size_t want; if (in_buffer < 4) { *size = RADIUS_HEADER_LENGTH; return FR_BIO_VERIFY_WANT_MORE; } + want = fr_nbo_to_uint16(hdr + 2); + if (uctx->max_packet_size && (want > uctx->max_packet_size)) { + return FR_BIO_VERIFY_ERROR_CLOSE; + } + /* * See if we need to discard the packet. */ @@ -63,13 +69,19 @@ fr_bio_verify_action_t fr_radius_bio_verify(UNUSED fr_bio_t *bio, void *verify_c */ fr_bio_verify_action_t fr_radius_bio_verify_datagram(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size) { - decode_fail_t failure; + fr_radius_decode_fail_t failure; size_t in_buffer = *size; fr_radius_bio_verify_t *uctx = verify_ctx; uint8_t const *hdr = data; + size_t want; if (in_buffer < RADIUS_HEADER_LENGTH) return FR_BIO_VERIFY_DISCARD; + want = fr_nbo_to_uint16(hdr + 2); + if (uctx->max_packet_size && (want > uctx->max_packet_size)) { + return FR_BIO_VERIFY_ERROR_DISCARD; + } + /* * See if we need to discard the packet. * diff --git a/src/protocols/radius/bio.h b/src/protocols/radius/bio.h index 152fcf552ae..533367fae01 100644 --- a/src/protocols/radius/bio.h +++ b/src/protocols/radius/bio.h @@ -35,6 +35,7 @@ typedef struct { size_t secret_len; uint32_t max_attributes; + uint32_t max_packet_size; bool allowed[FR_RADIUS_CODE_MAX]; //!< allowed outgoing packet types diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index d3a35d64965..57721f9365d 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -2165,6 +2165,7 @@ static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const * static const char *reason_name[DECODE_FAIL_MAX] = { [ DECODE_FAIL_NONE ] = "all OK", [ DECODE_FAIL_MIN_LENGTH_PACKET ] = "packet is too small", + [ DECODE_FAIL_MAX_LENGTH_PACKET ] = "packet is too large", [ DECODE_FAIL_MIN_LENGTH_FIELD ] = "length field is too small", [ DECODE_FAIL_MIN_LENGTH_MISMATCH ] = "length mismatch", [ DECODE_FAIL_HEADER_OVERFLOW ] = "header overflow", @@ -2184,7 +2185,7 @@ static ssize_t fr_radius_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx) { fr_radius_decode_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_radius_decode_ctx_t); - decode_fail_t reason; + fr_radius_decode_fail_t reason; fr_pair_t *vp; size_t packet_len = data_len; diff --git a/src/protocols/radius/packet.c b/src/protocols/radius/packet.c index 5d69f394d3e..36f4157935c 100644 --- a/src/protocols/radius/packet.c +++ b/src/protocols/radius/packet.c @@ -116,7 +116,7 @@ ssize_t fr_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, * - True on success. * - False on failure. */ -bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason) +bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason) { char host_ipaddr[INET6_ADDRSTRLEN]; diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 3ece3aed65b..e019f9c9c06 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -158,6 +158,28 @@ typedef struct { fr_radius_attr_flags_encrypt_t encrypt; //!< Attribute is encrypted } fr_radius_attr_flags_t; +/** Failure reasons */ +typedef enum { + DECODE_FAIL_NONE = 0, + DECODE_FAIL_MIN_LENGTH_PACKET, + DECODE_FAIL_MAX_LENGTH_PACKET, + DECODE_FAIL_MIN_LENGTH_FIELD, + DECODE_FAIL_MIN_LENGTH_MISMATCH, + DECODE_FAIL_HEADER_OVERFLOW, + DECODE_FAIL_UNKNOWN_PACKET_CODE, + DECODE_FAIL_INVALID_ATTRIBUTE, + DECODE_FAIL_ATTRIBUTE_TOO_SHORT, + DECODE_FAIL_ATTRIBUTE_OVERFLOW, + DECODE_FAIL_MA_INVALID_LENGTH, + DECODE_FAIL_ATTRIBUTE_UNDERFLOW, + DECODE_FAIL_TOO_MANY_ATTRIBUTES, + DECODE_FAIL_MA_MISSING, + DECODE_FAIL_MA_INVALID, + DECODE_FAIL_UNKNOWN, + DECODE_FAIL_MAX +} fr_radius_decode_fail_t; + + DIAG_OFF(unused-function) /** Return RADIUS-specific flags for a given attribute */ @@ -205,7 +227,7 @@ int fr_radius_verify(uint8_t *packet, uint8_t const *vector, bool require_message_authenticator, bool limit_proxy_state) CC_HINT(nonnull (1,3)); bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, - uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason) CC_HINT(nonnull (1,2)); + uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason) CC_HINT(nonnull (1,2)); ssize_t fr_radius_ascend_secret(fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, uint8_t const *vector); @@ -234,7 +256,7 @@ ssize_t fr_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, char const *secret) CC_HINT(nonnull (1,2,4)); bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, - decode_fail_t *reason) CC_HINT(nonnull (1)); + fr_radius_decode_fail_t *reason) CC_HINT(nonnull (1)); int fr_packet_verify(fr_packet_t *packet, fr_packet_t *original, char const *secret) CC_HINT(nonnull (1,3));