The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Functions | Variables
base.c File Reference

Functions to send/receive radius packets. More...

#include <fcntl.h>
#include <ctype.h>
#include "attrs.h"
#include "radius.h"
#include <freeradius-devel/io/pair.h>
#include <freeradius-devel/util/md5.h>
#include <freeradius-devel/util/net.h>
#include <freeradius-devel/util/proto.h>
#include <freeradius-devel/util/table.h>
#include <freeradius-devel/util/udp.h>
#include <freeradius-devel/protocol/radius/freeradius.internal.h>
+ Include dependency graph for base.c:

Go to the source code of this file.

Macros

#define FR_DEBUG_STRERROR_PRINTF   if (fr_debug_lvl) fr_strerror_printf_push
 

Functions

static bool attr_valid (fr_dict_attr_t *da)
 
static int dict_flag_encrypt (fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
 
int fr_radius_allow_reply (int code, bool allowed[static FR_RADIUS_CODE_MAX])
 
ssize_t fr_radius_ascend_secret (fr_dbuff_t *dbuff, uint8_t const *in, size_t inlen, char const *secret, uint8_t const *vector)
 Do Ascend-Send / Recv-Secret calculation. More...
 
ssize_t fr_radius_decode (TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t *packet, size_t packet_len, fr_radius_decode_ctx_t *decode_ctx)
 
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. More...
 
ssize_t fr_radius_encode (fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
 
void fr_radius_global_free (void)
 
int fr_radius_global_init (void)
 
void * fr_radius_next_encodable (fr_dlist_head_t *list, void *current, void *uctx)
 
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)
 See if the data pointed to by PTR is a valid RADIUS packet. More...
 
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. More...
 
int fr_radius_sign (uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len)
 Sign a previously encoded packet. More...
 
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 a request / response packet. More...
 

Variables

static const fr_radius_packet_code_t allowed_replies [FR_RADIUS_CODE_MAX]
 If we get a reply, the request must come from one of a small number of packet types. More...
 
fr_dict_attr_t const * attr_chap_challenge
 
fr_dict_attr_t const * attr_chargeable_user_identity
 
fr_dict_attr_t const * attr_eap_message
 
fr_dict_attr_t const * attr_message_authenticator
 
fr_dict_attr_t const * attr_nas_filter_rule
 
fr_dict_attr_t const * attr_packet_authentication_vector
 
fr_dict_attr_t const * attr_packet_type
 
fr_dict_attr_t const * attr_state
 
fr_dict_attr_t const * attr_vendor_specific
 
fr_dict_t const * dict_freeradius
 
fr_dict_t const * dict_radius
 
static const bool disallow_tunnel_passwords [FR_RADIUS_CODE_MAX]
 
fr_table_num_sorted_t const fr_radius_limit_proxy_state_table []
 
size_t fr_radius_limit_proxy_state_table_len = NUM_ELEMENTS(fr_radius_limit_proxy_state_table)
 
char const * fr_radius_packet_name [FR_RADIUS_CODE_MAX]
 
fr_table_num_sorted_t const fr_radius_request_name_table []
 
size_t fr_radius_request_name_table_len = NUM_ELEMENTS(fr_radius_request_name_table)
 
fr_table_num_sorted_t const fr_radius_require_ma_table []
 
size_t fr_radius_require_ma_table_len = NUM_ELEMENTS(fr_radius_require_ma_table)
 
static uint32_t instance_count = 0
 
fr_dict_autoload_t libfreeradius_radius_dict []
 
fr_dict_attr_autoload_t libfreeradius_radius_dict_attr []
 
fr_dict_protocol_t libfreeradius_radius_dict_protocol
 
static fr_dict_flag_parser_t const radius_flags []
 

Detailed Description

Functions to send/receive radius packets.

Id
b381becb8717331ad50f394d96442eedd8559a78

Definition in file base.c.

Macro Definition Documentation

◆ FR_DEBUG_STRERROR_PRINTF

#define FR_DEBUG_STRERROR_PRINTF   if (fr_debug_lvl) fr_strerror_printf_push

Definition at line 81 of file base.c.

Function Documentation

◆ attr_valid()

static bool attr_valid ( fr_dict_attr_t da)
static

Definition at line 1247 of file base.c.

+ Here is the call graph for this function:

◆ dict_flag_encrypt()

static int dict_flag_encrypt ( fr_dict_attr_t **  da_p,
char const *  value,
UNUSED fr_dict_flag_parser_rule_t const *  rules 
)
static

Definition at line 191 of file base.c.

+ Here is the call graph for this function:

◆ fr_radius_allow_reply()

int fr_radius_allow_reply ( int  code,
bool  allowed[static FR_RADIUS_CODE_MAX] 
)

Definition at line 227 of file base.c.

+ Here is the caller graph for this function:

◆ fr_radius_ascend_secret()

ssize_t fr_radius_ascend_secret ( fr_dbuff_t dbuff,
uint8_t const *  in,
size_t  inlen,
char const *  secret,
uint8_t const *  vector 
)

Do Ascend-Send / Recv-Secret calculation.

The secret is hidden by xoring with a MD5 digest created from the RADIUS shared secret and the authentication vector. We put them into MD5 in the reverse order from that used when encrypting passwords to RADIUS.

Definition at line 247 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_decode()

ssize_t fr_radius_decode ( TALLOC_CTX *  ctx,
fr_pair_list_t out,
uint8_t packet,
size_t  packet_len,
fr_radius_decode_ctx_t decode_ctx 
)

Definition at line 1087 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_decode_simple()

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.

Definition at line 1195 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_encode()

ssize_t fr_radius_encode ( fr_dbuff_t dbuff,
fr_pair_list_t vps,
fr_radius_encode_ctx_t packet_ctx 
)

Definition at line 952 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_global_free()

void fr_radius_global_free ( void  )

Definition at line 1240 of file base.c.

+ Here is the caller graph for this function:

◆ fr_radius_global_init()

int fr_radius_global_init ( void  )

Definition at line 1217 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_next_encodable()

void * fr_radius_next_encodable ( fr_dlist_head_t list,
void *  current,
void *  uctx 
)

Definition at line 914 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_ok()

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 
)

