#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;
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;
/*
* - <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];
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
*
* - 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;
}
-/** 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
* - <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;
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;
-}
-
}
+/** 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
*
*/
/** 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;
* 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;
}
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());
* 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());
* 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());
*
* 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.
*/
{
* 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());
* 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());
# 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;
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:
}
/*
- * 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];
}
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);
}
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);
}
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);
}
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);
/*
* 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().
*/
/*
* @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;
}