25 RCSID(
"$Id: 64c45ff76169ad20d4032349ba1daf1d15a0042a $")
27 #include <freeradius-devel/radius/client.h>
28 #include <freeradius-devel/radius/client_udp.h>
29 #include <freeradius-devel/radius/client_tcp.h>
30 #include <freeradius-devel/radius/client_priv.h>
78 if (!my->
codes[i])
goto fail;
97 if (!my->
mem)
goto fail;
102 if (!my->
retry)
goto fail;
147 if (!id_ctx)
goto all_ids_used;
208 id_ctx->
packet = packet_ctx;
211 retry_ctx->
uctx = id_ctx;
243 if (!code)
return false;
251 if (!id_ctx)
return false;
314 if (!my->
retry)
return 0;
317 if (!id_ctx || !id_ctx->
retry_ctx)
return 0;
353 original = response.
uctx;
359 if (!reply)
return -1;
367 reply->
data = talloc_memdup(reply, my->
buffer, slen);
375 reply->
id = reply->
data[1];
387 *request_ctx_p = original->
uctx;
424 if ((
id < 0) || (
id > 256)) {
static int const char char buffer[256]
static ssize_t fr_bio_write(fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
Write raw data to a bio.
static ssize_t fr_bio_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
Read raw data from a bio.
void * uctx
user ctx, caller can manually set it.
fr_bio_t * bio
underlying bio for IO
fr_bio_t * fr_bio_retry_alloc(TALLOC_CTX *ctx, size_t max_saved, fr_bio_retry_sent_t sent, fr_bio_retry_response_t response, fr_bio_retry_rewrite_t rewrite, fr_bio_retry_release_t release, fr_bio_retry_config_t const *cfg, fr_bio_t *next)
Allocate a fr_bio_retry_t.
int fr_bio_retry_entry_start(UNUSED fr_bio_t *bio, fr_bio_retry_entry_t *item, fr_retry_config_t const *cfg)
Set a per-packet retry config.
int fr_bio_retry_entry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *item)
Cancel one item.
fr_bio_retry_release_reason_t
void * packet_ctx
packet_ctx from the write() call
fr_bio_retry_rewrite_t rewrite
per-packet rewrite callback
void * uctx
user-writable context
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
fr_radius_code_id_t codes
fr_bio_fd_info_t const * fd_info
fr_radius_client_config_t cfg
fr_radius_client_bio_info_t info
uint8_t buffer[4096]
temporary read buffer
fr_bio_packet_t * fr_radius_client_tcp_bio_alloc(TALLOC_CTX *ctx, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
Allocate a RADIUS bio for writing client packets.
fr_bio_packet_t * fr_radius_client_udp_bio_alloc(TALLOC_CTX *ctx, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
Allocate a RADIUS bio for writing client packets.
fr_radius_packet_code_t
RADIUS packet codes.
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_DISCONNECT_REQUEST
RFC3575/RFC5176 - Disconnect-Request.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_RADIUS_CODE_DISCONNECT_ACK
RFC3575/RFC5176 - Disconnect-Ack (positive)
@ FR_RADIUS_CODE_COA_REQUEST
RFC3575/RFC5176 - CoA-Request.
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
@ FR_RADIUS_CODE_COA_NAK
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
@ FR_RADIUS_CODE_COA_ACK
RFC3575/RFC5176 - CoA-Ack (positive)
@ FR_RADIUS_CODE_DISCONNECT_NAK
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
@ FR_RADIUS_CODE_PROTOCOL_ERROR
RFC7930 - Protocol-Error (generic NAK)
@ FR_RADIUS_CODE_ACCOUNTING_REQUEST
RFC2866 - Accounting-Request.
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
fr_bio_fd_info_t const * fr_bio_fd_info(fr_bio_t *bio)
Returns a pointer to the bio-specific information.
fr_bio_t * fr_bio_fd_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, fr_bio_fd_config_t const *cfg, size_t offset)
Allocate a FD bio.
int fr_bio_fd_connect(fr_bio_t *bio)
Finalize a connect()
fr_socket_t socket
as connected socket
@ FR_BIO_FD_CONNECTED
connected client sockets (UDP or TCP)
@ FR_BIO_FD_UNCONNECTED
unconnected UDP / datagram only
fr_bio_fd_type_t type
type of the socket
fr_bio_fd_state_t state
connecting, open, closed, etc.
@ FR_BIO_FD_STATE_INVALID
@ FR_BIO_FD_STATE_CONNECTING
@ FR_BIO_FD_STATE_OPEN
error states must be before this
fr_bio_fd_type_t type
accept, connected, unconnected, etc.
char const * path
for Unix domain sockets
char const * filename
for files
int socket_type
SOCK_STREAM or SOCK_DGRAM.
Configuration for sockets.
int fr_bio_free(fr_bio_t *bio)
Free this bio, and everything it calls.
int fr_bio_shutdown(fr_bio_t *bio)
Shut down a set of BIOs.
fr_bio_t * fr_bio_mem_alloc(TALLOC_CTX *ctx, size_t read_size, size_t write_size, fr_bio_t *next)
Allocate a memory buffer bio.
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
#define RADIUS_HEADER_LENGTH
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_ma)
Verify a request / response packet.
ssize_t fr_radius_decode_simple(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, uint8_t const *vector, char const *secret)
Simple wrapper for callers who just need a shared secret.
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
bool require_message_authenticator
fr_radius_bio_verify_t verify
fr_bio_retry_config_t retry_cfg
fr_retry_config_t retry[FR_RADIUS_CODE_MAX]
default retry configuration for each packet type
bool outgoing[FR_RADIUS_CODE_MAX]
allowed outgoing packet types
fr_radius_id_t * fr_radius_id_alloc(TALLOC_CTX *ctx)
Allocate a tracking structure for one packet code.
static void fr_radius_code_id_push(fr_radius_code_id_t codes, fr_packet_t const *packet)
static fr_radius_id_ctx_t * fr_radius_code_id_pop(fr_radius_code_id_t codes, fr_packet_t *packet)
void * retry_ctx
to find the retry information
void * request_ctx
for the application to track
fr_packet_t * packet
outgoing packet
fr_packet_t * response
response to outgoing packet
static fr_radius_id_ctx_t * fr_radius_code_id_find(fr_radius_code_id_t codes, int code, int id)
static int fr_radius_code_id_force(fr_radius_code_id_t codes, int code, int id)
int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret)
Sign a previously encoded packet.
ssize_t fr_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret)
Encode a packet.
#define request_ctx
Talloc ctx for allocating request pairs under.
fr_radius_client_fd_bio_t * fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t read_size, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
static int _radius_client_fd_bio_free(fr_radius_client_fd_bio_t *my)
static void radius_client_retry_release(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, UNUSED fr_bio_retry_release_reason_t reason)
fr_bio_packet_t * fr_radius_client_bio_alloc(TALLOC_CTX *ctx, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
static bool radius_client_retry_response(fr_bio_t *bio, fr_bio_retry_entry_t **retry_ctx_p, UNUSED void *packet_ctx, const void *buffer, UNUSED size_t size)
static void radius_client_retry_sent(fr_bio_t *bio, void *packet_ctx, const void *buffer, UNUSED size_t size, fr_bio_retry_entry_t *retry_ctx)
fr_bio_t * fr_radius_client_bio_get_fd(fr_bio_packet_t *bio)
static const fr_radius_packet_code_t allowed_replies[FR_RADIUS_CODE_MAX]
int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, void **request_ctx_p, fr_packet_t **packet_p, UNUSED TALLOC_CTX *out_ctx, fr_pair_list_t *out)
int fr_radius_client_fd_bio_cancel(fr_bio_packet_t *bio, fr_packet_t *packet)
Cancel one packet.
int fr_radius_client_bio_force_id(fr_bio_packet_t *bio, int code, int id)
int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, void *request_ctx, fr_packet_t *packet, fr_pair_list_t *list)
fr_radius_client_bio_info_t const * fr_radius_client_bio_info(fr_bio_packet_t *bio)
size_t fr_radius_client_bio_outstanding(fr_bio_packet_t *bio)
int fr_radius_client_bio_connect(fr_bio_packet_t *bio)
Try to connect a socket.
#define fr_time()
Allow us to arbitrarily manipulate time.
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.
int af
AF_INET, AF_INET6, or AF_UNIX.
static void fr_socket_addr_swap(fr_socket_t *dst, fr_socket_t const *src)
Swap src/dst information of a fr_socket_t.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static size_t char ** out