See if the data pointed to by PTR is a valid RADIUS packet.

Parameters
[in]packetto check.
[in,out]packet_len_pThe size of the packet data.
[in]max_attributesto allow in the packet.
[in]require_message_authenticatorwhether we require Message-Authenticator.
[in]reasonif not NULL, will have the failure reason written to where it points.
Returns
  • True on success.
  • False on failure.

Definition at line 514 of file base.c.

+ Here is the call graph for this function:

◆ fr_radius_recv_header()

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.

Note
fr_strerror errors are only available if fr_debug_lvl > 0. This is to reduce CPU time consumed when discarding malformed packet.
Parameters
[in]sockfdwe're reading from.
[out]src_ipaddrof the packet.
[out]src_portof the packet.
[out]codePointer to where to write the packet code.
Returns
  • -1 on failure.
  • 1 on decode error.
  • >= RADIUS_HEADER_LENGTH on success. This is the packet length as specified in the header.

Definition at line 285 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_sign()

int fr_radius_sign ( uint8_t packet,
uint8_t const *  vector,
uint8_t const *  secret,
size_t  secret_len 
)

Sign a previously encoded packet.

Calculates the request/response authenticator for packets which need it, and fills in the message-authenticator value if the attribute is present in the encoded packet.

Parameters
[in,out]packet(request or response).
[in]vectororiginal packet vector to use
[in]secretto sign the packet with.
[in]secret_lenThe length of the secret.
Returns
  • <0 on error
  • 0 on success

Definition at line 358 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_radius_verify()

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 a request / response packet.

This function does its work by calling fr_radius_sign(), and then comparing the signature in the packet with the one we calculated. If they differ, there's a problem.

Parameters
[in]packetthe raw RADIUS packet (request or response)
[in]vectorthe original packet vector
[in]secretthe shared secret
[in]secret_lenthe length of the secret
[in]require_message_authenticatorwhether we require Message-Authenticator.
[in]limit_proxy_statewhether we allow Proxy-State without Message-Authenticator.
Returns
  • -2 if the message authenticator or request authenticator was invalid.
  • -1 if we were unable to verify the shared secret, or the packet was in some other way malformed.
  • 0 on success.

Definition at line 777 of file base.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ allowed_replies

