All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_eap.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 9906be3770482b5820367cd1df4b6be901f507df $
19  * @file rlm_eap.c
20  * @brief Implements the EAP framework.
21  *
22  * @copyright 2000-2003,2006 The FreeRADIUS server project
23  * @copyright 2001 hereUare Communications, Inc. <raghud@hereuare.com>
24  * @copyright 2003 Alan DeKok <aland@freeradius.org>
25  */
26 RCSID("$Id: 9906be3770482b5820367cd1df4b6be901f507df $")
27 
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modules.h>
30 
31 #include "rlm_eap.h"
32 
33 static const CONF_PARSER module_config[] = {
34  { FR_CONF_OFFSET("default_eap_type", PW_TYPE_STRING, rlm_eap_t, default_method_name), .dflt = "md5" },
35  { FR_CONF_DEPRECATED("timer_expire", PW_TYPE_INTEGER, rlm_eap_t, timer_limit), .dflt = "60" },
36  { FR_CONF_OFFSET("ignore_unknown_eap_types", PW_TYPE_BOOLEAN, rlm_eap_t, ignore_unknown_types), .dflt = "no" },
37  { FR_CONF_OFFSET("cisco_accounting_username_bug", PW_TYPE_BOOLEAN, rlm_eap_t, mod_accounting_username_bug), .dflt = "no" },
38  { FR_CONF_DEPRECATED("max_sessions", PW_TYPE_INTEGER, rlm_eap_t, max_sessions), .dflt = "2048" },
40 };
41 
42 
43 /*
44  * read the config section and load all the eap authentication types present.
45  */
46 static int mod_instantiate(CONF_SECTION *cs, void *instance)
47 {
48  int i, ret;
49  eap_type_t method;
50  int num_methods;
51  CONF_SECTION *scs;
52  rlm_eap_t *inst = instance;
53 
54  /*
55  * Create our own random pool.
56  */
57  for (i = 0; i < 256; i++) {
58  inst->rand_pool.randrsl[i] = fr_rand();
59  }
60  fr_randinit(&inst->rand_pool, 1);
61  inst->rand_pool.randcnt = 0;
62 
63  inst->xlat_name = cf_section_name2(cs);
64  if (!inst->xlat_name) inst->xlat_name = "EAP";
65 
66  /* Load all the configured EAP-Types */
67  num_methods = 0;
68  for(scs = cf_subsection_find_next(cs, NULL, NULL);
69  scs != NULL;
70  scs = cf_subsection_find_next(cs, scs, NULL)) {
71 
72  char const *name;
73 
74  name = cf_section_name1(scs);
75  if (!name) continue;
76 
77  if (!strcmp(name, TLS_CONFIG_SECTION)) continue;
78 
79  method = eap_name2type(name);
80  if (method == PW_EAP_INVALID) {
81  cf_log_err_cs(cs, "No dictionary definition for EAP method %s", name);
82  return -1;
83  }
84 
85  if ((method < PW_EAP_MD5) || (method >= PW_EAP_MAX_TYPES)) {
86  cf_log_err_cs(cs, "Invalid EAP method %s (unsupported)", name);
87  return -1;
88  }
89 
90 #if !defined(HAVE_OPENSSL_SSL_H) || !defined(HAVE_LIBSSL)
91  /*
92  * This allows the default configuration to be
93  * shipped with EAP-TLS, etc. enabled. If the
94  * system doesn't have OpenSSL, they will be
95  * ignored.
96  *
97  * If the system does have OpenSSL, then this
98  * code will not be used. The administrator will
99  * then have to delete the tls,
100  * etc. configurations from eap.conf in order to
101  * have EAP without the TLS types.
102  */
103  switch (method) {
104  case PW_EAP_TLS:
105  case PW_EAP_TTLS:
106  case PW_EAP_PEAP:
107  case PW_EAP_PWD:
108  WARN("rlm_eap (%s): Ignoring EAP method %s because we don't have OpenSSL support",
109  inst->xlat_name, name);
110  continue;
111 
112  default:
113  break;
114  }
115 #endif
116 
117  /*
118  * Load the type.
119  */
120  ret = eap_module_instantiate(inst, &inst->methods[method], method, scs);
121 
122  (void) talloc_get_type_abort(inst->methods[method], eap_module_t);
123 
124  if (ret < 0) {
125  (void) talloc_steal(inst, inst->methods[method]);
126  return -1;
127  }
128 
129  (void) talloc_steal(inst, inst->methods[method]);
130  num_methods++; /* successfully loaded one more methods */
131  }
132 
133  if (num_methods == 0) {
134  cf_log_err_cs(cs, "No EAP method configured, module cannot do anything");
135  return -1;
136  }
137 
138  /*
139  * Ensure that the default EAP type is loaded.
140  */
141  method = eap_name2type(inst->default_method_name);
142  if (method == PW_EAP_INVALID) {
143  cf_log_err_cs(cs, "No dictionary definition for default EAP method '%s'",
144  inst->default_method_name);
145  return -1;
146  }
147 
148  if (!inst->methods[method]) {
149  cf_log_err_cs(cs, "No such sub-type for default EAP method %s",
150  inst->default_method_name);
151  return -1;
152  }
153  inst->default_method = method; /* save the numerical method */
154 
155  return 0;
156 }
157 
158 
159 /*
160  * For backwards compatibility.
161  */
162 static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
163 {
164  rlm_eap_t *inst;
165  eap_session_t *eap_session;
167  eap_rcode_t status;
168  rlm_rcode_t rcode;
169 
170  inst = (rlm_eap_t *) instance;
171 
172  if (!fr_pair_find_by_num(request->packet->vps, 0, PW_EAP_MESSAGE, TAG_ANY)) {
173  REDEBUG("You set 'Auth-Type = EAP' for a request that does "
174  "not contain an EAP-Message attribute!");
175  return RLM_MODULE_INVALID;
176  }
177 
178  /*
179  * Get the eap packet to start with
180  */
181  eap_packet = eap_vp2packet(request, request->packet->vps);
182  if (!eap_packet) {
183  RERROR("Malformed EAP Message: %s", fr_strerror());
184  return RLM_MODULE_FAIL;
185  }
186 
187  /*
188  * Create the eap eap_session. The eap_packet will end up being
189  * "swallowed" into the eap_session, so we can't access it after
190  * this call.
191  */
192  eap_session = eap_session_get(inst, &eap_packet, request);
193  if (!eap_session) {
194  RDEBUG2("Failed in eap_session");
195  return RLM_MODULE_INVALID;
196  }
197 
198  /*
199  * Select the appropriate method or default to the
200  * configured one
201  */
202  status = eap_method_select(inst, eap_session);
203 
204  /*
205  * If it failed, die.
206  */
207  if (status == EAP_INVALID) {
208  eap_fail(eap_session);
209  TALLOC_FREE(eap_session);
210  RDEBUG2("Failed in EAP select");
211  rcode = RLM_MODULE_INVALID;
212  goto finish;
213  }
214 
215 #ifdef WITH_PROXY
216  /*
217  * If we're doing horrible tunneling work, remember it.
218  */
219  if ((request->options & RAD_REQUEST_OPTION_PROXY_EAP) != 0) {
220  RDEBUG2("No EAP proxy set. Not composing EAP");
221  /*
222  * Add the handle to the proxied list, so that we
223  * can retrieve it in the post-proxy stage, and
224  * send a response.
225  */
226  eap_session->inst = inst;
227  status = request_data_add(request, inst, REQUEST_DATA_EAP_SESSION_PROXIED, eap_session,
228  false, false, false);
229  rad_assert(status == 0);
230 
231  rcode = RLM_MODULE_HANDLED;
232  goto finish;
233  }
234 #endif
235 
236 #ifdef WITH_PROXY
237  /*
238  * Maybe the request was marked to be proxied. If so,
239  * proxy it.
240  */
241  if (request->proxy != NULL) {
242  VALUE_PAIR *vp = NULL;
243 
244  rad_assert(!request->proxy_reply);
245 
246  /*
247  * Add the handle to the proxied list, so that we
248  * can retrieve it in the post-proxy stage, and
249  * send a response.
250  */
251  eap_session->inst = inst;
252 
253  status = request_data_add(request, inst, REQUEST_DATA_EAP_SESSION_PROXIED, eap_session,
254  false, false, false);
255  rad_assert(status == 0);
256 
257  /*
258  * Some simple sanity checks. These should really
259  * be handled by the radius library...
260  */
261  vp = fr_pair_find_by_num(request->proxy->vps, 0, PW_EAP_MESSAGE, TAG_ANY);
262  if (vp) {
263  vp = fr_pair_find_by_num(request->proxy->vps, 0, PW_MESSAGE_AUTHENTICATOR, TAG_ANY);
264  if (!vp) {
265  fr_pair_make(request->proxy,
266  &request->proxy->vps,
267  "Message-Authenticator",
268  NULL, T_OP_EQ);
269  }
270  }
271 
272  /*
273  * Delete the "proxied to" attribute, as it's
274  * set to 127.0.0.1 for tunneled requests, and
275  * we don't want to tell the world that...
276  */
277  fr_pair_delete_by_num(&request->proxy->vps, VENDORPEC_FREERADIUS, PW_FREERADIUS_PROXIED_TO, TAG_ANY);
278 
279  RDEBUG2("Tunneled session will be proxied. Not doing EAP");
280  rcode = RLM_MODULE_HANDLED;
281  goto finish;
282  }
283 #endif
284 
285  /*
286  * We are done, wrap the EAP-request in RADIUS to send
287  * with all other required radius attributes
288  */
289  rcode = eap_compose(eap_session);
290 
291  /*
292  * Add to the list only if it is EAP-Request, OR if
293  * it's LEAP, and a response.
294  */
295  if (((eap_session->this_round->request->code == PW_EAP_REQUEST) &&
296  (eap_session->this_round->request->type.num >= PW_EAP_MD5)) ||
297 
298  /*
299  * LEAP is a little different. At Stage 4,
300  * it sends an EAP-Success message, but we still
301  * need to keep the State attribute & session
302  * data structure around for the AP Challenge.
303  *
304  * At stage 6, LEAP sends an EAP-Response, which
305  * isn't put into the list.
306  */
307  ((eap_session->this_round->response->code == PW_EAP_RESPONSE) &&
308  (eap_session->this_round->response->type.num == PW_EAP_LEAP) &&
309  (eap_session->this_round->request->code == PW_EAP_SUCCESS) &&
310  (eap_session->this_round->request->type.num == 0))) {
311  talloc_free(eap_session->prev_round);
312  eap_session->prev_round = eap_session->this_round;
313  eap_session->this_round = NULL;
314  } else {
315  RDEBUG2("Freeing eap_session");
316  TALLOC_FREE(eap_session);
317  }
318 
319  /*
320  * If it's an Access-Accept, RFC 2869, Section 2.3.1
321  * says that we MUST include a User-Name attribute in the
322  * Access-Accept.
323  */
324  if ((request->reply->code == PW_CODE_ACCESS_ACCEPT) && request->username) {
325  VALUE_PAIR *vp;
326 
327  /*
328  * Doesn't exist, add it in.
329  */
330  vp = fr_pair_find_by_num(request->reply->vps, 0, PW_USER_NAME, TAG_ANY);
331  if (!vp) {
332  vp = fr_pair_copy(request->reply, request->username);
333  fr_pair_add(&request->reply->vps, vp);
334  }
335 
336  /*
337  * Cisco AP1230 has a bug and needs a zero
338  * terminated string in Access-Accept.
339  */
340  if (inst->mod_accounting_username_bug) {
341  char *new = talloc_zero_array(vp, char, vp->vp_length + 1 + 1); /* \0 + \0 */
342 
343  memcpy(new, vp->vp_strvalue, vp->vp_length);
344  fr_pair_value_strsteal(vp, new); /* Also frees existing buffer */
345  }
346  }
347 
348 finish:
349  /*
350  * Set the request pointer to NULL, so that if the EAP
351  * session gets cleaned up later as part of freeing a
352  * state entry, the destructor knows it's not associated
353  * with a request.
354  */
355  if (eap_session) eap_session->request = NULL;
356  return rcode;
357 }
358 
359 /*
360  * EAP authorization DEPENDS on other rlm authorizations,
361  * to check for user existence & get their configured values.
362  * It Handles EAP-START Messages, User-Name initilization.
363  */
364 static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request)
365 {
366  rlm_eap_t *inst;
367  int status;
368  VALUE_PAIR *vp;
369 
370  inst = (rlm_eap_t *)instance;
371 
372 #ifdef WITH_PROXY
373  /*
374  * We don't do authorization again, once we've seen the
375  * proxy reply (or the proxied packet)
376  */
377  if (request->proxy != NULL)
378  return RLM_MODULE_NOOP;
379 #endif
380 
381  /*
382  * For EAP_START, send Access-Challenge with EAP Identity
383  * request. even when we have to proxy this request
384  *
385  * RFC 2869, Section 2.3.1 notes that the "domain" of the
386  * user, (i.e. where to proxy him) comes from the EAP-Identity,
387  * so we CANNOT proxy the user, until we know his identity.
388  *
389  * We therefore send an EAP Identity request.
390  */
391  status = eap_start(inst, request);
392  switch (status) {
393  case EAP_NOOP:
394  return RLM_MODULE_NOOP;
395  case EAP_FAIL:
396  return RLM_MODULE_FAIL;
397  case EAP_FOUND:
398  return RLM_MODULE_HANDLED;
399  case EAP_OK:
400  case EAP_NOTFOUND:
401  default:
402  break;
403  }
404 
405  /*
406  * RFC 2869, Section 2.3.1. If a NAS sends an EAP-Identity,
407  * it MUST copy the identity into the User-Name attribute.
408  *
409  * But we don't worry about that too much. We depend on
410  * each EAP sub-module to look for eap_session->request->username,
411  * and to get excited if it doesn't appear.
412  */
413  vp = fr_pair_find_by_num(request->config, 0, PW_AUTH_TYPE, TAG_ANY);
414  if ((!vp) || (vp->vp_integer != PW_AUTH_TYPE_REJECT)) {
415  vp = pair_make_config("Auth-Type", inst->xlat_name, T_OP_EQ);
416  if (!vp) {
417  RDEBUG2("Failed to create Auth-Type %s: %s\n",
418  inst->xlat_name, fr_strerror());
419  return RLM_MODULE_FAIL;
420  }
421  } else {
422  RWDEBUG2("Auth-Type already set. Not setting to EAP");
423  }
424 
425  if (status == EAP_OK) return RLM_MODULE_OK;
426 
427  return RLM_MODULE_UPDATED;
428 }
429 
430 
431 #ifdef WITH_PROXY
432 /*
433  * If we're proxying EAP, then there may be magic we need
434  * to do.
435  */
436 static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *instance, REQUEST *request)
437 {
438  size_t i;
439  size_t len;
440  ssize_t ret;
441  char *p;
442  VALUE_PAIR *vp;
443  eap_session_t *eap_session;
444  vp_cursor_t cursor;
445  rlm_eap_t *inst = instance;
446 
447  /*
448  * If there was a eap_session associated with this request,
449  * then it's a tunneled request which was proxied...
450  */
451  eap_session = request_data_get(request, inst, REQUEST_DATA_EAP_SESSION_PROXIED);
452  if (eap_session != NULL) {
453  rlm_rcode_t rcode;
455 
456  /*
457  * Grab the tunnel callbacks from the request.
458  */
459  data = (eap_tunnel_data_t *) request_data_get(request,
460  request->proxy,
462  if (!data) {
463  RERROR("Failed to retrieve callback for tunneled session!");
464  talloc_free(eap_session);
465  return RLM_MODULE_FAIL;
466  }
467 
468  /*
469  * Do the callback...
470  */
471  RDEBUG2("Doing post-proxy callback");
472  rcode = data->callback(eap_session, data->tls_session);
473  talloc_free(data);
474  if (rcode == 0) {
475  RDEBUG2("Failed in post-proxy callback");
476  eap_fail(eap_session);
477  talloc_free(eap_session);
478  return RLM_MODULE_REJECT;
479  }
480 
481  /*
482  * We are done, wrap the EAP-request in RADIUS to send
483  * with all other required radius attributes
484  */
485  eap_compose(eap_session);
486 
487  /*
488  * Add to the list only if it is EAP-Request, OR if
489  * it's LEAP, and a response.
490  */
491  if ((eap_session->this_round->request->code == PW_EAP_REQUEST) &&
492  (eap_session->this_round->request->type.num >= PW_EAP_MD5)) {
493  talloc_free(eap_session->prev_round);
494  eap_session->prev_round = eap_session->this_round;
495  eap_session->this_round = NULL;
496  } else { /* couldn't have been LEAP, there's no tunnel */
497  RDEBUG2("Freeing eap_session");
498  talloc_free(eap_session);
499  }
500 
501  /*
502  * If it's an Access-Accept, RFC 2869, Section 2.3.1
503  * says that we MUST include a User-Name attribute in the
504  * Access-Accept.
505  */
506  if ((request->reply->code == PW_CODE_ACCESS_ACCEPT) && request->username) {
507  /*
508  * Doesn't exist, add it in.
509  */
510  vp = fr_pair_find_by_num(request->reply->vps, 0, PW_USER_NAME, TAG_ANY);
511  if (!vp) {
512  pair_make_reply("User-Name", request->username->vp_strvalue, T_OP_EQ);
513  }
514  }
515 
516  return RLM_MODULE_OK;
517  } else {
518  RDEBUG2("No pre-existing eap_session found");
519  }
520 
521  /*
522  * This is allowed.
523  */
524  if (!request->proxy_reply) return RLM_MODULE_NOOP;
525 
526  /*
527  * Hmm... there's got to be a better way to
528  * discover codes for vendor attributes.
529  *
530  * This is vendor Cisco (9), Cisco-AVPair
531  * attribute (1)
532  */
533  for (vp = fr_cursor_init(&cursor, &request->proxy_reply->vps);
534  vp;
535  vp = fr_cursor_next_by_num(&cursor, 9, 1, TAG_ANY)) {
536  /*
537  * If it's "leap:session-key", then stop.
538  *
539  * The format is VERY specific!
540  */
541  if (strncasecmp(vp->vp_strvalue, "leap:session-key=", 17) == 0) break;
542  }
543 
544  /*
545  * Got to the end without finding "leap:session-key="
546  */
547  if (!vp) return RLM_MODULE_NOOP;
548 
549  /*
550  * The format is very specific.
551  *
552  * - 17 bytes are "leap:session-key="
553  * - 32 are the hex encoded session key.
554  * - 2 bytes are the salt.
555  */
556  if (vp->vp_length != (17 + 34)) {
557  RDEBUG2("&Cisco-AVPair with leap:session-key has incorrect length. Got %zu, expected %d",
558  vp->vp_length, 17 + 34);
559  return RLM_MODULE_NOOP;
560  }
561 
562  /*
563  * Decrypt the session key, using the proxy data.
564  *
565  * Note that the session key is *binary*, and therefore
566  * may contain embedded zeros. So we have to use memdup.
567  * However, Cisco-AVPair is a "string", so the rest of the
568  * code assumes that it's terminated by a trailing '\0'.
569  *
570  * So... be sure to (a) use memdup, and (b) include the last
571  * zero byte.
572  */
573  i = 34;
574  p = talloc_memdup(vp, vp->vp_strvalue, vp->vp_length + 1);
575  talloc_set_type(p, uint8_t);
576  ret = fr_radius_decode_tunnel_password((uint8_t *)p + 17, &i, request->home_server->secret,
577  request->proxy->vector);
578  if (ret < 0) {
579  REDEBUG("Decoding leap:session-key failed");
580  talloc_free(p);
581  return RLM_MODULE_FAIL;
582  }
583  len = i;
584  if (len != 16) {
585  REDEBUG("Decoded key length is incorrect, must be 16 bytes");
586  talloc_free(p);
587  return RLM_MODULE_FAIL;
588  }
589 
590  /*
591  * Encrypt the session key again, using the request data.
592  */
593  ret = fr_radius_encode_tunnel_password(p + 17, &len, request->client->secret, request->packet->vector);
594  if (ret < 0) {
595  REDEBUG("Encoding leap:session-key failed");
596  talloc_free(p);
597  return RLM_MODULE_FAIL;
598  }
599 
600  fr_pair_value_strsteal(vp, p);
601 
602  return RLM_MODULE_UPDATED;
603 }
604 #endif
605 
606 static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request)
607 {
608  rlm_eap_t *inst = instance;
609  VALUE_PAIR *vp;
610  eap_session_t *eap_session;
612 
613  /*
614  * Only build a failure message if something previously rejected the request
615  */
616  vp = fr_pair_find_by_num(request->config, 0, PW_POST_AUTH_TYPE, TAG_ANY);
617 
618  if (!vp || (vp->vp_integer != PW_POST_AUTH_TYPE_REJECT)) return RLM_MODULE_NOOP;
619 
620  if (!fr_pair_find_by_num(request->packet->vps, 0, PW_EAP_MESSAGE, TAG_ANY)) {
621  RDEBUG3("Request didn't contain an EAP-Message, not inserting EAP-Failure");
622  return RLM_MODULE_NOOP;
623  }
624 
625  if (fr_pair_find_by_num(request->reply->vps, 0, PW_EAP_MESSAGE, TAG_ANY)) {
626  RDEBUG3("Reply already contained an EAP-Message, not inserting EAP-Failure");
627  return RLM_MODULE_NOOP;
628  }
629 
630  eap_packet = eap_vp2packet(request, request->packet->vps);
631  if (!eap_packet) {
632  RERROR("Malformed EAP Message: %s", fr_strerror());
633  return RLM_MODULE_FAIL;
634  }
635 
636  eap_session = eap_session_get(inst, &eap_packet, request);
637  if (!eap_session) {
638  RDEBUG2("Failed to get eap_session, probably already removed, not inserting EAP-Failure");
639  return RLM_MODULE_NOOP;
640  }
641 
642  RDEBUG2("Request was previously rejected, inserting EAP-Failure");
643  eap_fail(eap_session);
644  talloc_free(eap_session);
645 
646  /*
647  * Make sure there's a message authenticator attribute in the response
648  * RADIUS protocol code will calculate the correct value later...
649  */
650  vp = fr_pair_find_by_num(request->reply->vps, 0, PW_MESSAGE_AUTHENTICATOR, TAG_ANY);
651  if (!vp) {
652  pair_make_reply("Message-Authenticator", "0x00", T_OP_EQ);
653  }
654 
655  return RLM_MODULE_UPDATED;
656 }
657 
658 /*
659  * The module name should be the only globally exported symbol.
660  * That is, everything else should be 'static'.
661  */
662 extern module_t rlm_eap;
663 module_t rlm_eap = {
665  .name = "eap",
666  .inst_size = sizeof(rlm_eap_t),
667  .config = module_config,
668  .instantiate = mod_instantiate,
669  .methods = {
672 #ifdef WITH_PROXY
673  [MOD_POST_PROXY] = mod_post_proxy,
674 #endif
676  },
677 };
Ok, continue.
Definition: eap_types.h:109
#define RERROR(fmt,...)
Definition: log.h:207
#define TLS_CONFIG_SECTION
Definition: eap.h:36
Invalid, don't reply.
Definition: eap_types.h:112
The module is OK, continue.
Definition: radiusd.h:91
static rlm_rcode_t mod_post_auth(void *instance, REQUEST *request) CC_HINT(nonnull)
Metadata exported by the module.
Definition: modules.h:134
#define RAD_REQUEST_OPTION_PROXY_EAP
Definition: eap.h:111
void * inst
Instance of the eap module this session was created by.
Definition: eap.h:65
VALUE_PAIR * fr_cursor_next_by_num(vp_cursor_t *cursor, unsigned int vendor, unsigned int attr, int8_t tag)
Iterate over a collection of VALUE_PAIRs of a given type in the pairlist.
Definition: cursor.c:200
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition: radius.c:1621
eap_type_t eap_name2type(char const *name)
Return an EAP-Type for a particular name.
Definition: eapcommon.c:88
7 methods index for postauth section.
Definition: modules.h:48
#define VENDORPEC_FREERADIUS
Definition: radius.h:201
static char const * name
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
Handle authorization requests using Couchbase document data.
#define RLM_MODULE_INIT
Definition: modules.h:86
#define REQUEST_DATA_EAP_TUNNEL_CALLBACK
Definition: eap.h:109
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
eap_packet_raw_t * eap_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps)
Definition: eapcommon.c:297
VALUE_PAIR * fr_cursor_init(vp_cursor_t *cursor, VALUE_PAIR *const *node)
Setup a cursor to iterate over attribute pairs.
Definition: cursor.c:60
rlm_rcode_t eap_compose(eap_session_t *eap_session)
Definition: eap.c:445
void fr_randinit(fr_randctx *ctx, int flag)
Definition: isaac.c:65
eap_packet_t * request
Packet we will send to the peer.
Definition: eap.h:45
#define inst
Definition: token.h:46
The module considers the request invalid.
Definition: radiusd.h:93
void eap_fail(eap_session_t *eap_session)
Definition: eap.c:850
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
eap_round_t * prev_round
Previous response/request pair.
Definition: eap.h:75
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
eap_type_data_t type
Definition: eap_types.h:136
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
Definition: pair.h:144
REQUEST * request
Request that contains the response we're processing.
Definition: eap.h:71
void fr_pair_value_strsteal(VALUE_PAIR *vp, char const *src)
Reparent an allocated char buffer to a VALUE_PAIR.
Definition: pair.c:1955
enum eap_method eap_type_t
#define rad_assert(expr)
Definition: rad_assert.h:38
static const CONF_PARSER module_config[]
Definition: rlm_eap.c:33
static int mod_instantiate(CONF_SECTION *cs, void *instance)
Definition: rlm_eap.c:46
eap_type_t num
Definition: eap_types.h:122
enum eap_rcode eap_rcode_t
bool mod_accounting_username_bug
Definition: rlm_eap.h:58
Structure to represent packet format of eap on wire
Definition: eap_types.h:143
char const * default_method_name
Definition: rlm_eap.h:54
CONF_SECTION * cf_subsection_find_next(CONF_SECTION const *section, CONF_SECTION const *subsection, char const *name1)
Definition: conffile.c:3799
#define pair_make_config(_a, _b, _c)
Definition: radiusd.h:547
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
Definition: pair.c:659
Tracks the progress of a single session of any EAP method.
Definition: eap.h:60
Immediately reject the request.
Definition: radiusd.h:89
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: eap.h:77
void * request_data_get(REQUEST *request, void *unique_ptr, int unique_int)
Get opaque data from a request.
Definition: request.c:374
eap_rcode_t eap_method_select(rlm_eap_t *inst, eap_session_t *eap_session)
Select the correct callback based on a response.
Definition: eap.c:317
RFC2865 - Access-Accept.
Definition: radius.h:93
void * tls_session
Definition: eap.h:119
Failed, don't reply.
Definition: eap_types.h:110
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
eap_tunnel_callback_t callback
Definition: eap.h:120
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
0 methods index for authenticate section.
Definition: modules.h:41
A truth value.
Definition: radius.h:56
#define FR_CONF_DEPRECATED(_n, _t, _p, _f)
Definition: conffile.h:179
32 Bit unsigned integer.
Definition: radius.h:34
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
#define RWDEBUG2(fmt,...)
Definition: log.h:252
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag)
Delete matching pairs.
Definition: pair.c:797
char const * cf_section_name1(CONF_SECTION const *cs)
Definition: conffile.c:3592
Module succeeded without doing anything.
Definition: radiusd.h:96
#define RDEBUG2(fmt,...)
Definition: log.h:244
EAP eap_session data found, continue.
Definition: eap_types.h:108
eap_session_t * eap_session_get(rlm_eap_t *inst, eap_packet_raw_t **eap_packet_p, REQUEST *request)
Definition: eap.c:1069
uint32_t randrsl[256]
Definition: libradius.h:429
uint8_t data[]
Definition: eap_pwd.h:625
uint64_t magic
Used to validate module struct.
Definition: modules.h:135
Module failed, don't reply.
Definition: radiusd.h:90
#define TAG_ANY
Definition: pair.h:191
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
int eap_module_instantiate(rlm_eap_t *inst, eap_module_t **m_inst, eap_type_t num, CONF_SECTION *cs)
Load required EAP sub-modules (methods)
Definition: eap.c:96
#define pair_make_reply(_a, _b, _c)
Definition: radiusd.h:546
int strncasecmp(char *s1, char *s2, int n)
Definition: missing.c:43
module_t rlm_eap
Definition: rlm_eap.c:663
ssize_t fr_radius_decode_tunnel_password(uint8_t *encpw, size_t *len, char const *secret, uint8_t const *vector)
Decode Tunnel-Password encrypted attributes.
Definition: radius_decode.c:36
int request_data_add(REQUEST *request, void *unique_ptr, int unique_int, void *opaque, bool free_on_replace, bool free_on_parent, bool persist)
Add opaque data to a REQUEST.
Definition: request.c:279
char const * xlat_name
Definition: rlm_eap.h:64
#define WARN(fmt,...)
Definition: log.h:144
fr_randctx rand_pool
Definition: rlm_eap.h:65
#define REDEBUG(fmt,...)
Definition: log.h:254
#define REQUEST_DATA_EAP_SESSION_PROXIED
Definition: eap.h:107
6 methods index for postproxy section.
Definition: modules.h:47
VALUE_PAIR * fr_pair_copy(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
Copy a single valuepair.
Definition: pair.c:129
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
EAP eap_session data not found.
Definition: eap_types.h:107
Succeeded without doing anything.
Definition: eap_types.h:111
eap_module_t * methods[PW_EAP_MAX_TYPES]
Definition: rlm_eap.h:52
struct rlm_eap rlm_eap_t
Structure to hold EAP data.
Definition: eap_types.h:132
int eap_start(rlm_eap_t *inst, REQUEST *request)
Definition: eap.c:608
static rlm_rcode_t CC_HINT(nonnull)
Definition: rlm_eap.c:162
eap_packet_t * response
Packet we received from the peer.
Definition: eap.h:44
String of printable characters.
Definition: radius.h:33
1 methods index for authorize section.
Definition: modules.h:42
eap_type_t default_method
Definition: rlm_eap.h:55
#define RCSID(id)
Definition: build.h:135
OK (pairs modified).
Definition: radiusd.h:97
uint32_t randcnt
Definition: libradius.h:428
int fr_radius_encode_tunnel_password(char *encpw, size_t *len, char const *secret, uint8_t const *vector)
Encode Tunnel-Password attributes when sending them out on the wire.
The module handled the request, so stop.
Definition: radiusd.h:92
VALUE_PAIR * fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op)
Create a VALUE_PAIR from ASCII strings.
Definition: pair.c:338
eap_code_t code
Definition: eap_types.h:133
char const * cf_section_name2(CONF_SECTION const *cs)
Definition: conffile.c:3601
#define RDEBUG3(fmt,...)
Definition: log.h:245