From: Arran Cudbard-Bell Date: Wed, 6 Jan 2021 17:42:48 +0000 (+0000) Subject: Pass list headers (separate from packets) into radius encoding/decoding functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f803edb1b683f3c697b04d99424f3cdfd859b46;p=thirdparty%2Ffreeradius-server.git Pass list headers (separate from packets) into radius encoding/decoding functions This is with a view of removing packet->vps, and moving it to request_t, after which we can maybe merge all the list heads under a single root. --- diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 6aeef16ddd8..0eaf67ea022 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -192,7 +192,7 @@ static int _rc_request_free(rc_request_t *request) return 0; } -static int mschapv1_encode(fr_radius_packet_t *packet, fr_pair_list_t *request, +static int mschapv1_encode(fr_radius_packet_t *packet, fr_pair_list_t *list, char const *password) { unsigned int i; @@ -205,7 +205,7 @@ static int mschapv1_encode(fr_radius_packet_t *packet, fr_pair_list_t *request, MEM(challenge = fr_pair_afrom_da(packet, attr_ms_chap_challenge)); - fr_pair_add(request, challenge); + fr_pair_add(list, challenge); challenge->vp_length = 8; challenge->vp_octets = p = talloc_array(challenge, uint8_t, challenge->vp_length); for (i = 0; i < challenge->vp_length; i++) { @@ -213,7 +213,7 @@ static int mschapv1_encode(fr_radius_packet_t *packet, fr_pair_list_t *request, } MEM(reply = fr_pair_afrom_da(packet, attr_ms_chap_response)); - fr_pair_add(request, reply); + fr_pair_add(list, reply); reply->vp_length = 50; reply->vp_octets = p = talloc_array(reply, uint8_t, reply->vp_length); memset(p, 0, reply->vp_length); @@ -939,7 +939,7 @@ static int send_one_packet(rc_request_t *request) /* * Send the packet. */ - if (fr_radius_packet_send(request->packet, NULL, secret) < 0) { + if (fr_radius_packet_send(request->packet, &request->request_pairs, NULL, secret) < 0) { REDEBUG("Failed to send packet for ID %d", request->packet->id); deallocate_id(request); request->done = true; @@ -1043,7 +1043,8 @@ static int recv_one_packet(fr_time_t wait_time) /* * If this fails, we're out of memory. */ - if (fr_radius_packet_decode(request->reply, request->packet, RADIUS_MAX_ATTRIBUTES, false, secret) != 0) { + if (fr_radius_packet_decode(request->reply, &request->reply_pairs, + request->packet, RADIUS_MAX_ATTRIBUTES, false, secret) != 0) { REDEBUG("Reply decode failed"); stats.lost++; goto packet_done; diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index a9bb91a28c1..e96b8a2e76f 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -1408,7 +1408,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt FILE *log_fp = fr_log_fp; fr_log_fp = NULL; - ret = fr_radius_packet_decode(packet, original ? original->expect : NULL, + ret = fr_radius_packet_decode(packet, &packet->vps, original ? original->expect : NULL, RADIUS_MAX_ATTRIBUTES, false, conf->radius_secret); fr_log_fp = log_fp; if (ret != 0) { @@ -1541,7 +1541,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt FILE *log_fp = fr_log_fp; fr_log_fp = NULL; - ret = fr_radius_packet_decode(packet, NULL, + ret = fr_radius_packet_decode(packet, &packet->vps, NULL, RADIUS_MAX_ATTRIBUTES, false, conf->radius_secret); fr_log_fp = log_fp; diff --git a/src/bin/radsnmp.c b/src/bin/radsnmp.c index aac98f3feb8..6d12eb904fe 100644 --- a/src/bin/radsnmp.c +++ b/src/bin/radsnmp.c @@ -766,14 +766,14 @@ static int radsnmp_send_recv(radsnmp_conf_t *conf, int fd) */ { fr_radius_packet_t *reply = NULL; - ssize_t rcode; + ssize_t rcode; - fd_set set; + fd_set set; - unsigned int ret; - unsigned int i; + unsigned int ret; + unsigned int i; - if (fr_radius_packet_encode(packet, NULL, conf->secret) < 0) { + if (fr_radius_packet_encode(packet, &packet->vps, NULL, conf->secret) < 0) { fr_perror("Failed encoding packet"); return EXIT_FAILURE; } @@ -822,7 +822,7 @@ static int radsnmp_send_recv(radsnmp_conf_t *conf, int fd) talloc_free(packet); continue; } - if (fr_radius_packet_decode(reply, packet, + if (fr_radius_packet_decode(reply, &reply->vps, packet, RADIUS_MAX_ATTRIBUTES, false, conf->secret) < 0) { fr_perror("Failed decoding reply"); goto recv_error; diff --git a/src/protocols/radius/packet.c b/src/protocols/radius/packet.c index ef400ecf6c4..42202c91f61 100644 --- a/src/protocols/radius/packet.c +++ b/src/protocols/radius/packet.c @@ -51,7 +51,8 @@ typedef struct { /** Encode a packet * */ -ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_radius_packet_t const *original, char const *secret) +ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t const *original, char const *secret) { uint8_t const *original_data; ssize_t slen; @@ -77,7 +78,7 @@ ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_radius_packet_t c memcpy(data + 4, packet->vector, sizeof(packet->vector)); slen = fr_radius_encode(data, sizeof(data), original_data, secret, talloc_array_length(secret) - 1, - packet->code, packet->id, &packet->vps); + packet->code, packet->id, list); if (slen < 0) return slen; /* @@ -100,14 +101,22 @@ ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_radius_packet_t c return 0; } - /** Calculate/check digest, and decode radius attributes * + * @param[in] packet to decode. + * @param[in] list to add pairs to. + * @param[in] original packet, if this is a reply. + * @param[in] max_attributes to decode. + * @param[in] tunnel_password_zeros set random elements of the tunnel password + * vectors to zero to aid in testing. + * @param[in] secret shared secret used for decoding encrypted + * password attributes. * @return * - 0 on success * - -1 on decoding error. */ -int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_radius_packet_t *original, +int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t *original, uint32_t max_attributes, bool tunnel_password_zeros, char const *secret) { int packet_length; @@ -225,7 +234,7 @@ int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_radius_packet_t *orig talloc_free_children(packet_ctx.tmp_ctx); } - fr_cursor_init(&out, &packet->vps); + fr_cursor_init(&out, list); fr_cursor_tail(&out); /* Move insertion point to the end of the list */ fr_cursor_head(&cursor); fr_cursor_merge(&out, &cursor); @@ -455,8 +464,8 @@ fr_radius_packet_t *fr_radius_packet_recv(TALLOC_CTX *ctx, int fd, int flags, ui * * Also attach reply attribute value pairs and any user message provided. */ -int fr_radius_packet_send(fr_radius_packet_t *packet, fr_radius_packet_t const *original, - char const *secret) +int fr_radius_packet_send(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t const *original, char const *secret) { /* * Maybe it's a fake packet. Don't send it. @@ -472,7 +481,7 @@ int fr_radius_packet_send(fr_radius_packet_t *packet, fr_radius_packet_t const * /* * Encode the packet. */ - if (fr_radius_packet_encode(packet, original, secret) < 0) { + if (fr_radius_packet_encode(packet, list, original, secret) < 0) { return -1; } diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 2de7401d39b..85c7528653d 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -139,11 +139,13 @@ void fr_radius_free(void); /* * protocols/radius/packet.c */ -ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_radius_packet_t const *original, - char const *secret) CC_HINT(nonnull (1,3)); -int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_radius_packet_t *original, +ssize_t fr_radius_packet_encode(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t const *original, + char const *secret) CC_HINT(nonnull (1,2,4)); +int fr_radius_packet_decode(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t *original, uint32_t max_attributes, bool tunnel_password_zeros, - char const *secret) CC_HINT(nonnull (1,5)); + char const *secret) CC_HINT(nonnull (1,2,6)); bool fr_radius_packet_ok(fr_radius_packet_t *packet, uint32_t max_attributes, bool require_ma, decode_fail_t *reason) CC_HINT(nonnull (1)); @@ -154,8 +156,8 @@ int fr_radius_packet_sign(fr_radius_packet_t *packet, fr_radius_packet_t const char const *secret) CC_HINT(nonnull (1,3)); fr_radius_packet_t *fr_radius_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_ma); -int fr_radius_packet_send(fr_radius_packet_t *packet, fr_radius_packet_t const *original, - char const *secret) CC_HINT(nonnull (1,3)); +int fr_radius_packet_send(fr_radius_packet_t *packet, fr_pair_list_t *list, + fr_radius_packet_t const *original, char const *secret) CC_HINT(nonnull (1,2,4)); #define fr_radius_packet_log_hex(_log, _packet) _fr_radius_packet_log_hex(_log, _packet, __FILE__, __LINE__); void _fr_radius_packet_log_hex(fr_log_t const *log, fr_radius_packet_t const *packet, char const *file, int line) CC_HINT(nonnull);