const fr_radius_packet_code_t allowed_replies[FR_RADIUS_CODE_MAX]
static
Initial value:
= {
}
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition: defs.h:43
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
Definition: defs.h:33
@ FR_RADIUS_CODE_DISCONNECT_REQUEST
RFC3575/RFC5176 - Disconnect-Request.
Definition: defs.h:46
@ FR_RADIUS_CODE_DISCONNECT_ACK
RFC3575/RFC5176 - Disconnect-Ack (positive)
Definition: defs.h:47
@ FR_RADIUS_CODE_COA_REQUEST
RFC3575/RFC5176 - CoA-Request.
Definition: defs.h:49
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
Definition: defs.h:34
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
Definition: defs.h:37
@ FR_RADIUS_CODE_COA_NAK
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
Definition: defs.h:51
@ FR_RADIUS_CODE_COA_ACK
RFC3575/RFC5176 - CoA-Ack (positive)
Definition: defs.h:50
@ FR_RADIUS_CODE_DISCONNECT_NAK
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
Definition: defs.h:48
@ FR_RADIUS_CODE_PROTOCOL_ERROR
RFC7930 - Protocol-Error (generic NAK)
Definition: defs.h:52
@ FR_RADIUS_CODE_ACCOUNTING_REQUEST
RFC2866 - Accounting-Request.
Definition: defs.h:36
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
Definition: defs.h:35

If we get a reply, the request must come from one of a small number of packet types.

Definition at line 172 of file base.c.

◆ attr_chap_challenge

fr_dict_attr_t const* attr_chap_challenge

Definition at line 55 of file base.c.

◆ attr_chargeable_user_identity

fr_dict_attr_t const* attr_chargeable_user_identity

Definition at line 56 of file base.c.

◆ attr_eap_message

fr_dict_attr_t const* attr_eap_message

Definition at line 57 of file base.c.

◆ attr_message_authenticator

fr_dict_attr_t const* attr_message_authenticator

Definition at line 58 of file base.c.

◆ attr_nas_filter_rule

fr_dict_attr_t const* attr_nas_filter_rule

Definition at line 61 of file base.c.

◆ attr_packet_authentication_vector

fr_dict_attr_t const* attr_packet_authentication_vector

Definition at line 54 of file base.c.

◆ attr_packet_type

fr_dict_attr_t const* attr_packet_type

Definition at line 53 of file base.c.

◆ attr_state

fr_dict_attr_t const* attr_state

Definition at line 59 of file base.c.

◆ attr_vendor_specific

fr_dict_attr_t const* attr_vendor_specific

Definition at line 60 of file base.c.

◆ dict_freeradius

fr_dict_t const* dict_freeradius

Definition at line 43 of file base.c.

◆ dict_radius

fr_dict_t const* dict_radius

Definition at line 44 of file base.c.

◆ disallow_tunnel_passwords

const bool disallow_tunnel_passwords[FR_RADIUS_CODE_MAX]
static
Initial value:

Definition at line 931 of file base.c.

◆ fr_radius_limit_proxy_state_table

fr_table_num_sorted_t const fr_radius_limit_proxy_state_table[]
Initial value:
= {
}
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
@ FR_RADIUS_LIMIT_PROXY_STATE_NO
Do not limit Proxy-State.
Definition: radius.h:77
@ FR_RADIUS_LIMIT_PROXY_STATE_AUTO
Do not allow Proxy-State unless:
Definition: radius.h:79
@ FR_RADIUS_LIMIT_PROXY_STATE_YES
Limit Proxy-State.
Definition: radius.h:84

Definition at line 92 of file base.c.

◆ fr_radius_limit_proxy_state_table_len

size_t fr_radius_limit_proxy_state_table_len = NUM_ELEMENTS(fr_radius_limit_proxy_state_table)

Definition at line 99 of file base.c.

◆ fr_radius_packet_name

char const* fr_radius_packet_name[FR_RADIUS_CODE_MAX]

Definition at line 112 of file base.c.

◆ fr_radius_request_name_table

fr_table_num_sorted_t const fr_radius_request_name_table[]
Initial value:
= {
}
@ FR_RADIUS_CODE_UNDEFINED
Packet code has not been set.
Definition: defs.h:32

Definition at line 101 of file base.c.

◆ fr_radius_request_name_table_len

size_t fr_radius_request_name_table_len = NUM_ELEMENTS(fr_radius_request_name_table)

Definition at line 110 of file base.c.

◆ fr_radius_require_ma_table

