The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 02eecbca33fd5b9d307addcecbeb5b1d5be2b00f $
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 
24 RCSID("$Id: 02eecbca33fd5b9d307addcecbeb5b1d5be2b00f $")
25 USES_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 static int setup_fake_request(request_t *request, request_t *fake, peap_tunnel_t *t);
33 
34 /*
35  * Send protected EAP-Failure
36  *
37  * Result-TLV = Failure
38  */
39 static int eap_peap_failure(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
40 {
41  uint8_t tlv_packet[11];
42 
43  RDEBUG2("FAILURE");
44 
45  tlv_packet[0] = FR_EAP_CODE_REQUEST;
46  tlv_packet[1] = eap_session->this_round->response->id +1;
47  tlv_packet[2] = 0;
48  tlv_packet[3] = 11; /* length of this packet */
49  tlv_packet[4] = FR_PEAP_EXTENSIONS_TYPE;
50  tlv_packet[5] = 0x80;
51  tlv_packet[6] = EAP_TLV_ACK_RESULT;
52  tlv_packet[7] = 0;
53  tlv_packet[8] = 2; /* length of the data portion */
54  tlv_packet[9] = 0;
55  tlv_packet[10] = EAP_TLV_FAILURE;
56 
57  (tls_session->record_from_buff)(&tls_session->clean_in, tlv_packet, 11);
58 
59  /*
60  * FIXME: Check the return code.
61  */
62  fr_tls_session_send(request, tls_session);
63 
64  return 1;
65 }
66 
67 
68 /*
69  * Send protected EAP-Success
70  *
71  * Result-TLV = Success
72  */
73 static int eap_peap_success(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
74 {
75  uint8_t tlv_packet[11];
76 
77  RDEBUG2("SUCCESS");
78 
79  tlv_packet[0] = FR_EAP_CODE_REQUEST;
80  tlv_packet[1] = eap_session->this_round->response->id +1;
81  tlv_packet[2] = 0;
82  tlv_packet[3] = 11; /* length of this packet */
83  tlv_packet[4] = FR_PEAP_EXTENSIONS_TYPE;
84  tlv_packet[5] = 0x80; /* mandatory AVP */
85  tlv_packet[6] = EAP_TLV_ACK_RESULT;
86  tlv_packet[7] = 0;
87  tlv_packet[8] = 2; /* length of the data portion */
88  tlv_packet[9] = 0;
89  tlv_packet[10] = EAP_TLV_SUCCESS;
90 
91  (tls_session->record_from_buff)(&tls_session->clean_in, tlv_packet, 11);
92 
93  /*
94  * FIXME: Check the return code.
95  */
96  fr_tls_session_send(request, tls_session);
97 
98  return 1;
99 }
100 
101 
102 static int eap_peap_identity(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
103 {
104  eap_packet_raw_t eap_packet;
105 
106  eap_packet.code = FR_EAP_CODE_REQUEST;
107  eap_packet.id = eap_session->this_round->response->id + 1;
108  eap_packet.length[0] = 0;
109  eap_packet.length[1] = EAP_HEADER_LEN + 1;
110  eap_packet.data[0] = FR_EAP_METHOD_IDENTITY;
111 
112  (tls_session->record_from_buff)(&tls_session->clean_in, &eap_packet, sizeof(eap_packet));
113  fr_tls_session_send(request, tls_session);
114  (tls_session->record_init)(&tls_session->clean_in);
115 
116  return 1;
117 }
118 
119 /*
120  * Verify the tunneled EAP message.
121  */
122 static int eap_peap_verify(request_t *request, peap_tunnel_t *peap_tunnel,
123  uint8_t const *data, size_t data_len)
124 {
125  eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data;
126  eap_type_t eap_method;
127 
128  /*
129  * No data, OR only 1 byte of EAP type.
130  */
131  if (!data || (data_len == 0) || ((data_len <= 1) && (data[0] != FR_EAP_METHOD_IDENTITY))) return 0;
132 
133  /*
134  * Since the full EAP header is sent for the EAP Extensions type (Type 33),
135  * but not for other Types, it is difficult for the implementation to distinguish
136  * an Extensions Request (Code 1) from an EAP Type 1 (Identity) Request packet.
137  *
138  * i.e. The only way to validate PEAP inner method packets properly is to know
139  * we just send a protected success/failure.
140  */
141  switch (peap_tunnel->status) {
144  if (eap_packet->data[0] != FR_PEAP_EXTENSIONS_TYPE) {
145  REDEBUG("Invalid inner tunnel data, expected method (%u), got (%u)",
146  FR_PEAP_EXTENSIONS_TYPE, eap_packet->data[0]);
147  return -1;
148  }
149  return 0;
150 
151  default:
152  break;
153  }
154 
155  eap_method = data[0]; /* Inner EAP header misses off code and identifier */
156  switch (eap_method) {
158  RDEBUG2("Received EAP-Identity-Response");
159  return 0;
160 
161  /*
162  * We normally do Microsoft MS-CHAPv2 (26), versus
163  * Cisco MS-CHAPv2 (29).
164  */
166  default:
167  RDEBUG2("EAP method %s (%d)", eap_type2name(eap_method), eap_method);
168  return 0;
169  }
170 
171 }
172 
173 /*
174  * Convert a pseudo-EAP packet to a list of fr_pair_t's.
175  */
176 static void eap_peap_inner_to_pairs(TALLOC_CTX *ctx, fr_pair_list_t *pairs,
177  eap_round_t *eap_round,
178  uint8_t const *data, size_t data_len)
179 {
180  size_t total;
181  uint8_t *p;
182  fr_pair_t *vp = NULL;
183 
184  if (data_len > 65535) return; /* paranoia */
185 
187  total = data_len;
188  if (total > 249) total = 249;
189 
190  /*
191  * Hand-build an EAP packet from the crap in PEAP version 0.
192  */
193  MEM(fr_pair_value_mem_alloc(vp, &p, EAP_HEADER_LEN + total, false) == 0);
194  p[0] = FR_EAP_CODE_RESPONSE;
195  p[1] = eap_round->response->id;
196  p[2] = (data_len + EAP_HEADER_LEN) >> 8;
197  p[3] = (data_len + EAP_HEADER_LEN) & 0xff;
198  memcpy(p + EAP_HEADER_LEN, data, total);
199 
200  fr_pair_append(pairs, vp);
201  while (total < data_len) {
203  fr_pair_value_memdup(vp, data + total, (data_len - total), false);
204 
205  total += vp->vp_length;
206 
207  fr_pair_append(pairs, vp);
208  }
209 }
210 
211 
212 /*
213  * Convert a list of fr_pair_t's to an EAP packet, through the
214  * simple expedient of dumping the EAP message
215  */
216 static int eap_peap_inner_from_pairs(request_t *request, fr_tls_session_t *tls_session, fr_pair_list_t *vps)
217 {
218  fr_pair_t *this;
219 
221 
222  /*
223  * Send the EAP data in the first attribute, WITHOUT the
224  * header.
225  */
226  this = fr_pair_list_head(vps);
227  (tls_session->record_from_buff)(&tls_session->clean_in, this->vp_octets + EAP_HEADER_LEN,
228  this->vp_length - EAP_HEADER_LEN);
229 
230  /*
231  * Send the rest of the EAP data, but skipping the first VP.
232  */
233  for (this = fr_pair_list_next(vps, this);
234  this;
235  this = fr_pair_list_next(vps, this)) {
236  (tls_session->record_from_buff)(&tls_session->clean_in, this->vp_octets, this->vp_length);
237  }
238 
239  fr_tls_session_send(request, tls_session);
240 
241  return 1;
242 }
243 
244 
245 /*
246  * See if there's a TLV in the response.
247  */
248 static int eap_peap_check_tlv(request_t *request, uint8_t const *data, size_t data_len)
249 {
250  eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data;
251 
252  if (data_len < 11) return 0;
253 
254  /*
255  * Look for success or failure.
256  */
257  if ((eap_packet->code == FR_EAP_CODE_RESPONSE) &&
258  (eap_packet->data[0] == FR_PEAP_EXTENSIONS_TYPE)) {
259  if (data[10] == EAP_TLV_SUCCESS) {
260  return 1;
261  }
262 
263  if (data[10] == EAP_TLV_FAILURE) {
264  RDEBUG2("Client rejected our response. The password is probably incorrect");
265  return 0;
266  }
267  }
268 
269  RDEBUG2("Unknown TLV %02x", data[10]);
270 
271  return 0;
272 }
273 
274 
275 /*
276  * Use a reply packet to determine what to do.
277  */
278 static rlm_rcode_t CC_HINT(nonnull) process_reply(eap_session_t *eap_session, fr_tls_session_t *tls_session,
279  request_t *request,
280  fr_packet_t *reply, fr_pair_list_t *reply_list)
281 {
283  fr_pair_list_t vps;
284  peap_tunnel_t *t = tls_session->opaque;
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, reply_list, NULL);
298  }
299 
300  switch (reply->code) {
302  RDEBUG2("Tunneled authentication was successful");
304  eap_peap_success(request, eap_session, tls_session);
305  rcode = RLM_MODULE_HANDLED;
306  break;
307 
309  RDEBUG2("Tunneled authentication was rejected");
311  eap_peap_failure(request, eap_session, tls_session);
312  rcode = RLM_MODULE_HANDLED;
313  break;
314 
316  RDEBUG2("Got tunneled Access-Challenge");
317 
318  /*
319  * PEAP takes only EAP-Message attributes inside
320  * of the tunnel. Any Reply-Message in the
321  * Access-Challenge is ignored.
322  */
323  fr_pair_list_init(&vps);
324  MEM(fr_pair_list_copy_by_da(t, &vps, reply_list, attr_eap_message, 0) >= 0);
325 
326  /*
327  * Handle the ACK, by tunneling any necessary reply
328  * VP's back to the client.
329  */
330  if (!fr_pair_list_empty(&vps)) {
331  eap_peap_inner_from_pairs(request, tls_session, &vps);
332  fr_pair_list_free(&vps);
333  }
334 
335  rcode = RLM_MODULE_HANDLED;
336  break;
337 
338  default:
339  RDEBUG2("Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);
340  rcode = RLM_MODULE_REJECT;
341  break;
342  }
343 
344  return rcode;
345 }
346 
347 
348 static char const *peap_state(peap_tunnel_t *t)
349 {
350  switch (t->status) {
352  return "TUNNEL ESTABLISHED";
353 
355  return "WAITING FOR INNER IDENTITY";
356 
358  return "send tlv success";
359 
361  return "send tlv failure";
362 
364  return "phase2_init";
365 
366  case PEAP_STATUS_PHASE2:
367  return "phase2";
368 
369  default:
370  break;
371  }
372  return "?";
373 }
374 
375 /*
376  * Process the pseudo-EAP contents of the tunneled data.
377  */
379  eap_session_t *eap_session, fr_tls_session_t *tls_session)
380 {
381  peap_tunnel_t *t = tls_session->opaque;
382  request_t *fake = NULL;
383  fr_pair_t *vp;
385  uint8_t const *data;
386  size_t data_len;
387  eap_round_t *eap_round = eap_session->this_round;
388 
389  /*
390  * Just look at the buffer directly, without doing
391  * record_to_buff. This lets us avoid another data copy.
392  */
393  data_len = tls_session->clean_out.used;
394  tls_session->clean_out.used = 0;
395  data = tls_session->clean_out.data;
396 
397  RDEBUG2("PEAP state %s", peap_state(t));
398 
399  if ((t->status != PEAP_STATUS_TUNNEL_ESTABLISHED) && (eap_peap_verify(request, t, data, data_len) < 0)) {
400  REDEBUG("Tunneled data is invalid");
402  }
403 
404  switch (t->status) {
406  /* FIXME: should be no data in the buffer here, check & assert? */
407 
408  if (SSL_session_reused(tls_session->ssl)) {
409  RDEBUG2("Skipping Phase2 because of session resumption");
411  /* we're good, send success TLV */
413  eap_peap_success(request, eap_session, tls_session);
414 
415  } else {
416  /* send an identity request */
419  eap_peap_identity(request, eap_session, tls_session);
420  }
421  rcode = RLM_MODULE_HANDLED;
422  goto finish;
423 
425  /* we're expecting an identity response */
426  if (data[0] != FR_EAP_METHOD_IDENTITY) {
427  REDEBUG("Expected EAP-Identity, got something else");
428  rcode = RLM_MODULE_REJECT;
429  goto finish;
430  }
431 
432  /*
433  * Save it for later.
434  */
436  t->username->vp_tainted = true;
437 
438  fr_pair_value_bstrndup(t->username, (char const *)data + 1, data_len - 1, true);
439 
440  RDEBUG2("Got inner identity \"%pV\"", &t->username->data);
442  break;
443 
444  /*
445  * If we authenticated the user, then it's OK.
446  */
448  if (eap_peap_check_tlv(request, data, data_len)) {
449  RDEBUG2("Success");
450  rcode = RLM_MODULE_OK;
451  goto finish;
452  }
453 
454  /*
455  * Otherwise, the client rejected the session
456  * resumption. If the session is being re-used,
457  * we need to do a full authentication.
458  *
459  * We do this by sending an EAP-Identity request
460  * inside of the PEAP tunnel.
461  */
463  RDEBUG2("Client rejected session resumption. Re-starting full authentication");
464 
465  /*
466  * Mark session resumption status.
467  */
470 
471  eap_peap_identity(request, eap_session, tls_session);
472  rcode = RLM_MODULE_HANDLED;
473  goto finish;
474  }
475 
476  REDEBUG("Sent a success, but received something weird in return");
477  rcode = RLM_MODULE_REJECT;
478  goto finish;
479 
480  /*
481  * Supplicant ACKs our failure.
482  */
484  RINDENT();
485  REDEBUG("The users session was previously rejected: returning reject (again.)");
486  RIDEBUG("This means you need to read the PREVIOUS messages in the debug output");
487  RIDEBUG("to find out the reason why the user was rejected");
488  RIDEBUG("Look for \"reject\" or \"fail\". Those earlier messages will tell you");
489  RIDEBUG("what went wrong, and how to fix the problem");
490  REXDENT();
491 
493 
495  RDEBUG2("In state machine in phase2 init?");
496  break;
497 
498  case PEAP_STATUS_PHASE2:
499  break;
500 
501  default:
502  REDEBUG("Unhandled state in peap");
503  rcode = RLM_MODULE_REJECT;
504  goto finish;
505  }
506 
507  fake = request_alloc_internal(request, &(request_init_args_t){ .parent = request });
508  fr_assert(fr_pair_list_empty(&fake->request_pairs));
509 
510  switch (t->status) {
511  /*
512  * If we're in PHASE2_INIT, the phase2 method hasn't been
513  * sent an Identity packet yet; do so from the stored
514  * username and this will kick off the phase2 eap method
515  */
517  {
518  size_t len;
519  uint8_t *q;
520 
521  fr_assert(t->username);
522 
523  len = t->username->vp_length + EAP_HEADER_LEN + 1;
525 
526  MEM(vp = fr_pair_afrom_da(fake->request_ctx, attr_eap_message));
527  MEM(fr_pair_value_mem_alloc(vp, &q, len, false) == 0);
528  q[0] = FR_EAP_CODE_RESPONSE;
529  q[1] = eap_round->response->id;
530  q[2] = (len >> 8) & 0xff;
531  q[3] = len & 0xff;
532  q[4] = FR_EAP_METHOD_IDENTITY;
533  memcpy(q + EAP_HEADER_LEN + 1,
534  t->username->vp_strvalue, t->username->vp_length);
535  fr_pair_append(&fake->request_pairs, vp);
536  }
537  break;
538 
539  case PEAP_STATUS_PHASE2:
540  eap_peap_inner_to_pairs(fake->request_ctx, &fake->request_pairs,
541  eap_round, data, data_len);
542  if (fr_pair_list_empty(&fake->request_pairs)) {
543  talloc_free(fake);
544  RDEBUG2("Unable to convert tunneled EAP packet to internal server data structures");
545  rcode = RLM_MODULE_REJECT;
546  goto finish;
547  }
548  break;
549 
550  default:
551  REDEBUG("Invalid state change in PEAP");
552  rcode = RLM_MODULE_REJECT;
553  goto finish;
554  }
555 
556  RDEBUG2("Got tunneled request");
557  log_request_pair_list(L_DBG_LVL_2, request, NULL, &fake->request_pairs, NULL);
558 
559  /*
560  * Update other items in the request_t data structure.
561  */
562  if (!t->username) {
563  /*
564  * There's no User-Name in the tunneled session,
565  * so we add one here, by pulling it out of the
566  * EAP-Identity packet.
567  */
568  if ((data[0] == FR_EAP_METHOD_IDENTITY) && (data_len > 1)) {
570  fr_assert(t->username != NULL);
571  t->username->vp_tainted = true;
572 
573  fr_pair_value_bstrndup(t->username, (char const *)data + 1, data_len - 1, true);
574 
575  RDEBUG2("Got tunneled identity of %pV", &t->username->data);
576  }
577  } /* else there WAS a t->username */
578 
579  setup_fake_request(request, fake, t);
580 
581  /*
582  * Call authentication recursively, which will
583  * do PAP, CHAP, MS-CHAP, etc.
584  */
585  eap_virtual_server(request, eap_session, t->virtual_server);
586 
587  /*
588  * Decide what to do with the reply.
589  */
590  if (!fake->reply->code) {
591  REDEBUG("Unknown RADIUS packet type %d: rejecting tunneled user", fake->reply->code);
592  rcode = RLM_MODULE_REJECT;
593  } else {
594  rcode = process_reply(eap_session, tls_session, request, fake->reply, &fake->reply_pairs);
595  }
596 
597 finish:
598  talloc_free(fake);
599 
600  RETURN_MODULE_RCODE(rcode);
601 }
602 
603 static int CC_HINT(nonnull) setup_fake_request(request_t *request, request_t *fake, peap_tunnel_t *t) {
604 
605  fr_pair_t *vp;
606 
607  /*
608  * Tell the request that it's a fake one.
609  */
610  MEM(fr_pair_prepend_by_da(fake->request_ctx, &vp, &fake->request_pairs, attr_freeradius_proxied_to) >= 0);
611  (void) fr_pair_value_from_str(vp, "127.0.0.1", sizeof("127.0.0.1") - 1, NULL, false);
612 
613  if (t->username) {
614  vp = fr_pair_copy(fake->request_ctx, t->username);
615  fr_pair_append(&fake->request_pairs, vp);
616  RDEBUG2("Setting &request.User-Name from tunneled (inner) identity \"%s\"",
617  vp->vp_strvalue);
618  } else {
619  RDEBUG2("No tunnel username (SSL resumption?)");
620  }
621 
622  return 0;
623 }
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
#define USES_APPLE_DEPRECATED_API
Definition: build.h:431
#define RCSID(id)
Definition: build.h:444
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
@ 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:64
@ 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
char const * virtual_server
Definition: eap_peap.h:50
#define FR_PEAP_EXTENSIONS_TYPE
Definition: eap_peap.h:67
peap_status status
Definition: eap_peap.h:46
peap_resumption session_resumption_state
Definition: eap_peap.h:51
#define EAP_TLV_SUCCESS
Definition: eap_peap.h:63
fr_pair_t * username
Definition: eap_peap.h:45
#define EAP_TLV_ACK_RESULT
Definition: eap_peap.h:65
HIDDEN fr_dict_attr_t const * attr_freeradius_proxied_to
Definition: base.c:93
HIDDEN fr_dict_attr_t const * attr_eap_message
Definition: base.c:90
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.
Definition: base.c:401
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:821
#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
Definition: merged_model.c:30
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:2403
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:278
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:2978
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:1340
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:2781
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition: pair.c:484
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:2927
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
Definition: pair.c:2586
int fr_pair_prepend_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and prepend)
Definition: pair.c:1488
static USES_APPLE_DEPRECATED_API int setup_fake_request(request_t *request, request_t *fake, peap_tunnel_t *t)
Definition: peap.c:603
static int eap_peap_success(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition: peap.c:73
static int eap_peap_identity(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition: peap.c:102
static int eap_peap_check_tlv(request_t *request, uint8_t const *data, size_t data_len)
Definition: peap.c:248
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:176
static int eap_peap_inner_from_pairs(request_t *request, fr_tls_session_t *tls_session, fr_pair_list_t *vps)
Definition: peap.c:216
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:378
static int eap_peap_failure(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Definition: peap.c:39
static char const * peap_state(peap_tunnel_t *t)
Definition: peap.c:348
static int eap_peap_verify(request_t *request, peap_tunnel_t *peap_tunnel, uint8_t const *data, size_t data_len)
Definition: peap.c:122
static rlm_rcode_t process_reply(eap_session_t *eap_session, fr_tls_session_t *tls_session, request_t *request, fr_packet_t *reply, fr_pair_list_t *reply_list)
Definition: peap.c:278
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Definition: base.c:94
static fr_dict_attr_t const * attr_user_name
Definition: radclient-ng.c:125
#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:51
#define RIDEBUG(fmt,...)
Definition: radsniff.h:65
#define RETURN_MODULE_REJECT
Definition: rcode.h:55
#define RETURN_MODULE_RCODE(_rcode)
Definition: rcode.h:64
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
#define request_alloc_internal(_ctx, _args)
Allocate a new internal request.
Definition: request.h:304
Optional arguments for initialising requests.
Definition: request.h:253
static const void * fake
Definition: rlm_sql_null.c:30
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
unsigned int code
Packet code (type).
Definition: packet.h:61
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
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
Definition: pair_inline.c:125
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.
Definition: pair_inline.c:113
static fr_slen_t data
Definition: value.h:1259
int nonnull(2, 5))