25 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
27 #include <freeradius-devel/radius/radius.h>
29 #include <freeradius-devel/server/main_config.h>
30 #include <freeradius-devel/server/module.h>
31 #include <freeradius-devel/server/pair.h>
32 #include <freeradius-devel/server/protocol.h>
33 #include <freeradius-devel/server/state.h>
35 #include <freeradius-devel/unlang/module.h>
37 #include <freeradius-devel/util/debug.h>
147 #define PROCESS_PACKET_TYPE fr_radius_packet_code_t
148 #define PROCESS_CODE_MAX FR_RADIUS_CODE_MAX
149 #define PROCESS_CODE_DO_NOT_RESPOND FR_RADIUS_CODE_DO_NOT_RESPOND
150 #define PROCESS_PACKET_CODE_VALID FR_RADIUS_PACKET_CODE_VALID
151 #define PROCESS_INST process_ttls_t
152 #include <freeradius-devel/server/process.h>
179 #ifdef WITH_IFINDEX_NAME_RESOLUTION
180 char if_name[IFNAMSIZ];
187 #ifdef WITH_IFINDEX_NAME_RESOLUTION
191 received ?
"Received" :
"Sending",
194 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
196 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
197 packet->
socket.inet.src_port,
198 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
200 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
201 packet->
socket.inet.dst_port
202 #ifdef WITH_IFINDEX_NAME_RESOLUTION
203 , packet->
socket.inet.ifindex ?
"via " :
"",
204 packet->
socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->
socket.inet.ifindex) :
"",
205 packet->
socket.inet.ifindex ?
" " :
""
209 if (received || request->parent) {
224 fr_process_state_t
const *state;
231 UPDATE_STATE(packet);
233 request->reply->code = state->packet_type[rcode];
234 if (!request->reply->code) request->reply->code = state->default_reply;
236 UPDATE_STATE_CS(reply);
239 RDEBUG(
"The 'recv Access-Request' section returned %s - not sending a response",
244 return CALL_SEND_STATE(state);
271 RDEBUG2(
"No 'authenticate %s { ... }' section found - skipping...", dv->
name);
283 NULL, 0, mctx->rctx);
288 static const fr_process_rcode_t auth_type_rcode = {
301 fr_process_state_t
const *state;
309 request->reply->code = auth_type_rcode[rcode];
312 RDEBUG(
"The 'authenticate' section returned %s - not sending a response",
316 return state->send(p_result, mctx, request);
322 if (auth_type_rcode[rcode]) request->reply->code = auth_type_rcode[rcode];
324 switch (request->reply->code) {
326 RDEBUG(
"No reply code was set. Forcing to Access-Reject");
334 RDEBUG2(
"Failed to authenticate the user");
350 RWDEBUG(
"Unprintable characters in the password. "
351 "Double-check the shared secret on the server "
385 return state->send(p_result, mctx, request);
401 if (!request->parent &&
403 (
vp->vp_strvalue[0] ==
'@') &&
405 RWDEBUG(
"User-Name is anonymized, and no Stripped-User-Name exists.");
406 RWDEBUG(
"It may be difficult or impossible to identify the user.");
407 RWDEBUG(
"Please update Stripped-User-Name with information which identifies the user.");
427 fr_process_state_t
const *state;
439 UPDATE_STATE_CS(reply);
440 return CALL_SEND_STATE(state);
462 vp->vp_uint32 = request->packet->code;
474 vp->vp_uint32 = FR_ERROR_CAUSE_VALUE_INVALID_REQUEST;
482 return CALL_RESUME(send_generic);
487 fr_process_state_t
const *state;
495 request->component =
"radius";
496 request->module = NULL;
499 UPDATE_STATE(packet);
503 return state->recv(p_result, mctx, request);
513 inst->auth.session.timeout,
inst->auth.session.state_server_id,
547 .recv = recv_generic,
548 .resume = resume_access_request,
559 .send = send_generic,
560 .resume = resume_access_accept,
571 .send = send_generic,
572 .resume = resume_access_reject,
583 .send = send_generic,
584 .resume = resume_access_challenge,
597 .send = send_generic,
598 .resume = resume_protocol_error,
615 .send = send_generic,
616 .resume = resume_send_generic,
625 .offset = PROCESS_CONF_OFFSET(access_request),
630 .offset = PROCESS_CONF_OFFSET(access_accept),
635 .offset = PROCESS_CONF_OFFSET(access_challenge),
640 .offset = PROCESS_CONF_OFFSET(access_reject),
646 .offset = PROCESS_CONF_OFFSET(protocol_error),
651 .offset = PROCESS_CONF_OFFSET(do_not_respond),
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_DO_NOT_RESPOND
Special rcode to indicate we will not respond.
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
@ FR_RADIUS_CODE_PROTOCOL_ERROR
RFC7930 - Protocol-Error (generic NAK)
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
static fr_time_delta_t timeout
fr_value_box_t const ** out
Enumeration value.
fr_dict_enum_value_t * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
fr_value_box_t const * value
Enum value (what name maps to).
char const * name
Enum name.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Specifies a value which must be present for the module to function.
Value of an enumerated attribute.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
uint32_t fr_hash_string(char const *p)
fr_dict_attr_t const * attr_packet_type
fr_dict_attr_t const * attr_state
fr_dict_t const * dict_freeradius
fr_dict_t const * dict_radius
fr_dict_attr_t const * attr_user_name
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
@ L_DBG_LVL_1
Highest priority debug messages (-x).
@ L_DBG
Only displayed when debugging is enabled.
main_config_t const * main_config
Main server configuration.
bool spawn_workers
Should the server spawn threads.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
unlang_mod_actions_t const mod_actions_authenticate
unlang_mod_actions_t const mod_actions_authorize
unlang_mod_actions_t const mod_actions_postauth
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
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.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
size_t fr_utf8_char(uint8_t const *str, ssize_t inlen)
Checks for utf-8, taken from http://www.w3.org/International/questions/qa-forms-utf-8.
CONF_SECTION * disconnect_nak
fr_state_tree_t * state_tree
State tree to link multiple requests/responses.
CONF_SECTION * access_request
static fr_dict_attr_t const * attr_user_password
static fr_dict_attr_t const * attr_module_failure_message
CONF_SECTION * access_reject
CONF_SECTION * access_accept
CONF_SECTION * status_server
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static virtual_server_compile_t const compile_list[]
process_ttls_session_t session
Session settings.
fr_time_delta_t timeout
Maximum time between the last response and next request.
fr_dict_autoload_t process_ttls_dict[]
process_ttls_sections_t sections
Pointers to various config sections we need to execute.
CONF_SECTION * do_not_respond
static fr_dict_attr_t const * attr_stripped_user_name
static fr_dict_attr_t const * attr_chap_password
static const conf_parser_t session_config[]
CONF_SECTION * accounting_request
static fr_dict_attr_t const * attr_calling_station_id
CONF_SECTION * server_cs
Our virtual server.
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_auth_type
static fr_value_box_t const * enum_auth_type_reject
static fr_dict_attr_t const * attr_error_cause
CONF_SECTION * protocol_error
static const conf_parser_t auth_config[]
static fr_process_state_t const process_state[]
CONF_SECTION * accounting_response
uint32_t max
Maximum ongoing session allowed.
process_ttls_auth_t auth
Authentication configuration.
CONF_SECTION * disconnect_request
static void radius_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, bool received)
static fr_value_box_t const * enum_auth_type_accept
static fr_dict_attr_t const * attr_nas_port
CONF_SECTION * disconnect_ack
CONF_SECTION * coa_request
fr_dict_attr_autoload_t process_ttls_dict_attr[]
uint8_t state_server_id
Sets a specific byte in the state to allow the authenticating server to be identified in packet captu...
static fr_dict_attr_t const * attr_service_type
static fr_dict_attr_t const * attr_original_packet_code
static const conf_parser_t config[]
CONF_SECTION * access_challenge
static int mod_instantiate(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_module_success_message
fr_dict_enum_autoload_t process_ttls_dict_enum[]
#define PROCESS_CODE_DO_NOT_RESPOND
fr_process_module_t process_ttls
#define PROCESS_TRACE
Trace each state function as it's entered.
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
#define RDEBUG_ENABLED2()
static void send_reply(int sockfd, fr_channel_data_t *reply)
#define FR_RADIUS_PACKET_CODE_VALID(_x)
void fr_rand_buffer(void *start, size_t length)
fr_table_num_sorted_t const rcode_table[]
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
static int instantiate(module_inst_ctx_t const *mctx)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
fr_state_tree_t * fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, uint32_t max_sessions, fr_time_delta_t timeout, uint8_t server_id, uint32_t context_id)
Initialise a new state tree.
void fr_state_discard(fr_state_tree_t *state, request_t *request)
Called when sending an Access-Accept/Access-Reject to discard state information.
int fr_request_to_state(fr_state_tree_t *state, request_t *request)
Transfer ownership of the state fr_pair_ts and ctx, back to a state entry.
unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define talloc_get_type_abort_const
A time delta, a difference in time measured in nanoseconds.
unsigned int code
Packet code (type).
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
int af
AF_INET, AF_INET6, or AF_UNIX.
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
#define fr_box_ipaddr(_val)
int virtual_server_section_attribute_define(CONF_SECTION *server_cs, char const *subcs_name, fr_dict_attr_t const *da)
Define a values for Auth-Type attributes by the sections present in a virtual-server.
#define COMPILE_TERMINATOR
section_name_t const * section
Identifier for the section.
Processing sections which are allowed in this virtual server.