The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
peap.c
Go to the documentation of this file.
1/*
2 * peap.c contains the interfaces that are called from eap
3 *
4 * Version: $Id: e5f6ed03242fd2239a4e62d98e7226757f98b3c3 $
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 2003 Alan DeKok (aland@freeradius.org)
21 * @copyright 2006 The FreeRADIUS server project
22 */
23
24RCSID("$Id: e5f6ed03242fd2239a4e62d98e7226757f98b3c3 $")
25USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
26
27#include <freeradius-devel/radius/radius.h>
28#include <freeradius-devel/radius/defs.h>
29
30#include "eap_peap.h"
31
32/*
33 * Send protected EAP-Failure
34 *
35 * Result-TLV = Failure
36 */
37static int eap_peap_failure(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
38{
39 uint8_t tlv_packet[11];
40
41 RDEBUG2("FAILURE");
42
43 tlv_packet[0] = FR_EAP_CODE_REQUEST;
44 tlv_packet[1] = eap_session->this_round->response->id +1;
45 tlv_packet[2] = 0;
46 tlv_packet[3] = 11; /* length of this packet */
47 tlv_packet[4] = FR_PEAP_EXTENSIONS_TYPE;
48 tlv_packet[5] = 0x80;
49 tlv_packet[6] = EAP_TLV_ACK_RESULT;
50 tlv_packet[7] = 0;
51 tlv_packet[8] = 2; /* length of the data portion */
52 tlv_packet[9] = 0;
53 tlv_packet[10] = EAP_TLV_FAILURE;
54
55 (tls_session->record_from_buff)(&tls_session->clean_in, tlv_packet, 11);
56
57 /*
58 * FIXME: Check the return code.
59 */
60 fr_tls_session_send(request, tls_session);
61
62 return 1;
63}
64
65
66/*
67 * Send protected EAP-Success
68 *
69 * Result-TLV = Success
70 */
71static int eap_peap_success(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
72{
73 uint8_t tlv_packet[11];
74
75 RDEBUG2("SUCCESS");
76
77 tlv_packet[0] = FR_EAP_CODE_REQUEST;
78 tlv_packet[1] = eap_session->this_round->response->id +1;
79 tlv_packet[2] = 0;
80 tlv_packet[3] = 11; /* length of this packet */
81 tlv_packet[4] = FR_PEAP_EXTENSIONS_TYPE;
82 tlv_packet[5] = 0x80; /* mandatory AVP */
83 tlv_packet[6] = EAP_TLV_ACK_RESULT;
84 tlv_packet[7] = 0;
85 tlv_packet[8] = 2; /* length of the data portion */
86 tlv_packet[9] = 0;
87 tlv_packet[10] = EAP_TLV_SUCCESS;
88
89 (tls_session->record_from_buff)(&tls_session->clean_in, tlv_packet, 11);
90
91 /*
92 * FIXME: Check the return code.
93 */
94 fr_tls_session_send(request, tls_session);
95
96 return 1;
97}
98
99
100static int eap_peap_identity(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
101{
102 eap_packet_raw_t eap_packet;
103
104 eap_packet.code = FR_EAP_CODE_REQUEST;
105 eap_packet.id = eap_session->this_round->response->id + 1;
106 eap_packet.length[0] = 0;
107 eap_packet.length[1] = EAP_HEADER_LEN + 1;
108 eap_packet.data[0] = FR_EAP_METHOD_IDENTITY;
109
110 (tls_session->record_from_buff)(&tls_session->clean_in, &eap_packet, sizeof(eap_packet));
111 fr_tls_session_send(request, tls_session);
112 (tls_session->record_init)(&tls_session->clean_in);
113
114 return 1;
115}
116
117/*
118 * Verify the tunneled EAP message.
119 */
120static int eap_peap_verify(request_t *request, peap_tunnel_t *peap_tunnel,
121 uint8_t const *data, size_t data_len)
122{
123 eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data;
124 eap_type_t eap_method;
125
126 /*
127 * No data, OR only 1 byte of EAP type.
128 */
129 if (!data || (data_len == 0) || ((data_len <= 1) && (data[0] != FR_EAP_METHOD_IDENTITY))) return 0;
130
131 /*
132 * Since the full EAP header is sent for the EAP Extensions type (Type 33),
133 * but not for other Types, it is difficult for the implementation to distinguish
134 * an Extensions Request (Code 1) from an EAP Type 1 (Identity) Request packet.
135 *
136 * i.e. The only way to validate PEAP inner method packets properly is to know
137 * we just send a protected success/failure.
138 */
139 switch (peap_tunnel->status) {
142 if (eap_packet->data[0] != FR_PEAP_EXTENSIONS_TYPE) {
143 REDEBUG("Invalid inner tunnel data, expected method (%u), got (%u)",
144 FR_PEAP_EXTENSIONS_TYPE, eap_packet->data[0]);
145 return -1;
146 }
147 return 0;
148
149 default:
150 break;
151 }
152
153 eap_method = data[0]; /* Inner EAP header misses off code and identifier */
154 switch (eap_method) {
156 RDEBUG2("Received EAP-Identity-Response");
157 return 0;
158
159 /*
160 * We normally do Microsoft MS-CHAPv2 (26), versus
161 * Cisco MS-CHAPv2 (29).
162 */
164 default:
165 RDEBUG2("EAP method %s (%d)", eap_type2name(eap_method), eap_method);
166 return 0;
167 }
168
169}
170
171/*
172 * Convert a pseudo-EAP packet to a list of fr_pair_t's.
173 */
174static void eap_peap_inner_to_pairs(TALLOC_CTX *ctx, fr_pair_list_t *pairs,
175 eap_round_t *eap_round,
176 uint8_t const *data, size_t data_len)
177{
178 size_t total;
179 uint8_t *p;
180 fr_pair_t *vp = NULL;
181
182 if (data_len > 65535) return; /* paranoia */
183
185 total = data_len;
186 if (total > 249) total = 249;
187
188 /*
189 * Hand-build an EAP packet from the crap in PEAP version 0.
190 */
191 MEM(fr_pair_value_mem_alloc(vp, &p, EAP_HEADER_LEN + total, false) == 0);
193 p[1] = eap_round->response->id;
194 p[2] = (data_len + EAP_HEADER_LEN) >> 8;
195 p[3] = (data_len + EAP_HEADER_LEN) & 0xff;
196 memcpy(p + EAP_HEADER_LEN, data, total);
197
198 fr_pair_append(pairs, vp);
199 while (total < data_len) {
201 fr_pair_value_memdup(vp, data + total, (data_len - total), false);
202
203 total += vp->vp_length;
204
205 fr_pair_append(pairs, vp);
206 }
207}
208
209
210/*
211 * Convert a list of fr_pair_t's to an EAP packet, through the
212 * simple expedient of dumping the EAP message
213 */
214static int eap_peap_inner_from_pairs(request_t *request, fr_tls_session_t *tls_session, fr_pair_list_t *vps)
215{
216 fr_pair_t *this;
217
219
220 /*
221 * Send the EAP data in the first attribute, WITHOUT the
222 * header.
223 */
224 this = fr_pair_list_head(vps);
225 (tls_session->record_from_buff)(&tls_session->clean_in, this->vp_octets + EAP_HEADER_LEN,
226 this->vp_length - EAP_HEADER_LEN);
227
228 /*
229 * Send the rest of the EAP data, but skipping the first VP.
230 */
231 for (this = fr_pair_list_next(vps, this);
232 this;
233 this = fr_pair_list_next(vps, this)) {
234 (tls_session->record_from_buff)(&tls_session->clean_in, this->vp_octets, this->vp_length);
235 }
236
237 fr_tls_session_send(request, tls_session);
238
239 return 1;
240}
241
242
243/*
244 * See if there's a TLV in the response.
245 */
246static int eap_peap_check_tlv(request_t *request, uint8_t const *data, size_t data_len)
247{
248 eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data;
249
250 if (data_len < 11) return 0;
251
252 /*
253 * Look for success or failure.
254 */
255 if ((eap_packet->code == FR_EAP_CODE_RESPONSE) &&
256 (eap_packet->data[0] == FR_PEAP_EXTENSIONS_TYPE)) {
257 if (data[10] == EAP_TLV_SUCCESS) {
258 return 1;
259 }
260
261 if (data[10] == EAP_TLV_FAILURE) {
262 RDEBUG2("Client rejected our response. The password is probably incorrect");
263 return 0;
264 }
265 }
266
267 RDEBUG2("Unknown TLV %02x", data[10]);
268
269 return 0;
270}
271
272
273/*
274 * Use a reply packet to determine what to do.
275 */
276static unlang_action_t process_reply(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
277{
278 eap_session_t *eap_session = talloc_get_type_abort(uctx, eap_session_t);
279 eap_tls_session_t *eap_tls_session = talloc_get_type_abort(eap_session->opaque, eap_tls_session_t);
280 fr_tls_session_t *tls_session = eap_tls_session->tls_session;
281 fr_pair_list_t vps;
282 peap_tunnel_t *t = tls_session->opaque;
283 request_t *parent = request->parent;
284 fr_packet_t *reply = request->reply;
285
286 if (RDEBUG_ENABLED2) {
287
288 /*
289 * Note that we don't do *anything* with the reply
290 * attributes.
291 */
292 if (FR_RADIUS_PACKET_CODE_VALID(reply->code)) {
293 RDEBUG2("Got tunneled reply %s", fr_radius_packet_name[reply->code]);
294 } else {
295 RDEBUG2("Got tunneled reply code %i", reply->code);
296 }
297 log_request_pair_list(L_DBG_LVL_2, request, NULL, &request->reply_pairs, NULL);
298 }
299
300 switch (reply->code) {
302 RDEBUG2("Tunneled authentication was successful");
304 eap_peap_success(request, eap_session, tls_session);
306
308 RDEBUG2("Tunneled authentication was rejected");
310 eap_peap_failure(request, eap_session, tls_session);
312
314 RDEBUG2("Got tunneled Access-Challenge");
315
316 /*
317 * PEAP takes only EAP-Message attributes inside
318 * of the tunnel. Any Reply-Message in the
319 * Access-Challenge is ignored.
320 */
321 fr_pair_list_init(&vps);
322 MEM(fr_pair_list_copy_by_da(t, &vps, &request->reply_pairs, attr_eap_message, 0) >= 0);
323
324 /*
325 * Handle the ACK, by tunneling any necessary reply
326 * VP's back to the client.
327 */
328 if (!fr_pair_list_empty(&vps)) {
329 eap_peap_inner_from_pairs(parent, tls_session, &vps);
330 fr_pair_list_free(&vps);
331 }
332
334
335 default:
336 RDEBUG2("Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);
338 }
339}
340
341
342static char const *peap_state(peap_tunnel_t *t)
343{
344 switch (t->status) {
346 return "TUNNEL ESTABLISHED";
347
349 return "WAITING FOR INNER IDENTITY";
350
352 return "send tlv success";
353
355 return "send tlv failure";
356
358 return "phase2_init";
359
361 return "phase2";
362
363 default:
364 break;
365 }
366 return "?";
367}
368
369/*
370 * Process the pseudo-EAP contents of the tunneled data.
371 */
373 eap_session_t *eap_session, fr_tls_session_t *tls_session)
374{
375 peap_tunnel_t *t = tls_session->opaque;
376 request_t *child = NULL;
377 fr_pair_t *vp;
379 uint8_t const *data;
380 size_t data_len;
381 eap_round_t *eap_round = eap_session->this_round;
382
383 /*
384 * Just look at the buffer directly, without doing
385 * record_to_buff. This lets us avoid another data copy.
386 */
387 data_len = tls_session->clean_out.used;
388 tls_session->clean_out.used = 0;
389 data = tls_session->clean_out.data;
390
391 RDEBUG2("PEAP state %s", peap_state(t));
392
393 if ((t->status != PEAP_STATUS_TUNNEL_ESTABLISHED) && (eap_peap_verify(request, t, data, data_len) < 0)) {
394 REDEBUG("Tunneled data is invalid");
396 }
397
398 switch (t->status) {
400 /* FIXME: should be no data in the buffer here, check & assert? */
401
402 if (SSL_session_reused(tls_session->ssl)) {
403 RDEBUG2("Skipping Phase2 because of session resumption");
405 /* we're good, send success TLV */
407 eap_peap_success(request, eap_session, tls_session);
408
409 } else {
410 /* send an identity request */
413 eap_peap_identity(request, eap_session, tls_session);
414 }
415 rcode = RLM_MODULE_HANDLED;
416 goto finish;
417
419 /* we're expecting an identity response */
420 if (data[0] != FR_EAP_METHOD_IDENTITY) {
421 REDEBUG("Expected EAP-Identity, got something else");
422 rcode = RLM_MODULE_REJECT;
423 goto finish;
424 }
425
426 /*
427 * Save it for later.
428 */
430 t->username->vp_tainted = true;
431
432 fr_pair_value_bstrndup(t->username, (char const *)data + 1, data_len - 1, true);
433
434 RDEBUG2("Got inner identity \"%pV\"", &t->username->data);
436 break;
437
438 /*
439 * If we authenticated the user, then it's OK.
440 */
442 if (eap_peap_check_tlv(request, data, data_len)) {
443 RDEBUG2("Success");
444 rcode = RLM_MODULE_OK;
445 goto finish;
446 }
447
448 /*
449 * Otherwise, the client rejected the session
450 * resumption. If the session is being re-used,
451 * we need to do a full authentication.
452 *
453 * We do this by sending an EAP-Identity request
454 * inside of the PEAP tunnel.
455 */
457 RDEBUG2("Client rejected session resumption. Re-starting full authentication");
458
459 /*
460 * Mark session resumption status.
461 */
464
465 eap_peap_identity(request, eap_session, tls_session);
466 rcode = RLM_MODULE_HANDLED;
467 goto finish;
468 }
469
470 REDEBUG("Sent a success, but received something weird in return");
471 rcode = RLM_MODULE_REJECT;
472 goto finish;
473
474 /*
475 * Supplicant ACKs our failure.
476 */
478 RINDENT();
479 REDEBUG("The users session was previously rejected: returning reject (again.)");
480 RIDEBUG("This means you need to read the PREVIOUS messages in the debug output");
481 RIDEBUG("to find out the reason why the user was rejected");
482 RIDEBUG("Look for \"reject\" or \"fail\". Those earlier messages will tell you");
483 RIDEBUG("what went wrong, and how to fix the problem");
484 REXDENT();
485
487
489 RDEBUG2("In state machine in phase2 init?");
490 break;
491
493 break;
494
495 default:
496 REDEBUG("Unhandled state in peap");
497 rcode = RLM_MODULE_REJECT;
498 goto finish;
499 }
500
501 MEM(child = unlang_subrequest_alloc(request, request->dict));
502 fr_assert(fr_pair_list_empty(&child->request_pairs));
503
504 switch (t->status) {
505 /*
506 * If we're in PHASE2_INIT, the phase2 method hasn't been
507 * sent an Identity packet yet; do so from the stored
508 * username and this will kick off the phase2 eap method
509 */
511 {
512 size_t len;
513 uint8_t *q;
514
516
517 len = t->username->vp_length + EAP_HEADER_LEN + 1;
519
520 MEM(vp = fr_pair_afrom_da(child->request_ctx, attr_eap_message));
521 MEM(fr_pair_value_mem_alloc(vp, &q, len, false) == 0);
523 q[1] = eap_round->response->id;
524 q[2] = (len >> 8) & 0xff;
525 q[3] = len & 0xff;
527 memcpy(q + EAP_HEADER_LEN + 1,
528 t->username->vp_strvalue, t->username->vp_length);
529 fr_pair_append(&child->request_pairs, vp);
530 }
531 break;
532
534 eap_peap_inner_to_pairs(child->request_ctx, &child->request_pairs,
535 eap_round, data, data_len);
536 if (fr_pair_list_empty(&child->request_pairs)) {
537 talloc_free(child);
538 RDEBUG2("Unable to convert tunneled EAP packet to internal server data structures");
539 rcode = RLM_MODULE_REJECT;
540 goto finish;
541 }
542 break;
543
544 default:
545 REDEBUG("Invalid state change in PEAP");
546 rcode = RLM_MODULE_REJECT;
547 goto finish;
548 }
549
550 RDEBUG2("Got tunneled request");
551 log_request_pair_list(L_DBG_LVL_2, request, NULL, &child->request_pairs, NULL);
552
553 /*
554 * Update other items in the request_t data structure.
555 */
556 if (!t->username) {
557 /*
558 * There's no User-Name in the tunneled session,
559 * so we add one here, by pulling it out of the
560 * EAP-Identity packet.
561 */
562 if ((data[0] == FR_EAP_METHOD_IDENTITY) && (data_len > 1)) {
564 fr_assert(t->username != NULL);
565 t->username->vp_tainted = true;
566
567 fr_pair_value_bstrndup(t->username, (char const *)data + 1, data_len - 1, true);
568
569 RDEBUG2("Got tunneled identity of %pV", &t->username->data);
570 }
571 } /* else there WAS a t->username */
572
573 if (t->username) {
574 vp = fr_pair_copy(child->request_ctx, t->username);
575 fr_pair_append(&child->request_pairs, vp);
576 RDEBUG2("Setting &request.User-Name from tunneled (inner) identity \"%s\"",
577 vp->vp_strvalue);
578 } else {
579 RDEBUG2("No tunnel username (SSL resumption?)");
580 }
581
582 if (unlang_subrequest_child_push(&eap_session->submodule_rcode, child,
583 &(unlang_subrequest_session_t){ .enable = true, .unique_ptr = child },
584 false, UNLANG_SUB_FRAME) < 0) goto finish;
585 if (unlang_function_push(child, NULL, process_reply, NULL, 0,
586 UNLANG_SUB_FRAME, eap_session) != UNLANG_ACTION_PUSHED_CHILD) goto finish;
587
588 /*
589 * Call authentication recursively, which will
590 * do PAP, CHAP, MS-CHAP, etc.
591 */
592 return eap_virtual_server(child, eap_session, t->server_cs);
593
594finish:
595 if (child) request_detach(child);
596
597 RETURN_MODULE_RCODE(rcode);
598}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
Definition action.h:39
#define USES_APPLE_DEPRECATED_API
Definition build.h:470
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
eap_packet_t * response
Packet we received from the peer.
Definition compose.h:49
uint8_t id
Definition compose.h:37
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
char const * eap_type2name(eap_type_t method)
Return an EAP-name for a particular type.
Definition types.c:54
@ FR_EAP_CODE_RESPONSE
Definition types.h:38
@ FR_EAP_CODE_REQUEST
Definition types.h:37
uint8_t data[1]
Definition types.h:125
enum eap_type eap_type_t
uint8_t code
Definition types.h:122
#define EAP_HEADER_LEN
Definition types.h:34
uint8_t length[2]
Definition types.h:124
uint8_t id
Definition types.h:123
@ FR_EAP_METHOD_MSCHAPV2
Definition types.h:71
@ FR_EAP_METHOD_IDENTITY
Definition types.h:46
Structure to represent packet format of eap on wire
Definition types.h:121
#define EAP_TLV_FAILURE
Definition eap_peap.h:61
@ PEAP_STATUS_PHASE2_INIT
Definition eap_peap.h:34
@ PEAP_STATUS_TUNNEL_ESTABLISHED
Definition eap_peap.h:32
@ PEAP_STATUS_PHASE2
Definition eap_peap.h:35
@ PEAP_STATUS_INNER_IDENTITY_REQ_SENT
Definition eap_peap.h:33
@ PEAP_STATUS_SENT_TLV_SUCCESS
Definition eap_peap.h:30
@ PEAP_STATUS_SENT_TLV_FAILURE
Definition eap_peap.h:31
@ PEAP_RESUMPTION_YES
Definition eap_peap.h:40
@ PEAP_RESUMPTION_NO
Definition eap_peap.h:39
#define FR_PEAP_EXTENSIONS_TYPE
Definition eap_peap.h:64
peap_status status
Definition eap_peap.h:46
peap_resumption session_resumption_state
Definition eap_peap.h:50
#define EAP_TLV_SUCCESS
Definition eap_peap.h:60
CONF_SECTION * server_cs
Definition eap_peap.h:49
fr_pair_t * username
Definition eap_peap.h:45
#define EAP_TLV_ACK_RESULT
Definition eap_peap.h:62
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:111
#define UNLANG_SUB_FRAME
Definition interpret.h:36
HIDDEN fr_dict_attr_t const * attr_eap_message
Definition base.c:96
unlang_action_t eap_virtual_server(request_t *request, eap_session_t *eap_session, CONF_SECTION *server_cs)
Run a subrequest through a virtual server.
Definition base.c:427
void * opaque
Opaque data used by EAP methods.
Definition session.h:62
rlm_rcode_t submodule_rcode
Result of last submodule call.
Definition session.h:46
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:59
Tracks the progress of a single session of any EAP method.
Definition session.h:40
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.
Definition log.c:830
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:443
#define RINDENT()
Indent R* messages by one level.
Definition log.h:430
talloc_free(reap)
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
Definition log.h:71
unsigned char uint8_t
int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count)
Duplicate pairs in a list matching the specified da.
Definition pair.c:2406
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
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1345
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.
Definition pair.c:283
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
Definition pair.c:2784
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:489
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
static USES_APPLE_DEPRECATED_API int eap_peap_failure(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition peap.c:37
static unlang_action_t process_reply(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Definition peap.c:276
static int eap_peap_success(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition peap.c:71
static int eap_peap_identity(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition peap.c:100
static int eap_peap_check_tlv(request_t *request, uint8_t const *data, size_t data_len)
Definition peap.c:246
static void eap_peap_inner_to_pairs(TALLOC_CTX *ctx, fr_pair_list_t *pairs, eap_round_t *eap_round, uint8_t const *data, size_t data_len)
Definition peap.c:174
static int eap_peap_inner_from_pairs(request_t *request, fr_tls_session_t *tls_session, fr_pair_list_t *vps)
Definition peap.c:214
static char const * peap_state(peap_tunnel_t *t)
Definition peap.c:342
unlang_action_t eap_peap_process(rlm_rcode_t *p_result, request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition peap.c:372
static int eap_peap_verify(request_t *request, peap_tunnel_t *peap_tunnel, uint8_t const *data, size_t data_len)
Definition peap.c:120
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Definition base.c:112
#define fr_assert(_expr)
Definition rad_assert.h:38
static fr_dict_attr_t const * attr_user_name
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG_ENABLED2()
Definition radclient.h:50
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define FR_RADIUS_PACKET_CODE_VALID(_x)
Definition radius.h:52
#define RIDEBUG(fmt,...)
Definition radsniff.h:65
#define RETURN_MODULE_REJECT
Definition rcode.h:55
#define RETURN_MODULE_RCODE(_rcode)
Definition rcode.h:64
#define RETURN_MODULE_HANDLED
Definition rcode.h:58
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:41
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
int request_detach(request_t *child)
Unlink a subrequest from its parent.
Definition request.c:668
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
request_t * unlang_subrequest_alloc(request_t *parent, fr_dict_t const *namespace)
Allocate a subrequest to run through a virtual server at some point in the future.
Definition subrequest.c:287
int unlang_subrequest_child_push(rlm_rcode_t *out, request_t *child, unlang_subrequest_session_t const *session, bool free_child, bool top_frame)
Push a pre-existing child back onto the stack as a subrequest.
fr_tls_session_t * tls_session
TLS session used to authenticate peer or tunnel sensitive data.
Definition tls.h:129
Tracks the state of an EAP-TLS session.
Definition tls.h:126
unsigned int code
Packet code (type).
Definition packet.h:61
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition pair_inline.c:70
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:43
static fr_slen_t parent
Definition pair.h:851
static fr_slen_t data
Definition value.h:1265