The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
compose.c
Go to the documentation of this file.
1 /*
2  * eap.c rfc2284 & rfc2869 implementation
3  *
4  * Version: $Id: 032eff53ce83ae0d66ac6dd33ec4e57e1224a133 $
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 
65 RCSID("$Id: 032eff53ce83ae0d66ac6dd33ec4e57e1224a133 $")
66 
67 static 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  */
89 static 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  */
196  case FR_EAP_CODE_SUCCESS:
197  case FR_EAP_CODE_FAILURE:
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 
256  case FR_EAP_CODE_SUCCESS:
257  request->reply->code = FR_RADIUS_CODE_ACCESS_ACCEPT;
258  rcode = RLM_MODULE_OK;
259  break;
260 
261  case FR_EAP_CODE_FAILURE:
262  request->reply->code = FR_RADIUS_CODE_ACCESS_REJECT;
263  rcode = RLM_MODULE_REJECT;
264  break;
265 
266  case FR_EAP_CODE_REQUEST:
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 %d 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 %i) 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  */
291 rlm_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 */
342  p[4] = FR_EAP_METHOD_IDENTITY;
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 {
485  eap_session->this_round->request->code = FR_EAP_CODE_REQUEST;
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);
504  eap_session->this_round->request->code = FR_EAP_CODE_FAILURE;
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 {
515  eap_session->this_round->request->code = FR_EAP_CODE_SUCCESS;
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:444
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_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
rlm_rcode_t eap_fail(eap_session_t *eap_session)
Definition: compose.c:494
static eap_round_t * eap_round_alloc(eap_session_t *eap_session)
Definition: compose.c:524
rlm_rcode_t eap_success(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:291
rlm_rcode_t eap_compose(eap_session_t *eap_session)
Definition: compose.c:153
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
@ 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:96
HIDDEN fr_dict_attr_t const * attr_eap_message
Definition: base.c:90
HIDDEN fr_dict_attr_t const * attr_eap_type
Definition: base.c:86
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
Definition: merged_model.c:31
unsigned char uint8_t
Definition: merged_model.c:30
#define RADIUS_AUTH_VECTOR_LENGTH
Definition: net.h:89
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:688
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_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
Definition: pair.c:1684
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:3033
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
VQP attributes.
#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
if(!subtype_vp) goto fail
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
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