61 RCSID(
"$Id: e4e7c3348502ce294cf0eb18047e9c3fe4357ee3 $")
63 #define LOG_PREFIX "eap"
65 #include <freeradius-devel/eap/base.h>
66 #include <freeradius-devel/server/virtual_servers.h>
67 #include <freeradius-devel/server/pair.h>
68 #include <freeradius-devel/server/auth.h>
69 #include <freeradius-devel/unlang/call.h>
129 DEBUG(
"Asked to encode empty EAP-Message!");
137 if (size > 253) size = 253;
168 packet_len = talloc_array_length((
uint8_t *) eap_packet);
178 fr_strerror_printf(
"Invalid EAP length field. Expected value in range %u-%zu, was %u bytes",
186 switch (eap_packet->
code) {
196 if ((eap_packet->
data[0] == 0) ||
210 if ((eap_packet->
data[1] != 0) ||
211 (eap_packet->
data[2] != 0) ||
212 (eap_packet->
data[3] != 0)) {
213 fr_strerror_const(
"Expanded EAP type has unknown Vendor-ID: ignoring the packet");
217 if ((eap_packet->
data[4] != 0) ||
218 (eap_packet->
data[5] != 0) ||
219 (eap_packet->
data[6] != 0)) {
220 fr_strerror_const(
"Expanded EAP type has unknown Vendor-Type: ignoring the packet");
224 if ((eap_packet->
data[7] == 0) ||
242 p = talloc_realloc(ctx, eap_packet,
uint8_t, len - 7);
250 p[2] = (len >> 8) & 0xff;
300 if (
vp->vp_length < 4) {
309 memcpy(&len,
vp->vp_strvalue + 2,
sizeof(len));
327 total_len +=
vp->vp_length;
329 if (total_len > len) {
331 "does not match actual length %i", len, total_len);
339 if (total_len < len) {
341 "match actual length");
349 if (!eap_packet)
return NULL;
354 ptr = (
unsigned char *)eap_packet;
360 memcpy(ptr,
vp->vp_strvalue,
vp->vp_length);
361 ptr +=
vp->vp_length;
417 RDEBUG2(
"Running request in virtual server");
425 if (eap_session->child) {
426 RDEBUG4(
"Adding eap_session_t %p to child request", eap_session->child);
433 if (eap_session_inner) {
438 if (!eap_session->child || (eap_session->child != eap_session_inner)) {
439 RDEBUG4(
"Binding lifetime of child eap_session %p to parent eap_session %p",
440 eap_session_inner, eap_session);
442 eap_session->child = eap_session_inner;
444 RDEBUG4(
"Got eap_session_t %p back unmolested", eap_session->child);
454 }
else if (eap_session->child) {
455 RDEBUG4(
"Inner server freed eap_session %p", eap_session->child);
456 eap_session->child = NULL;
469 PERROR(
"%s", __FUNCTION__);
478 PERROR(
"%s", __FUNCTION__);
unlang_action_t rad_virtual_server(rlm_rcode_t *p_result, request_t *request)
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
#define fr_dict_autofree(_to_free)
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.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
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.
char const * eap_type2name(eap_type_t method)
Return an EAP-name for a particular type.
#define FR_EAP_EXPANDED_TYPE
@ FR_EAP_METHOD_NOTIFICATION
Structure to represent packet format of eap on wire
HIDDEN fr_dict_attr_t const * attr_virtual_server
fr_dict_attr_autoload_t eap_base_dict_attr[]
void eap_packet_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *list, eap_packet_raw_t const *eap)
fr_dict_attr_t const * attr_eap_session_id
fr_dict_attr_t const * attr_state
fr_dict_attr_t const * attr_eap_identity
fr_dict_attr_t const * attr_freeradius_proxied_to
fr_dict_attr_t const * attr_chbind_response_code
fr_dict_attr_t const * attr_eap_message
fr_dict_attr_t const * attr_eap_type
fr_dict_attr_t const * attr_eap_msk
fr_dict_attr_t const * attr_eap_channel_binding_message
fr_dict_t const * dict_freeradius
fr_dict_t const * dict_radius
int eap_base_init(void)
Initialise the lib eap base library.
void eap_base_free(void)
De-init the lib eap base library.
fr_dict_attr_t const * attr_eap_emsk
fr_dict_attr_t const * attr_ms_mppe_send_key
fr_dict_attr_t const * attr_user_name
static bool eap_is_valid(TALLOC_CTX *ctx, eap_packet_raw_t **eap_packet_p)
Basic EAP packet verifications & validations.
fr_dict_attr_t const * attr_ms_mppe_recv_key
fr_dict_autoload_t eap_base_dict[]
rlm_rcode_t eap_virtual_server(UNUSED request_t *request, UNUSED eap_session_t *eap_session, UNUSED char const *virtual_server)
Run a subrequest through a virtual server, managing the eap_session_t of the child.
void eap_add_reply(request_t *request, fr_dict_attr_t const *da, uint8_t const *value, int len)
eap_packet_raw_t * eap_packet_from_vp(TALLOC_CTX *ctx, fr_pair_list_t *vps)
fr_dict_attr_t const * attr_message_authenticator
#define REQUEST_DATA_EAP_SESSION
eap_session_t * child
Session for tunneled EAP method.
Tracks the progress of a single session of any EAP method.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RINDENT()
Indent R* messages by one level.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
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.
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_FAIL
Module failed, don't reply.
void * request_data_get(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request.
#define request_data_talloc_add(_request, _unique_ptr, _unique_int, _type, _opaque, _free_on_replace, _free_on_parent, _persist)
Add opaque data to a request_t.
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
Stores an attribute, a value and various bits of other data.
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
Types of values contained within an fr_value_box_t.
CONF_SECTION * virtual_server_find(char const *name)
Return virtual server matching the specified name.