fr_table_num_sorted_t const fr_radius_require_ma_table[]
Initial value:
= {
{ L("false"), FR_RADIUS_REQUIRE_MA_NO },
}
@ FR_RADIUS_REQUIRE_MA_NO
Do not require Message-Authenticator.
Definition: radius.h:63
@ FR_RADIUS_REQUIRE_MA_YES
Require Message-Authenticator.
Definition: radius.h:68
@ FR_RADIUS_REQUIRE_MA_AUTO
Only require Message-Authenticator if we've previously received a packet from this client with Messag...
Definition: radius.h:64

Definition at line 83 of file base.c.

◆ fr_radius_require_ma_table_len

size_t fr_radius_require_ma_table_len = NUM_ELEMENTS(fr_radius_require_ma_table)

Definition at line 90 of file base.c.

◆ instance_count

uint32_t instance_count = 0
static

Definition at line 41 of file base.c.

◆ libfreeradius_radius_dict

fr_dict_autoload_t libfreeradius_radius_dict
Initial value:
= {
{ .out = &dict_freeradius, .proto = "freeradius" },
{ .out = &dict_radius, .proto = "radius" },
{ NULL }
}
fr_dict_t const * dict_freeradius
Definition: base.c:77
fr_dict_t const * dict_radius
Definition: base.c:78

Definition at line 47 of file base.c.

◆ libfreeradius_radius_dict_attr

fr_dict_attr_autoload_t libfreeradius_radius_dict_attr
Initial value:
= {
{ .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_radius },
{ .out = &attr_packet_authentication_vector, .name = "Packet-Authentication-Vector", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_chap_challenge, .name = "CHAP-Challenge", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_chargeable_user_identity, .name = "Chargeable-User-Identity", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_eap_message, .name = "EAP-Message", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_message_authenticator, .name = "Message-Authenticator", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_state, .name = "State", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
{ .out = &attr_vendor_specific, .name = "Vendor-Specific", .type = FR_TYPE_VSA, .dict = &dict_radius },
{ .out = &attr_nas_filter_rule, .name = "NAS-Filter-Rule", .type = FR_TYPE_STRING, .dict = &dict_radius },
{ NULL }
}
fr_dict_attr_t const * attr_packet_type
Definition: base.c:91
fr_dict_attr_t const * attr_state
Definition: base.c:101
fr_dict_attr_t const * attr_eap_message
Definition: base.c:94
fr_dict_attr_t const * attr_message_authenticator
Definition: base.c:92
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
Definition: merged_model.c:121
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
fr_dict_attr_t const * attr_nas_filter_rule
Definition: base.c:61
fr_dict_attr_t const * attr_packet_authentication_vector
Definition: base.c:54
fr_dict_attr_t const * attr_chap_challenge
Definition: base.c:55
fr_dict_attr_t const * attr_vendor_specific
Definition: base.c:60
fr_dict_attr_t const * attr_chargeable_user_identity
Definition: base.c:56

Definition at line 64 of file base.c.

◆ libfreeradius_radius_dict_protocol

fr_dict_protocol_t libfreeradius_radius_dict_protocol
Initial value:
= {
.name = "radius",
.default_type_size = 1,
.default_type_length = 1,
.attr = {
.flags = {
.table = radius_flags,
.table_len = NUM_ELEMENTS(radius_flags),
.len = sizeof(fr_radius_attr_flags_t),
},
.valid = attr_valid,
},
}
#define NUM_ELEMENTS(_t)
Definition: build.h:335
static fr_dict_flag_parser_t const radius_flags[]
Definition: base.c:218
static bool attr_valid(fr_dict_attr_t *da)
Definition: base.c:1247
int fr_radius_global_init(void)
Definition: base.c:1217
void fr_radius_global_free(void)
Definition: base.c:1240
ssize_t fr_radius_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
Definition: decode.c:2088
ssize_t fr_radius_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
Definition: encode.c:1682

Definition at line 1389 of file base.c.

◆ radius_flags

fr_dict_flag_parser_t const radius_flags[]
static
Initial value:
= {
{ L("abinary"), { .func = dict_flag_abinary } },
{ L("concat"), { .func = dict_flag_concat } },
{ L("encrypt"), { .func = dict_flag_encrypt, .needs_value = true } },
{ L("extended"), { .func = dict_flag_extended } },
{ L("has_tag"), { .func = dict_flag_has_tag } },
{ L("long_extended"), { .func = dict_flag_long_extended } }
}
static int dict_flag_encrypt(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
Definition: base.c:191

Definition at line 218 of file base.c.