25RCSID(
"$Id: 6ebec053ab9104cf697347a3b55da5263703141b $")
29#include <freeradius-devel/util/udp.h>
30#include <freeradius-devel/util/syserror.h>
37#define FR_DEBUG_STRERROR_PRINTF if (fr_debug_lvl) fr_strerror_printf
64 .request_authenticator = original ? original->
data + 4 : NULL,
69 .request_code = original ? original->
data[0] : 0,
74#if defined(__clang_analyzer__) || defined(__COVERITY__)
83 if (slen < 0)
return slen;
124 if (!
fr_radius_ok(packet->
data, &
len, max_attributes, require_message_authenticator, reason)) {
134 packet->
id = packet->
data[1];
145 char buffer[INET6_ADDRSTRLEN];
147 if (!packet->
data)
return -1;
171 if (ret < 0)
return ret;
187 if ((errno == EAGAIN) || (errno == EINTR))
return 0;
191 if (data_len == 0)
return -1;
193 packet->
data = talloc_array(packet,
uint8_t, data_len);
194 if (!packet->
data)
return -1;
226#ifdef WITH_VERIFY_PTR
230 if ((packet->
socket.inet.src_ipaddr.
af == AF_UNSPEC) ||
231 (packet->
socket.inet.src_port == 0) ||
232 (packet->
socket.inet.dst_ipaddr.
af == AF_UNSPEC) ||
233 (packet->
socket.inet.dst_port == 0)) {
338 if (ret >= 0)
return ret;
358 if (!packet->
data)
return;
363 if ((packet->
socket.inet.src_ipaddr.
af == AF_INET) || (packet->
socket.inet.src_ipaddr.
af == AF_INET6)) {
385 int i,
len, offset = 2;
386 unsigned int vendor = 0;
388 char const *truncated =
"";
393 if (attr[1] < 2)
break;
397 if ((attr[0] == FR_VENDOR_SPECIFIC) &&
402 attr[2], attr[3], attr[4], attr[5], vendor);
407 len = attr[1] - offset;
413 for (i = 0; i <
len; i++) {
429 char const *via_prefix =
"";
430 char const *via_ifname =
"";
431 char const *via_suffix =
"";
432#ifdef WITH_IFINDEX_NAME_RESOLUTION
433 char if_name[IFNAMSIZ];
439#ifdef WITH_IFINDEX_NAME_RESOLUTION
442 via_ifname = fr_ifname_from_ifindex(if_name, packet->
socket.inet.ifindex);
455 "%s %s Id %i from %s%s%s:%i to %s%s%s:%i "
456 "%s%s%slength %zu\n",
457 received ?
"Received" :
"Sent",
460 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
462 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
463 packet->
socket.inet.src_port,
464 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
466 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
467 packet->
socket.inet.dst_port,
468 via_prefix, via_ifname, via_suffix,
472 "%s code %u Id %i from %s%s%s:%i to %s%s%s:%i "
473 "%s%s%slength %zu\n",
474 received ?
"Received" :
"Sent",
477 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
479 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
480 packet->
socket.inet.src_port,
481 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
483 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
484 packet->
socket.inet.dst_port,
485 via_prefix, via_ifname, via_suffix,
503 if (!received)
switch (packet->
code) {
507 fr_log(log,
L_DBG, __FILE__, __LINE__,
"\tMessage-Authenticator = 0x\n");
static int const char char buffer[256]
static int packet_ctx
the tests pass only the address of packet_ctx
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_RADIUS_CODE_STATUS_SERVER
RFC2865/RFC5997 - Status Server (request)
char * fr_inet_ntop(char out[static FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print the address portion of a fr_ipaddr_t.
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
#define fr_log(_log, _lvl, _file, _line, _fmt,...)
@ L_DBG_LVL_4
4th highest priority debug messages (-xxxx | -Xxx).
@ L_DBG
Only displayed when debugging is enabled.
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
void fr_packet_free(fr_packet_t **packet_p)
Free a fr_packet_t.
ssize_t udp_send(fr_socket_t const *sock, int flags, void *data, size_t data_len)
Send a packet via a UDP socket.
ssize_t udp_recv(int sockfd, int flags, fr_socket_t *socket_out, void *data, size_t data_len, fr_time_t *when)
Read a UDP packet.
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)
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
#define RADIUS_AUTH_VECTOR_LENGTH
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len)
Sign a previously encoded packet.
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_message_authenticator, bool limit_proxy_state)
Verify the signature of a request / response packet.
ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
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.
static ssize_t rad_recvfrom(int sockfd, fr_packet_t *packet, int flags)
Wrapper for recvfrom, which handles recvfromto, IPv6, and all possible combinations.
int fr_radius_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret)
Sign a previously encoded packet.
void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
bool fr_radius_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason)
See if the data pointed to by PTR is a valid RADIUS packet.
int fr_radius_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.
void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
ssize_t fr_radius_packet_send(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret)
Reply to the request.
#define FR_DEBUG_STRERROR_PRINTF
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
ssize_t fr_radius_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret)
Encode a packet.
static fr_dict_attr_t const * attr_message_authenticator
fr_radius_decode_fail_t
Failure reasons.
#define fr_packet_log_hex(_log, _packet)
#define FR_RADIUS_PACKET_CODE_VALID(_x)
uint32_t fr_rand(void)
Return a 32-bit random number.
Smaller fast random number generator.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
unsigned int code
Packet code (type).
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
uint8_t * data
Packet data (body).
size_t data_len
Length of packet data.
uint8_t vector[RADIUS_AUTH_VECTOR_LENGTH]
RADIUS authentication vector.
fr_time_t timestamp
When we received the packet.
#define fr_pair_list_log(_log, _lvl, _list)
int af
AF_INET, AF_INET6, or AF_UNIX.
int fd
File descriptor if this is a live socket.
int type
SOCK_STREAM, SOCK_DGRAM, etc.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_box_ipaddr(_val)
static fr_sbuff_err_t char size_t * len
#define fr_box_octets(_val, _len)