The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
compose.c
Go to the documentation of this file.
1/*
2 * eap.c rfc2284 & rfc2869 implementation
3 *
4 * Version: $Id: 908b87943621688589c6f80cd66c11121d1db4e0 $
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 * @copyright 2000-2003,2006 The FreeRADIUS server project
21 * @copyright 2001 hereUare Communications, Inc. (raghud@hereuare.com)
22 * @copyright 2003 Alan DeKok (aland@freeradius.org)
23 */
24/*
25 * EAP PACKET FORMAT
26 * --- ------ ------
27 * 0 1 2 3
28 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
29 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 * | Code | Identifier | Length |
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Data ...
33 * +-+-+-+-+
34 *
35 *
36 * EAP Request and Response Packet Format
37 * --- ------- --- -------- ------ ------
38 * 0 1 2 3
39 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Code | Identifier | Length |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | Type | Type-Data ...
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
45 *
46 *
47 * EAP Success and Failure Packet Format
48 * --- ------- --- ------- ------ ------
49 * 0 1 2 3
50 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * | Code | Identifier | Length |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 *
55 */
56#define LOG_PREFIX "eap"
57#include <freeradius-devel/server/modpriv.h>
58#include <freeradius-devel/server/pair.h>
59#include <freeradius-devel/radius/radius.h>
60#include <ctype.h>
61
62#include "attrs.h"
63#include "compose.h"
64
65RCSID("$Id: 908b87943621688589c6f80cd66c11121d1db4e0 $")
66
67static char const *eap_codes[] = {
68 "", /* 0 is invalid */
69 "Request",
70 "Response",
71 "Success",
72 "Failure"
73};
74
75/*
76 * EAP packet format to be sent over the wire
77 *
78 * i.e. code+id+length+data where data = null/type+typedata
79 * based on code.
80 *
81 * INPUT to function is reply->code
82 * reply->id
83 * reply->type - setup with data
84 *
85 * OUTPUT reply->packet is setup with wire format, and will
86 * be allocated to the right size.
87 *
88 */
89static int eap_wireformat(eap_packet_t *reply)
90{
91 eap_packet_raw_t *header;
92 uint16_t total_length = 0;
93
94 if (!reply) return 0;
95
96 /*
97 * If reply->packet is set, then the wire format
98 * has already been calculated, just succeed.
99 */
100 if(reply->packet != NULL) return 0;
101
102 total_length = EAP_HEADER_LEN;
103 if (reply->code == FR_EAP_CODE_REQUEST) {
104 total_length += 1/* EAP Method */;
105 if (reply->type.data && (reply->type.length > 0)) {
106 if (reply->type.length > (size_t) (UINT16_MAX - total_length)) {
107 fr_strerror_const("EAP type data too large for wire format");
108 return -1;
109 }
110 total_length += reply->type.length;
111 }
112 }
113
114 reply->packet = talloc_array(reply, uint8_t, total_length);
115 if (!reply->packet) {
116 return -1;
117 }
118
119 header = (eap_packet_raw_t *)reply->packet;
120 header->code = (reply->code & 0xFF);
121 header->id = (reply->id & 0xFF);
122
123 total_length = htons(total_length);
124 memcpy(header->length, &total_length, sizeof(total_length));
125
126 /*
127 * Request and Response packets are special.
128 */
129 if ((reply->code == FR_EAP_CODE_REQUEST) ||
130 (reply->code == FR_EAP_CODE_RESPONSE)) {
131 header->data[0] = (reply->type.num & 0xFF);
132
133 /*
134 * Here since we cannot know the typedata format and length
135 *
136 * Type_data is expected to be wired by each EAP-Type
137 *
138 * Zero length/No typedata is supported as long as
139 * type is defined
140 */
141 if (reply->type.data && reply->type.length > 0) {
142 memcpy(&header->data[1], reply->type.data, reply->type.length);
143 talloc_free(reply->type.data);
144 reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;
145 }
146 }
147
148 return 0;
149}
150
151/*
152 * compose EAP reply packet in EAP-Message attr of RADIUS.
153 *
154 * Set the RADIUS reply codes based on EAP request codes. Append
155 * any additional VPs to RADIUS reply
156 */
158{
159 fr_pair_t *vp;
160 eap_packet_raw_t *eap_packet;
161 request_t *request;
162 eap_round_t *eap_round;
163 eap_packet_t *reply;
164 int rcode;
165
166 eap_session = talloc_get_type_abort(eap_session, eap_session_t);
167 request = talloc_get_type_abort(eap_session->request, request_t);
168 eap_round = talloc_get_type_abort(eap_session->this_round, eap_round_t);
169 reply = talloc_get_type_abort(eap_round->request, eap_packet_t);
170
171 /*
172 * The Id for the EAP packet to the NAS wasn't set.
173 * Do so now.
174 */
175 if (!eap_round->set_request_id) {
176 /*
177 * Id serves to support request/response
178 * retransmission in the EAP layer and as such
179 * must be different for 'adjacent' packets
180 * except in case of success/failure-replies.
181 *
182 * RFC2716 (EAP-TLS) requires this to be
183 * incremented, RFC2284 only makes the above-
184 * mentioned restriction.
185 */
186 reply->id = eap_session->this_round->response->id;
187
188 switch (reply->code) {
189 /*
190 * The Id is a simple "ack" for success
191 * and failure.
192 *
193 * RFC 3748 section 4.2 says
194 *
195 * ... The Identifier field MUST match
196 * the Identifier field of the Response
197 * packet that it is sent in response
198 * to.
199 */
202 break;
203
204 /*
205 * We've sent a response to their
206 * request, the Id is incremented.
207 */
208 default:
209 ++reply->id;
210 }
211 }
212
213 /*
214 * For Request & Response packets, set the EAP sub-type,
215 * if the EAP sub-module didn't already set it.
216 *
217 * This allows the TLS module to be "morphic", and means
218 * that the TTLS and PEAP modules can call it to do most
219 * of their dirty work.
220 */
221 if (((eap_round->request->code == FR_EAP_CODE_REQUEST) ||
222 (eap_round->request->code == FR_EAP_CODE_RESPONSE)) &&
223 (eap_round->request->type.num == 0)) {
224 fr_assert(eap_session->type >= FR_EAP_METHOD_MD5);
225 fr_assert(eap_session->type < FR_EAP_METHOD_MAX);
226
227 eap_round->request->type.num = eap_session->type;
228 }
229
230 if (eap_wireformat(reply) < 0) return RLM_MODULE_INVALID;
231
232 eap_packet = (eap_packet_raw_t *)reply->packet;
233
235 fr_pair_value_memdup_shallow(vp, talloc_steal(vp, reply->packet),
236 eap_packet->length[0] * 256 + eap_packet->length[1], false);
237 reply->packet = NULL;
238
239 /*
240 * EAP-Message is always associated with
241 * Message-Authenticator but not vice-versa.
242 *
243 * Don't add a Message-Authenticator if
244 * it's already there.
245 */
246 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_message_authenticator);
247 if (!vp) {
248 static uint8_t auth_vector[RADIUS_AUTH_VECTOR_LENGTH] = { 0x00 };
249
251 fr_pair_value_memdup(vp, auth_vector, sizeof(auth_vector), false);
252 }
253
254 switch (reply->code) {
256 request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
257 rcode = RLM_MODULE_HANDLED;
258 break;
259
261 request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
262 rcode = RLM_MODULE_OK;
263 break;
264
266 request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
267 rcode = RLM_MODULE_REJECT;
268 break;
269
271 request->reply->code = FR_RADIUS_CODE_ACCESS_CHALLENGE;
272 rcode = RLM_MODULE_HANDLED;
273 break;
274
275 default:
276 /* Should never enter here */
277 REDEBUG("Reply code %u is unknown, rejecting the request", reply->code);
278 request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
279 eap_packet->code = reply->code = FR_EAP_CODE_FAILURE;
280 rcode = RLM_MODULE_REJECT;
281 break;
282 }
283
284 RDEBUG2("Sending EAP %s (code %d) ID %d length %i",
285 eap_codes[reply->code], reply->code, reply->id,
286 eap_packet->length[0] * 256 + eap_packet->length[1]);
287
288 return rcode;
289}
290
291/*
292 * Code to return when we either ignore unknown EAP types (so that they can be proxied), or else we fail,
293 * so that we reject them.
294 */
298
299/*
300 * Start or continue an EAP session.
301 */
302rlm_rcode_t eap_start(request_t *request, rlm_eap_method_t const methods[], bool ignore_unknown_types)
303{
304 fr_pair_t *vp;
305 fr_pair_t *eap_msg;
306
307 eap_msg = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_message);
308 if (!eap_msg) {
309 RDEBUG2("No EAP-Message, not doing EAP");
310 return RLM_MODULE_NOOP;
311 }
312
313 /*
314 * Look for EAP-Type = None (FreeRADIUS specific attribute)
315 * this allows you to NOT do EAP for some users.
316 */
317 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_type);
318 if (vp && vp->vp_uint32 == 0) {
319 RDEBUG2("Found EAP-Message, but EAP-Type = None, so we're not doing EAP");
320 return RLM_MODULE_NOOP;
321 }
322
323 /*
324 * Check the length before dereferencing the contents.
325 *
326 * Lengths of zero are required by the RFC for EAP-Start,
327 * but we've never seen them in practice.
328 *
329 * Lengths of two are what we see in practice as
330 * EAP-Starts.
331 */
332 if ((eap_msg->vp_length == 0) || (eap_msg->vp_length == 2)) {
333 uint8_t *p;
334
335 RDEBUG2("Got EAP_START message");
336
338
339 /*
340 * Manually create an EAP Identity request
341 */
342 MEM(fr_pair_value_mem_alloc(vp, &p, 5, false) == 0);
343 p[0] = FR_EAP_CODE_REQUEST;
344 p[1] = 0; /* ID */
345 p[2] = 0;
346 p[3] = 5; /* length */
348
349 return RLM_MODULE_HANDLED;
350 } /* end of handling EAP-Start */
351
352 /*
353 * Supplicants don't usually send EAP-Failures to the server, but they're not forbidden from
354 * doing so.
355 *
356 * This behaviour was observed with a Spirent Avalanche test server.
357 */
358 if ((eap_msg->vp_octets[0] == FR_EAP_CODE_FAILURE) &&
359 (eap_msg->vp_length >= EAP_HEADER_LEN)) {
360 REDEBUG("Peer sent EAP %s (code %i) ID %d length %zu",
361 eap_codes[eap_msg->vp_octets[0]],
362 eap_msg->vp_octets[0],
363 eap_msg->vp_octets[1],
364 eap_msg->vp_length);
365 return RLM_MODULE_FAIL;
366 }
367
368 /*
369 * The EAP packet header is 4 bytes, plus one byte of EAP sub-type. Short packets are invalid,
370 * and are discarded.
371 */
372 if (eap_msg->vp_length < (EAP_HEADER_LEN + 1)) {
373 RDEBUG2("Ignoring EAP-Message which is too short to be meaningful");
374 return RLM_MODULE_INVALID;
375 }
376
377 /*
378 * We only get EAP RESPONSE from the supplicant.
379 *
380 * LEAP sent requests from the supplicant, but that has been removed for years.
381 */
382 if (eap_msg->vp_octets[0] != FR_EAP_CODE_RESPONSE) {
383 RDEBUG2("Ignoring unexpected EAP code %d", eap_msg->vp_octets[0]);
384 return RLM_MODULE_INVALID;
385 }
386
387 if ((eap_msg->vp_octets[4] == 0) ||
388 (eap_msg->vp_octets[4] == FR_EAP_METHOD_NOTIFICATION)) {
389 RDEBUG2("Ignoring invalid EAP type %d", eap_msg->vp_octets[4]);
390 return RLM_MODULE_INVALID;
391 }
392
393 /*
394 * Create an EAP-Type containing the EAP-type
395 * from the packet.
396 */
398 vp->vp_uint32 = eap_msg->vp_octets[4];
399
400 /*
401 * From now on, we're supposed to be handling the
402 * EAP packet. We better understand it...
403 */
404
405 RDEBUG2("Peer sent EAP %s (code %i) ID %d length %zu Type %d",
406 eap_codes[eap_msg->vp_octets[0]],
407 eap_msg->vp_octets[0],
408 eap_msg->vp_octets[1],
409 eap_msg->vp_length,
410 eap_msg->vp_octets[4]);
411
412 /*
413 * We return ok in response to EAP identity This means we can write:
414 *
415 * eap {
416 * ok = return
417 * }
418 * ldap
419 * sql
420 *
421 * ...in the inner-tunnel, to avoid expensive and unnecessary SQL/LDAP lookups.
422 */
423 if (eap_msg->vp_octets[4] == FR_EAP_METHOD_IDENTITY) {
424 RDEBUG2("Peer sent EAP-Identity. Returning 'ok' so we can short-circuit the rest of authorize");
425 return RLM_MODULE_OK;
426 }
427
428 /*
429 * They're NAKing the EAP type that we proposed.
430 *
431 * NAK is code + id + length[2] + NAK + requested EAP type(s).
432 */
433 if (eap_msg->vp_octets[4] == FR_EAP_METHOD_NAK) {
435
436 /*
437 * Empty NAK means we just fail.
438 */
439 if (eap_msg->vp_length == (EAP_HEADER_LEN + 1)) {
440 RDEBUG2("Received NAK with no proposed EAP types");
441 return RLM_MODULE_FAIL;
442 }
443
444 /*
445 * @todo - walk over the EAP types to be sure that there is at least one which we
446 * support.
447 */
448 type = eap_msg->vp_octets[5];
449
450 /*
451 * Can't NAK,and ask for Invalid, Identity, Notification, or NAK.
452 */
453 if (type < FR_EAP_METHOD_MD5) {
454 RDEBUG2("Ignoring NAK for invalid EAP type %d", type);
455 return RLM_MODULE_FAIL;
456 }
457
458 if (type >= FR_EAP_METHOD_MAX) {
459 RDEBUG2("Ignoring NAK for unknown EAP type %d", type);
460 return rcode_ignore[ignore_unknown_types];
461 }
462
463 if (!methods[type].submodule) {
464 RDEBUG2("Ignoring NAK for unsupported EAP type %d", eap_msg->vp_octets[4]);
465 return rcode_ignore[ignore_unknown_types];
466 }
467
468 /*
469 * Else the NAK is for a method that we support.
470 */
471 return RLM_MODULE_OK;
472 }
473
474 /*
475 * Valid, but something we don't implement at all.
476 */
477 if (eap_msg->vp_octets[4] >= FR_EAP_METHOD_MAX) {
478 RDEBUG2("Ignoring unknown EAP type %d", eap_msg->vp_octets[4]);
479 return rcode_ignore[ignore_unknown_types];
480 }
481
482 /*
483 * Known (potentially), but not currently configured.
484 */
485 if (!methods[eap_msg->vp_octets[4]].submodule) {
486 RDEBUG2("Ignoring unsupported EAP type %d", eap_msg->vp_octets[4]);
487 return rcode_ignore[ignore_unknown_types];
488 }
489
490 /*
491 * Later EAP messages are longer than the 'start'
492 * message, so if everything is OK, this function returns
493 * 'no start found', so that the rest of the EAP code can
494 * use the State attribute to match this EAP-Message to
495 * an ongoing conversation.
496 */
497 RDEBUG2("Continuing on-going EAP conversation");
498
499 return RLM_MODULE_NOTFOUND;
500}
501
503{
505 eap_session->finished = false;
506
507 return eap_compose(eap_session);
508}
509
510/*
511 * compose EAP FAILURE packet in EAP-Message
512 */
514{
515 /*
516 * Delete any previous replies.
517 */
518 fr_pair_delete_by_da(&eap_session->request->reply_pairs, attr_eap_message);
519 fr_pair_delete_by_da(&eap_session->request->reply_pairs, attr_state);
520
521 talloc_free(eap_session->this_round->request);
522 eap_session->this_round->request = talloc_zero(eap_session->this_round, eap_packet_t);
524 eap_session->finished = true;
525
526 return eap_compose(eap_session);
527}
528
529/*
530 * compose EAP SUCCESS packet in EAP-Message
531 */
533{
535 eap_session->finished = true;
536
537 return eap_compose(eap_session);
538}
539
540/*
541 * Allocate a new eap_packet_t
542 */
544{
545 eap_round_t *eap_round;
546
547 eap_round = talloc_zero(eap_session, eap_round_t);
548 if (!eap_round) return NULL;
549
550 eap_round->response = talloc_zero(eap_round, eap_packet_t);
551 if (!eap_round->response) {
552 talloc_free(eap_round);
553 return NULL;
554 }
555 eap_round->request = talloc_zero(eap_round, eap_packet_t);
556 if (!eap_round->request) {
557 talloc_free(eap_round);
558 return NULL;
559 }
560
561 return eap_round;
562}
563
564/*
565 * Create our Request-Response data structure with the eap packet
566 */
568{
569 eap_round_t *eap_round = NULL;
570 int typelen;
571 eap_packet_raw_t *eap_packet = *eap_packet_p;
572 uint16_t len;
573
574 eap_round = eap_round_alloc(eap_session);
575 if (eap_round == NULL) return NULL;
576
577 eap_round->response->packet = (uint8_t *)eap_packet;
578 (void) talloc_steal(eap_round, eap_packet);
579 eap_round->response->code = eap_packet->code;
580 eap_round->response->id = eap_packet->id;
581 eap_round->response->type.num = eap_packet->data[0];
582
583 memcpy(&len, eap_packet->length, sizeof(uint16_t));
584 len = ntohs(len);
585 eap_round->response->length = len;
586
587 /*
588 * We've eaten the eap packet into the eap_round.
589 */
590 *eap_packet_p = NULL;
591
592 /*
593 * First 5 bytes in eap, are code + id + length(2) + type.
594 *
595 * The rest is type-specific data. We skip type while
596 * getting typedata from data.
597 */
598 typelen = len - 5/*code + id + length + type */;
599 if (typelen > 0) {
600 /*
601 * Since the packet contains the complete
602 * eap_packet, typedata will be a ptr in packet
603 * to its typedata
604 */
605 eap_round->response->type.data = eap_round->response->packet + 5/*code+id+length+type*/;
606 eap_round->response->type.length = typelen;
607 } else {
608 eap_round->response->type.length = 0;
609 eap_round->response->type.data = NULL;
610 }
611
612 return eap_round;
613}
#define RCSID(id)
Definition build.h:487
rlm_rcode_t eap_continue(eap_session_t *eap_session)
Definition compose.c:502
static int eap_wireformat(eap_packet_t *reply)
Definition compose.c:89
static const rlm_rcode_t rcode_ignore[2]
Definition compose.c:295
static char const * eap_codes[]
Definition compose.c:67
eap_round_t * eap_round_build(eap_session_t *eap_session, eap_packet_raw_t **eap_packet_p)
Definition compose.c:567
rlm_rcode_t eap_fail(eap_session_t *eap_session)
Definition compose.c:513
rlm_rcode_t eap_start(request_t *request, rlm_eap_method_t const methods[], bool ignore_unknown_types)
Definition compose.c:302
rlm_rcode_t eap_compose(eap_session_t *eap_session)
Definition compose.c:157
static eap_round_t * eap_round_alloc(eap_session_t *eap_session)
Definition compose.c:543
EAP packet composition.
eap_type_data_t type
Definition compose.h:39
uint8_t * packet
Definition compose.h:41
size_t length
Definition compose.h:38
bool set_request_id
Whether the EAP-Method already set the next request ID.
Definition compose.h:51
eap_packet_t * response
Packet we received from the peer.
Definition compose.h:49
eap_code_t code
Definition compose.h:36
uint8_t id
Definition compose.h:37
eap_packet_t * request
Packet we will send to the peer.
Definition compose.h:50
Structure to hold EAP data.
Definition compose.h:35
Contains a pair of request and response packets.
Definition compose.h:48
#define MEM(x)
Definition debug.h:36
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition defs.h:43
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
Definition defs.h:34
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
Definition defs.h:35
uint8_t data[]
Definition types.h:125
@ FR_EAP_CODE_FAILURE
Definition types.h:40
@ FR_EAP_CODE_RESPONSE
Definition types.h:38
@ FR_EAP_CODE_REQUEST
Definition types.h:37
@ FR_EAP_CODE_SUCCESS
Definition types.h:39
eap_type_t num
Definition types.h:110
size_t length
Definition types.h:111
uint8_t code
Definition types.h:122
#define EAP_HEADER_LEN
Definition types.h:34
uint8_t * data
Definition types.h:112
uint8_t length[2]
Definition types.h:124
uint8_t id
Definition types.h:123
@ FR_EAP_METHOD_NAK
Definition types.h:48
@ FR_EAP_METHOD_MD5
Definition types.h:49
@ FR_EAP_METHOD_NOTIFICATION
Definition types.h:47
@ FR_EAP_METHOD_IDENTITY
Definition types.h:46
@ FR_EAP_METHOD_MAX
Definition types.h:102
Structure to represent packet format of eap on wire
Definition types.h:121
talloc_free(hp)
HIDDEN fr_dict_attr_t const * attr_state
Definition base.c:103
HIDDEN fr_dict_attr_t const * attr_eap_message
Definition base.c:96
HIDDEN fr_dict_attr_t const * attr_eap_type
Definition base.c:92
eap_type_t type
EAP method number.
Definition session.h:50
request_t * request
Current request.
Definition session.h:52
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:60
bool finished
Whether we consider this session complete.
Definition session.h:72
Tracks the progress of a single session of any EAP method.
Definition session.h:41
unsigned short uint16_t
unsigned char uint8_t
#define RADIUS_AUTH_VECTOR_LENGTH
Definition net.h:89
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.
Definition pair.c:2946
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.
Definition pair.c:705
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
Definition pair.c:1694
int fr_pair_value_memdup_shallow(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a "octets" type value pair.
Definition pair.c:3001
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
Definition pair.c:2895
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
static fr_dict_attr_t const * attr_message_authenticator
Definition radsnmp.c:114
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:51
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:47
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:53
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:50
#define pair_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
Definition pair.h:37
#define pair_append_reply(_attr, _da)
Allocate and append a fr_pair_t to reply list.
Definition pair.h:47
eap_success
SUCCESS state - State machine exit point after sending EAP-Success.
fr_aka_sim_id_type_t type
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
rlm_eap_submodule_t const * submodule
Submodule's exported interface.
Definition submodule.h:69
Private structure to hold handles and interfaces for an EAP method.
Definition submodule.h:67
#define fr_strerror_const(_msg)
Definition strerror.h:223