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: 04277d15d11d133b2b23e93e636003f953cb75b5 $
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: 04277d15d11d133b2b23e93e636003f953cb75b5 $")
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 < 3) {
104 total_length += 1/* EAP Method */;
105 if (reply->type.data && reply->type.length > 0) {
106 total_length += reply->type.length;
107 }
108 }
109
110 reply->packet = talloc_array(reply, uint8_t, total_length);
111 header = (eap_packet_raw_t *)reply->packet;
112 if (!header) {
113 return -1;
114 }
115
116 header->code = (reply->code & 0xFF);
117 header->id = (reply->id & 0xFF);
118
119 total_length = htons(total_length);
120 memcpy(header->length, &total_length, sizeof(total_length));
121
122 /*
123 * Request and Response packets are special.
124 */
125 if ((reply->code == FR_EAP_CODE_REQUEST) ||
126 (reply->code == FR_EAP_CODE_RESPONSE)) {
127 header->data[0] = (reply->type.num & 0xFF);
128
129 /*
130 * Here since we cannot know the typedata format and length
131 *
132 * Type_data is expected to be wired by each EAP-Type
133 *
134 * Zero length/No typedata is supported as long as
135 * type is defined
136 */
137 if (reply->type.data && reply->type.length > 0) {
138 memcpy(&header->data[1], reply->type.data, reply->type.length);
139 talloc_free(reply->type.data);
140 reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;
141 }
142 }
143
144 return 0;
145}
146
147/*
148 * compose EAP reply packet in EAP-Message attr of RADIUS.
149 *
150 * Set the RADIUS reply codes based on EAP request codes. Append
151 * any additional VPs to RADIUS reply
152 */
154{
155 fr_pair_t *vp;
156 eap_packet_raw_t *eap_packet;
157 request_t *request;
158 eap_round_t *eap_round;
159 eap_packet_t *reply;
160 int rcode;
161
162 eap_session = talloc_get_type_abort(eap_session, eap_session_t);
163 request = talloc_get_type_abort(eap_session->request, request_t);
164 eap_round = talloc_get_type_abort(eap_session->this_round, eap_round_t);
165 reply = talloc_get_type_abort(eap_round->request, eap_packet_t);
166
167 /*
168 * The Id for the EAP packet to the NAS wasn't set.
169 * Do so now.
170 */
171 if (!eap_round->set_request_id) {
172 /*
173 * Id serves to support request/response
174 * retransmission in the EAP layer and as such
175 * must be different for 'adjacent' packets
176 * except in case of success/failure-replies.
177 *
178 * RFC2716 (EAP-TLS) requires this to be
179 * incremented, RFC2284 only makes the above-
180 * mentioned restriction.
181 */
182 reply->id = eap_session->this_round->response->id;
183
184 switch (reply->code) {
185 /*
186 * The Id is a simple "ack" for success
187 * and failure.
188 *
189 * RFC 3748 section 4.2 says
190 *
191 * ... The Identifier field MUST match
192 * the Identifier field of the Response
193 * packet that it is sent in response
194 * to.
195 */
198 break;
199
200 /*
201 * We've sent a response to their
202 * request, the Id is incremented.
203 */
204 default:
205 ++reply->id;
206 }
207 }
208
209 /*
210 * For Request & Response packets, set the EAP sub-type,
211 * if the EAP sub-module didn't already set it.
212 *
213 * This allows the TLS module to be "morphic", and means
214 * that the TTLS and PEAP modules can call it to do most
215 * of their dirty work.
216 */
217 if (((eap_round->request->code == FR_EAP_CODE_REQUEST) ||
218 (eap_round->request->code == FR_EAP_CODE_RESPONSE)) &&
219 (eap_round->request->type.num == 0)) {
220 fr_assert(eap_session->type >= FR_EAP_METHOD_MD5);
221 fr_assert(eap_session->type < FR_EAP_METHOD_MAX);
222
223 eap_round->request->type.num = eap_session->type;
224 }
225
226 if (eap_wireformat(reply) < 0) return RLM_MODULE_INVALID;
227
228 eap_packet = (eap_packet_raw_t *)reply->packet;
229
231 fr_pair_value_memdup_shallow(vp, talloc_steal(vp, reply->packet),
232 eap_packet->length[0] * 256 + eap_packet->length[1], false);
233 reply->packet = NULL;
234
235 /*
236 * EAP-Message is always associated with
237 * Message-Authenticator but not vice-versa.
238 *
239 * Don't add a Message-Authenticator if
240 * it's already there.
241 */
242 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_message_authenticator);
243 if (!vp) {
244 static uint8_t auth_vector[RADIUS_AUTH_VECTOR_LENGTH] = { 0x00 };
245
247 fr_pair_value_memdup(vp, auth_vector, sizeof(auth_vector), false);
248 }
249
250 switch (reply->code) {
252 request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
253 rcode = RLM_MODULE_HANDLED;
254 break;
255
257 request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
258 rcode = RLM_MODULE_OK;
259 break;
260
262 request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
263 rcode = RLM_MODULE_REJECT;
264 break;
265
267 request->reply->code = FR_RADIUS_CODE_ACCESS_CHALLENGE;
268 rcode = RLM_MODULE_HANDLED;
269 break;
270
271 default:
272 /* Should never enter here */
273 REDEBUG("Reply code %u is unknown, rejecting the request", reply->code);
274 request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
275 reply->code = FR_EAP_CODE_FAILURE;
276 rcode = RLM_MODULE_REJECT;
277 break;
278 }
279
280 RDEBUG2("Sending EAP %s (code %d) ID %d length %i",
281 eap_codes[eap_packet->code], eap_packet->code, reply->id,
282 eap_packet->length[0] * 256 + eap_packet->length[1]);
283
284 return rcode;
285}
286
287/*
288 * Radius criteria, EAP-Message is invalid without Message-Authenticator
289 * For EAP_START, send Access-Challenge with EAP Identity request.
290 */
291rlm_rcode_t eap_start(request_t *request, rlm_eap_method_t const methods[], bool ignore_unknown_types)
292{
293 fr_pair_t *vp;
294 fr_pair_t *eap_msg;
295
296 eap_msg = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_message);
297 if (!eap_msg) {
298 RDEBUG2("No EAP-Message, not doing EAP");
299 return RLM_MODULE_NOOP;
300 }
301
302 /*
303 * Look for EAP-Type = None (FreeRADIUS specific attribute)
304 * this allows you to NOT do EAP for some users.
305 */
306 vp = fr_pair_find_by_da(&request->request_pairs, NULL, attr_eap_type);
307 if (vp && vp->vp_uint32 == 0) {
308 RDEBUG2("Found EAP-Message, but EAP-Type = None, so we're not doing EAP");
309 return RLM_MODULE_NOOP;
310 }
311
312 /*
313 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
314 *
315 * Checks for Message-Authenticator are handled by fr_packet_recv().
316 */
317
318 /*
319 * Check the length before de-referencing the contents.
320 *
321 * Lengths of zero are required by the RFC for EAP-Start,
322 * but we've never seen them in practice.
323 *
324 * Lengths of two are what we see in practice as
325 * EAP-Starts.
326 */
327 if ((eap_msg->vp_length == 0) || (eap_msg->vp_length == 2)) {
328 uint8_t *p;
329
330 RDEBUG2("Got EAP_START message");
331
333
334 /*
335 * Manually create an EAP Identity request
336 */
337 MEM(fr_pair_value_mem_alloc(vp, &p, 5, false) == 0);
338 p[0] = FR_EAP_CODE_REQUEST;
339 p[1] = 0; /* ID */
340 p[2] = 0;
341 p[3] = 5; /* length */
343
344 return RLM_MODULE_HANDLED;
345 } /* end of handling EAP-Start */
346
347 /*
348 * Supplicants don't usually send EAP-Failures to the
349 * server, but they're not forbidden from doing so.
350 * This behaviour was observed with a Spirent Avalanche test server.
351 */
352 if ((eap_msg->vp_length == EAP_HEADER_LEN) && (eap_msg->vp_octets[0] == FR_EAP_CODE_FAILURE)) {
353 REDEBUG("Peer sent EAP %s (code %i) ID %d length %zu",
354 eap_codes[eap_msg->vp_octets[0]],
355 eap_msg->vp_octets[0],
356 eap_msg->vp_octets[1],
357 eap_msg->vp_length);
358 return RLM_MODULE_FAIL;
359 /*
360 * The EAP packet header is 4 bytes, plus one byte of
361 * EAP sub-type. Short packets are discarded.
362 */
363 } else if (eap_msg->vp_length < (EAP_HEADER_LEN + 1)) {
364 RDEBUG2("Ignoring EAP-Message which is too short to be meaningful");
365 return RLM_MODULE_FAIL;
366 }
367
368 /*
369 * Create an EAP-Type containing the EAP-type
370 * from the packet.
371 */
373 vp->vp_uint32 = eap_msg->vp_octets[4];
374
375 /*
376 * From now on, we're supposed to be handling the
377 * EAP packet. We better understand it...
378 */
379
380 /*
381 * We're allowed only a few codes. Request, Response,
382 * Success, or Failure.
383 */
384 if ((eap_msg->vp_octets[0] == 0) ||
385 (eap_msg->vp_octets[0] >= FR_EAP_CODE_MAX)) {
386 RDEBUG2("Peer sent EAP packet with unknown code %i", eap_msg->vp_octets[0]);
387 } else {
388 RDEBUG2("Peer sent EAP %s (code %i) ID %d length %zu",
389 eap_codes[eap_msg->vp_octets[0]],
390 eap_msg->vp_octets[0],
391 eap_msg->vp_octets[1],
392 eap_msg->vp_length);
393 }
394
395 /*
396 * We handle request and responses. The only other defined
397 * codes are success and fail. The client SHOULD NOT be
398 * sending success/fail packets to us, as it doesn't make
399 * sense.
400 */
401 if ((eap_msg->vp_octets[0] != FR_EAP_CODE_REQUEST) &&
402 (eap_msg->vp_octets[0] != FR_EAP_CODE_RESPONSE)) {
403 RDEBUG2("Ignoring EAP packet which we don't know how to handle");
404 return RLM_MODULE_FAIL;
405 }
406
407 /*
408 * We've been told to ignore unknown EAP types, AND it's
409 * an unknown type. Return "NOOP", which will cause the
410 * mod_authorize() to return NOOP.
411 *
412 * EAP-Identity, Notification, and NAK are all handled
413 * internally, so they never have eap_sessions.
414 */
415 if ((eap_msg->vp_octets[4] >= FR_EAP_METHOD_MD5) &&
416 ignore_unknown_types &&
417 ((eap_msg->vp_octets[4] == 0) ||
418 (eap_msg->vp_octets[4] >= FR_EAP_METHOD_MAX) ||
419 (!methods[eap_msg->vp_octets[4]].submodule))) {
420 RDEBUG2("Ignoring Unknown EAP type");
421 return RLM_MODULE_NOOP;
422 }
423
424 /*
425 * They're NAKing the EAP type we wanted to use, and
426 * asking for one which we don't support.
427 *
428 * NAK is code + id + length1 + length + NAK
429 * + requested EAP type(s).
430 *
431 * We know at this point that we can't handle the
432 * request. We could either return an EAP-Fail here, but
433 * it's not too critical.
434 *
435 * By returning "noop", we can ensure that authorize()
436 * returns NOOP, and another module may choose to proxy
437 * the request.
438 */
439 if ((eap_msg->vp_octets[4] == FR_EAP_METHOD_NAK) &&
440 (eap_msg->vp_length >= (EAP_HEADER_LEN + 2)) &&
441 ignore_unknown_types &&
442 ((eap_msg->vp_octets[5] == 0) ||
443 (eap_msg->vp_octets[5] >= FR_EAP_METHOD_MAX) ||
444 (!methods[eap_msg->vp_octets[5]].submodule))) {
445 RDEBUG2("Ignoring NAK with request for unknown EAP type");
446 return RLM_MODULE_NOOP;
447 }
448
449 if ((eap_msg->vp_octets[4] == FR_EAP_METHOD_TTLS) ||
450 (eap_msg->vp_octets[4] == FR_EAP_METHOD_PEAP)) {
451 RDEBUG2("Continuing tunnel setup");
452 return RLM_MODULE_OK;
453 }
454 /*
455 * We return ok in response to EAP identity
456 * This means we can write:
457 *
458 * eap {
459 * ok = return
460 * }
461 * ldap
462 * sql
463 *
464 * ...in the inner-tunnel, to avoid expensive and unnecessary SQL/LDAP lookups
465 */
466 if (eap_msg->vp_octets[4] == FR_EAP_METHOD_IDENTITY) {
467 RDEBUG2("Peer sent EAP-Identity. Returning 'ok' so we can short-circuit the rest of authorize");
468 return RLM_MODULE_OK;
469 }
470
471 /*
472 * Later EAP messages are longer than the 'start'
473 * message, so if everything is OK, this function returns
474 * 'no start found', so that the rest of the EAP code can
475 * use the State attribute to match this EAP-Message to
476 * an ongoing conversation.
477 */
478 RDEBUG2("Continuing on-going EAP conversation");
479
480 return RLM_MODULE_NOTFOUND;
481}
482
484{
486 eap_session->finished = false;
487
488 return eap_compose(eap_session);
489}
490
491/*
492 * compose EAP FAILURE packet in EAP-Message
493 */
495{
496 /*
497 * Delete any previous replies.
498 */
499 fr_pair_delete_by_da(&eap_session->request->reply_pairs, attr_eap_message);
500 fr_pair_delete_by_da(&eap_session->request->reply_pairs, attr_state);
501
502 talloc_free(eap_session->this_round->request);
503 eap_session->this_round->request = talloc_zero(eap_session->this_round, eap_packet_t);
505 eap_session->finished = true;
506
507 return eap_compose(eap_session);
508}
509
510/*
511 * compose EAP SUCCESS packet in EAP-Message
512 */
514{
516 eap_session->finished = true;
517
518 return eap_compose(eap_session);
519}
520
521/*
522 * Allocate a new eap_packet_t
523 */
525{
526 eap_round_t *eap_round;
527
528 eap_round = talloc_zero(eap_session, eap_round_t);
529 if (!eap_round) return NULL;
530
531 eap_round->response = talloc_zero(eap_round, eap_packet_t);
532 if (!eap_round->response) {
533 talloc_free(eap_round);
534 return NULL;
535 }
536 eap_round->request = talloc_zero(eap_round, eap_packet_t);
537 if (!eap_round->request) {
538 talloc_free(eap_round);
539 return NULL;
540 }
541
542 return eap_round;
543}
544
545/*
546 * Create our Request-Response data structure with the eap packet
547 */
549{
550 eap_round_t *eap_round = NULL;
551 int typelen;
552 eap_packet_raw_t *eap_packet = *eap_packet_p;
553 uint16_t len;
554
555 eap_round = eap_round_alloc(eap_session);
556 if (eap_round == NULL) return NULL;
557
558 eap_round->response->packet = (uint8_t *)eap_packet;
559 (void) talloc_steal(eap_round, eap_packet);
560 eap_round->response->code = eap_packet->code;
561 eap_round->response->id = eap_packet->id;
562 eap_round->response->type.num = eap_packet->data[0];
563
564 memcpy(&len, eap_packet->length, sizeof(uint16_t));
565 len = ntohs(len);
566 eap_round->response->length = len;
567
568 /*
569 * We've eaten the eap packet into the eap_round.
570 */
571 *eap_packet_p = NULL;
572
573 /*
574 * First 5 bytes in eap, are code + id + length(2) + type.
575 *
576 * The rest is type-specific data. We skip type while
577 * getting typedata from data.
578 */
579 typelen = len - 5/*code + id + length + type */;
580 if (typelen > 0) {
581 /*
582 * Since the packet contains the complete
583 * eap_packet, typedata will be a ptr in packet
584 * to its typedata
585 */
586 eap_round->response->type.data = eap_round->response->packet + 5/*code+id+length+type*/;
587 eap_round->response->type.length = typelen;
588 } else {
589 eap_round->response->type.length = 0;
590 eap_round->response->type.data = NULL;
591 }
592
593 return eap_round;
594}
#define RCSID(id)
Definition build.h:483
rlm_rcode_t eap_continue(eap_session_t *eap_session)
Definition compose.c:483
static int eap_wireformat(eap_packet_t *reply)
Definition compose.c:89
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:548
rlm_rcode_t eap_fail(eap_session_t *eap_session)
Definition compose.c:494
rlm_rcode_t eap_start(request_t *request, rlm_eap_method_t const methods[], bool ignore_unknown_types)
Definition compose.c:291
rlm_rcode_t eap_compose(eap_session_t *eap_session)
Definition compose.c:153
static eap_round_t * eap_round_alloc(eap_session_t *eap_session)
Definition compose.c:524
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
@ 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_MAX
Definition types.h:41
@ FR_EAP_CODE_SUCCESS
Definition types.h:39
eap_type_t num
Definition types.h:110
uint8_t data[1]
Definition types.h:125
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_TTLS
Definition types.h:66
@ FR_EAP_METHOD_MD5
Definition types.h:49
@ FR_EAP_METHOD_IDENTITY
Definition types.h:46
@ FR_EAP_METHOD_PEAP
Definition types.h:70
@ FR_EAP_METHOD_MAX
Definition types.h:102
Structure to represent packet format of eap on wire
Definition types.h:121
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:49
request_t * request
Current request.
Definition session.h:51
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:59
bool finished
Whether we consider this session complete.
Definition session.h:71
Tracks the progress of a single session of any EAP method.
Definition session.h:40
talloc_free(reap)
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:2981
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:693
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:1689
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:3036
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:2930
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
static fr_dict_attr_t const * attr_message_authenticator
Definition radsnmp.c:112
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:47
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
#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_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