From: Alan T. DeKok Date: Tue, 2 May 2017 20:11:28 +0000 (-0400) Subject: More cleanups. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98ad2ca0634cf4489a0cfb6db8d9cdbbe504251a;p=thirdparty%2Ffreeradius-server.git More cleanups. fr_radius_recv() -> fr_radius_packet_recv() Move more functions out of radius.c to radius_packet.c --- diff --git a/src/include/libradius.h b/src/include/libradius.h index fd46519bb41..a49889fe28a 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -212,33 +212,48 @@ do { \ #define FR_TUNNEL_PW_ENC_LENGTH(_x) (2 + 1 + _x + PAD(_x + 1, 16)) extern FR_NAME_NUMBER const fr_request_types[]; -void fr_radius_ascend_secret(uint8_t *digest, uint8_t const *vector, char const *secret, uint8_t const *value); +int fr_radius_sign(uint8_t *packet, uint8_t const *original, + uint8_t const *secret, size_t secret_len) CC_HINT(nonnull (1,3)); +int fr_radius_verify(uint8_t *packet, uint8_t const *original, + uint8_t const *secret, size_t secret_len) CC_HINT(nonnull (1,3)); +bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, bool require_ma, + decode_fail_t *reason) CC_HINT(nonnull (1,2)); -void fr_radius_print_hex(RADIUS_PACKET const *packet); - -int fr_radius_packet_send(RADIUS_PACKET *, RADIUS_PACKET const *, char const *secret); - -bool fr_radius_packet_ok(RADIUS_PACKET *packet, bool require_ma, decode_fail_t *reason); - -RADIUS_PACKET *fr_radius_recv(TALLOC_CTX *ctx, int fd, int flags, bool require_ma); +void fr_radius_ascend_secret(uint8_t *digest, uint8_t const *vector, + char const *secret, uint8_t const *value) CC_HINT(nonnull); ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code); -int fr_radius_packet_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret); - -int fr_radius_packet_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret); - -int fr_radius_packet_encode(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret); - -int fr_radius_packet_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret); - int fr_digest_cmp(uint8_t const *a, uint8_t const *b, size_t length); +/* + * radius_packet.c + */ RADIUS_PACKET *fr_radius_alloc(TALLOC_CTX *ctx, bool new_vector); RADIUS_PACKET *fr_radius_alloc_reply(TALLOC_CTX *ctx, RADIUS_PACKET *); RADIUS_PACKET *fr_radius_copy(TALLOC_CTX *ctx, RADIUS_PACKET const *in); void fr_radius_free(RADIUS_PACKET **); +int fr_radius_packet_encode(RADIUS_PACKET *packet, RADIUS_PACKET const *original, + char const *secret) CC_HINT(nonnull (1,3)); +int fr_radius_packet_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, + char const *secret) CC_HINT(nonnull (1,3)); + +bool fr_radius_packet_ok(RADIUS_PACKET *packet, bool require_ma, + decode_fail_t *reason) CC_HINT(nonnull (1)); + +int fr_radius_packet_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, + char const *secret) CC_HINT(nonnull (1,3)); +int fr_radius_packet_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, + char const *secret) CC_HINT(nonnull (1,3)); + +RADIUS_PACKET *fr_radius_packet_recv(TALLOC_CTX *ctx, int fd, int flags, bool require_ma); +int fr_radius_packet_send(RADIUS_PACKET *packet, RADIUS_PACKET const *original, + char const *secret) CC_HINT(nonnull (1,3)); + +void fr_radius_print_hex(RADIUS_PACKET const *packet) CC_HINT(nonnull); + + typedef struct fr_radius_ctx { RADIUS_PACKET const *packet; RADIUS_PACKET const *original; diff --git a/src/lib/util/packet.c b/src/lib/util/packet.c index 269a36ec1ba..4b9da372cc9 100644 --- a/src/lib/util/packet.c +++ b/src/lib/util/packet.c @@ -914,7 +914,7 @@ RADIUS_PACKET *fr_packet_list_recv(fr_packet_list_t *pl, fd_set *set) packet = fr_tcp_recv(pl->sockets[start].sockfd, false); } else #endif - packet = fr_radius_recv(NULL, pl->sockets[start].sockfd, UDP_FLAGS_NONE, false); + packet = fr_radius_packet_recv(NULL, pl->sockets[start].sockfd, UDP_FLAGS_NONE, false); if (!packet) continue; /* diff --git a/src/lib/util/radius.c b/src/lib/util/radius.c index bb69a03ce9c..96344255d55 100644 --- a/src/lib/util/radius.c +++ b/src/lib/util/radius.c @@ -225,8 +225,8 @@ invalid: * - <0 on error * - 0 on success */ -static int fr_radius_sign(uint8_t *packet, uint8_t const *original, - uint8_t const *secret, size_t secret_len) +int fr_radius_sign(uint8_t *packet, uint8_t const *original, + uint8_t const *secret, size_t secret_len) { uint8_t *msg, *end; size_t packet_len = (packet[2] << 8) | packet[3]; @@ -362,38 +362,6 @@ static int fr_radius_sign(uint8_t *packet, uint8_t const *original, return 0; } -/** Sign a previously encoded packet - * - */ -int fr_radius_packet_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, - char const *secret) -{ - int rcode; - uint8_t const *original_data; - - if (original) { - original_data = original->data; - } else { - original_data = NULL; - } - - /* - * Copy the random vector to the packet. Other packet - * codes have the Request Authenticator be the packet - * signature. - */ - if ((packet->code == PW_CODE_ACCESS_REQUEST) || - (packet->code == PW_CODE_STATUS_SERVER)) { - memcpy(packet->data + 4, packet->vector, sizeof(packet->vector)); - } - - rcode = fr_radius_sign(packet->data, original_data, - (uint8_t const *) secret, talloc_array_length(secret) - 1); - if (rcode < 0) return rcode; - - memcpy(packet->vector, packet->data + 4, AUTH_VECTOR_LEN); - return 0; -} /** Do a comparison of two authentication digests by comparing the FULL digest * @@ -425,7 +393,7 @@ int fr_digest_cmp(uint8_t const *a, uint8_t const *b, size_t length) * - True on success. * - False on failure. */ -static bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, bool require_ma, decode_fail_t *reason) +bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, bool require_ma, decode_fail_t *reason) { uint8_t const *attr, *end; size_t totallen; @@ -678,41 +646,6 @@ finish: } -/** See if the data pointed to by PTR is a valid RADIUS packet. - * - * Packet is not 'const * const' because we may update data_len, if there's more data - * in the UDP packet than in the RADIUS packet. - * - * @param packet to check - * @param require_ma to require Message-Authenticator - * @param reason if not NULL, will have the failure reason written to where it points. - * @return - * - True on success. - * - False on failure. - */ -bool fr_radius_packet_ok(RADIUS_PACKET *packet, bool require_ma, decode_fail_t *reason) -{ - char host_ipaddr[INET6_ADDRSTRLEN]; - - if (!fr_radius_ok(packet->data, &packet->data_len, require_ma, reason)) { - FR_DEBUG_STRERROR_PRINTF("Bad packet received from host %s - %s", - inet_ntop(packet->src_ipaddr.af, - &packet->src_ipaddr.ipaddr, - host_ipaddr, sizeof(host_ipaddr)), - fr_strerror()); - return false; - } - - /* - * Fill RADIUS header fields - */ - packet->code = packet->data[0]; - packet->id = packet->data[1]; - memcpy(packet->vector, packet->data + 4, sizeof(packet->vector)); - return true; -} - - /** Verify a request / response packet * * This function does its work by calling fr_radius_sign(), and then @@ -727,8 +660,8 @@ bool fr_radius_packet_ok(RADIUS_PACKET *packet, bool require_ma, decode_fail_t * * - <0 on error * - 0 on success */ -static int fr_radius_verify(uint8_t *packet, uint8_t const *original, - uint8_t const *secret, size_t secret_len) +int fr_radius_verify(uint8_t *packet, uint8_t const *original, + uint8_t const *secret, size_t secret_len) { int rcode; uint8_t *msg, *end; @@ -828,33 +761,3 @@ static int fr_radius_verify(uint8_t *packet, uint8_t const *original, return 0; } - - -/** Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet - * - */ -int fr_radius_packet_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret) -{ - uint8_t const *original_data; - char buffer[INET6_ADDRSTRLEN]; - - if (!packet || !packet->data) return -1; - - if (original) { - original_data = original->data; - } else { - original_data = NULL; - } - - if (fr_radius_verify(packet->data, original_data, - (uint8_t const *) secret, talloc_array_length(secret) - 1) < 0) { - fr_strerror_printf("Received packet from %s with %s", - inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, - buffer, sizeof(buffer)), - fr_strerror()); - return -1; - } - - return 0; -} - diff --git a/src/lib/util/radius_packet.c b/src/lib/util/radius_packet.c index 52edc7786bc..0e1278a6481 100644 --- a/src/lib/util/radius_packet.c +++ b/src/lib/util/radius_packet.c @@ -452,6 +452,104 @@ int fr_radius_packet_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, char } +/** See if the data pointed to by PTR is a valid RADIUS packet. + * + * Packet is not 'const * const' because we may update data_len, if there's more data + * in the UDP packet than in the RADIUS packet. + * + * @param packet to check + * @param require_ma to require Message-Authenticator + * @param reason if not NULL, will have the failure reason written to where it points. + * @return + * - True on success. + * - False on failure. + */ +bool fr_radius_packet_ok(RADIUS_PACKET *packet, bool require_ma, decode_fail_t *reason) +{ + char host_ipaddr[INET6_ADDRSTRLEN]; + + if (!fr_radius_ok(packet->data, &packet->data_len, require_ma, reason)) { + FR_DEBUG_STRERROR_PRINTF("Bad packet received from host %s - %s", + inet_ntop(packet->src_ipaddr.af, + &packet->src_ipaddr.ipaddr, + host_ipaddr, sizeof(host_ipaddr)), + fr_strerror()); + return false; + } + + /* + * Fill RADIUS header fields + */ + packet->code = packet->data[0]; + packet->id = packet->data[1]; + memcpy(packet->vector, packet->data + 4, sizeof(packet->vector)); + return true; +} + + +/** Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet + * + */ +int fr_radius_packet_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret) +{ + uint8_t const *original_data; + char buffer[INET6_ADDRSTRLEN]; + + if (!packet->data) return -1; + + if (original) { + original_data = original->data; + } else { + original_data = NULL; + } + + if (fr_radius_verify(packet->data, original_data, + (uint8_t const *) secret, talloc_array_length(secret) - 1) < 0) { + fr_strerror_printf("Received packet from %s with %s", + inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, + buffer, sizeof(buffer)), + fr_strerror()); + return -1; + } + + return 0; +} + + +/** Sign a previously encoded packet + * + */ +int fr_radius_packet_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, + char const *secret) +{ + int rcode; + uint8_t const *original_data; + + if (original) { + original_data = original->data; + } else { + original_data = NULL; + } + + /* + * Copy the random vector to the packet. Other packet + * codes have the Request Authenticator be the packet + * signature. + */ + if ((packet->code == PW_CODE_ACCESS_REQUEST) || + (packet->code == PW_CODE_STATUS_SERVER)) { + memcpy(packet->data + 4, packet->vector, sizeof(packet->vector)); + } + + rcode = fr_radius_sign(packet->data, original_data, + (uint8_t const *) secret, talloc_array_length(secret) - 1); + if (rcode < 0) return rcode; + + memcpy(packet->vector, packet->data + 4, AUTH_VECTOR_LEN); + return 0; +} + + /** Wrapper for recvfrom, which handles recvfromto, IPv6, and all possible combinations * */ @@ -482,7 +580,7 @@ static ssize_t rad_recvfrom(int sockfd, RADIUS_PACKET *packet, int flags) /** Receive UDP client requests, and fill in the basics of a RADIUS_PACKET structure * */ -RADIUS_PACKET *fr_radius_recv(TALLOC_CTX *ctx, int fd, int flags, bool require_ma) +RADIUS_PACKET *fr_radius_packet_recv(TALLOC_CTX *ctx, int fd, int flags, bool require_ma) { ssize_t data_len; RADIUS_PACKET *packet; @@ -578,12 +676,12 @@ RADIUS_PACKET *fr_radius_recv(TALLOC_CTX *ctx, int fd, int flags, bool require_m * Also attach reply attribute value pairs and any user message provided. */ int fr_radius_packet_send(RADIUS_PACKET *packet, RADIUS_PACKET const *original, - char const *secret) + char const *secret) { /* * Maybe it's a fake packet. Don't send it. */ - if (!packet || (packet->sockfd < 0)) { + if (packet->sockfd < 0) { return 0; } diff --git a/src/main/listen.c b/src/main/listen.c index 4567bf5b7dd..f4f59007be5 100644 --- a/src/main/listen.c +++ b/src/main/listen.c @@ -512,7 +512,7 @@ RADCLIENT *client_listener_find(rad_listen_t *listener, request->listener = listener; request->client = client; - request->packet = fr_radius_recv(NULL, listener->fd, UDP_FLAGS_PEEK, false); + request->packet = fr_radius_packet_recv(NULL, listener->fd, UDP_FLAGS_PEEK, false); if (!request->packet) { /* badly formed, etc */ talloc_free(request); if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); @@ -1781,7 +1781,7 @@ static int stats_socket_recv(rad_listen_t *listener) * Now that we've sanity checked everything, receive the * packet. */ - packet = fr_radius_recv(NULL, listener->fd, UDP_FLAGS_NONE, true); /* require message authenticator */ + packet = fr_radius_packet_recv(NULL, listener->fd, UDP_FLAGS_NONE, true); /* require message authenticator */ if (!packet) { FR_STATS_INC(auth, total_malformed_requests); if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); @@ -1875,7 +1875,7 @@ static int auth_socket_recv(rad_listen_t *listener) * Now that we've sanity checked everything, receive the * packet. */ - packet = fr_radius_recv(ctx, listener->fd, UDP_FLAGS_NONE, client->message_authenticator); + packet = fr_radius_packet_recv(ctx, listener->fd, UDP_FLAGS_NONE, client->message_authenticator); if (!packet) { FR_STATS_INC(auth, total_malformed_requests); if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); @@ -1892,7 +1892,7 @@ static int auth_socket_recv(rad_listen_t *listener) * * This hack works ONLY if the clients are global. If * each listener has the same client IP, but with - * different secrets, then it will fail the fr_radius_recv() + * different secrets, then it will fail the fr_radius_packet_recv() * check above, and there's nothing you can do. */ { @@ -1990,7 +1990,7 @@ static int acct_socket_recv(rad_listen_t *listener) * Now that we've sanity checked everything, receive the * packet. */ - packet = fr_radius_recv(ctx, listener->fd, UDP_FLAGS_NONE, false); + packet = fr_radius_packet_recv(ctx, listener->fd, UDP_FLAGS_NONE, false); if (!packet) { FR_STATS_INC(acct, total_malformed_requests); if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); @@ -2267,7 +2267,7 @@ static int coa_socket_recv(rad_listen_t *listener) * Now that we've sanity checked everything, receive the * packet. */ - packet = fr_radius_recv(ctx, listener->fd, UDP_FLAGS_NONE, client->message_authenticator); + packet = fr_radius_packet_recv(ctx, listener->fd, UDP_FLAGS_NONE, client->message_authenticator); if (!packet) { FR_STATS_INC(coa, total_malformed_requests); if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); @@ -2298,7 +2298,7 @@ static int proxy_socket_recv(rad_listen_t *listener) # endif char buffer[128]; - packet = fr_radius_recv(NULL, listener->fd, UDP_FLAGS_NONE, false); + packet = fr_radius_packet_recv(NULL, listener->fd, UDP_FLAGS_NONE, false); if (!packet) { if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror()); return 0; diff --git a/src/main/radsnmp.c b/src/main/radsnmp.c index 727af6ae81d..befd09b8a55 100644 --- a/src/main/radsnmp.c +++ b/src/main/radsnmp.c @@ -799,7 +799,7 @@ static int radsnmp_send_recv(radsnmp_conf_t *conf, int fd) continue; /* Timeout */ case 1: - reply = fr_radius_recv(request, request->sockfd, UDP_FLAGS_NONE, false); + reply = fr_radius_packet_recv(request, request->sockfd, UDP_FLAGS_NONE, false); if (!reply) { ERROR("Failed receiving reply: %s", fr_strerror()); recv_error: diff --git a/src/main/tls_listen.c b/src/main/tls_listen.c index e32a685b42c..408d322fa8b 100644 --- a/src/main/tls_listen.c +++ b/src/main/tls_listen.c @@ -261,7 +261,7 @@ static int tls_socket_recv(rad_listen_t *listener) } /* - * Copied from src/lib/radius.c, fr_radius_recv(); + * Copied from src/lib/radius.c, fr_radius_packet_recv(); */ if (fr_debug_lvl) { char host_ipaddr[INET6_ADDRSTRLEN]; diff --git a/src/modules/proto_radius/proto_radius_acct.c b/src/modules/proto_radius/proto_radius_acct.c index d8758b62558..7e2f10d8242 100644 --- a/src/modules/proto_radius/proto_radius_acct.c +++ b/src/modules/proto_radius/proto_radius_acct.c @@ -288,7 +288,7 @@ static int acct_socket_recv(rad_listen_t *listener) } talloc_set_name_const(ctx, "acct_listener_pool"); - packet = fr_radius_recv(ctx, listener->fd, 0, false); + packet = fr_radius_packet_recv(ctx, listener->fd, 0, false); if (!packet) { ERROR("%s", fr_strerror()); talloc_free(ctx); diff --git a/src/modules/proto_radius/proto_radius_auth.c b/src/modules/proto_radius/proto_radius_auth.c index 09dff876fcf..2e325eb316f 100644 --- a/src/modules/proto_radius/proto_radius_auth.c +++ b/src/modules/proto_radius/proto_radius_auth.c @@ -927,7 +927,7 @@ static int auth_socket_recv(rad_listen_t *listener) } talloc_set_name_const(ctx, "auth_listener_pool"); - packet = fr_radius_recv(ctx, listener->fd, 0, false); + packet = fr_radius_packet_recv(ctx, listener->fd, 0, false); if (!packet) { ERROR("%s", fr_strerror()); talloc_free(ctx); diff --git a/src/modules/proto_radius/proto_radius_coa.c b/src/modules/proto_radius/proto_radius_coa.c index e59d393bf88..ec2c86e701f 100644 --- a/src/modules/proto_radius/proto_radius_coa.c +++ b/src/modules/proto_radius/proto_radius_coa.c @@ -333,7 +333,7 @@ static int coa_socket_recv(rad_listen_t *listener) } talloc_set_name_const(ctx, "coa_listener_pool"); - packet = fr_radius_recv(ctx, listener->fd, 0, false); + packet = fr_radius_packet_recv(ctx, listener->fd, 0, false); if (!packet) { ERROR("%s", fr_strerror()); talloc_free(ctx); diff --git a/src/modules/proto_radius/proto_radius_status.c b/src/modules/proto_radius/proto_radius_status.c index 1a60d1db730..654fc52f33e 100644 --- a/src/modules/proto_radius/proto_radius_status.c +++ b/src/modules/proto_radius/proto_radius_status.c @@ -294,7 +294,7 @@ static int status_socket_recv(rad_listen_t *listener) } talloc_set_name_const(ctx, "status_listener_pool"); - packet = fr_radius_recv(ctx, listener->fd, 0, false); + packet = fr_radius_packet_recv(ctx, listener->fd, 0, false); if (!packet) { ERROR("%s", fr_strerror()); talloc_free(ctx); diff --git a/src/modules/rlm_eap/eap.c b/src/modules/rlm_eap/eap.c index e7db25666bb..ccc3bdd4c2d 100644 --- a/src/modules/rlm_eap/eap.c +++ b/src/modules/rlm_eap/eap.c @@ -253,7 +253,7 @@ int eap_start(rlm_eap_t const *inst, REQUEST *request) /* * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message * - * Checks for Message-Authenticator are handled by fr_radius_recv(). + * Checks for Message-Authenticator are handled by fr_radius_packet_recv(). */ /* diff --git a/src/modules/rlm_radius_client/rlm_radius_client.c b/src/modules/rlm_radius_client/rlm_radius_client.c index 55fe9a205ba..54939e4299d 100644 --- a/src/modules/rlm_radius_client/rlm_radius_client.c +++ b/src/modules/rlm_radius_client/rlm_radius_client.c @@ -117,7 +117,7 @@ static void mod_event_fd(UNUSED fr_event_list_t *el, int fd, void *ctx) * @fixme: if there's an error in the socket, remove the * socket from the packet list. */ - reply = fr_radius_recv(conn, fd, 0, false); + reply = fr_radius_packet_recv(conn, fd, 0, false); if (!reply) { return; }