2 * eap.c rfc2284 & rfc2869 implementation
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.
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.
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
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>
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * EAP Request and Response Packet Format
37 * --- ------- --- -------- ------ ------
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
47 * EAP Success and Failure Packet Format
48 * --- ------- --- ------- ------ ------
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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 #include <freeradius-devel/ident.h>
58 #include <freeradius-devel/modpriv.h>
63 static const char *eap_codes[] = {
64 "", /* 0 is invalid */
72 * Load all the required eap authentication types.
73 * Get all the supported EAP-types from config file.
75 int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
79 const char *eaptype_name;
82 eaptype_name = eaptype_type2name(eap_type, namebuf, sizeof(namebuf));
83 snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_name);
85 /* Make room for the EAP-Type */
86 node = (EAP_TYPES *)malloc(sizeof(EAP_TYPES));
88 radlog(L_ERR, "rlm_eap: out of memory");
91 memset(node, 0, sizeof(*node));
93 /* fill in the structure */
97 * In general, this is a terrible idea. It works here
98 * solely because the eap_type2name function returns a
99 * 'static const char *' pointer sometimes, and we can
100 * ONLY link to module which are named in that static
103 node->typename = eaptype_name;
104 node->type_data = NULL;
106 #ifdef WITHOUT_LIBLTDL
111 node->type = (EAP_TYPE *)lt_dlsym(RTLD_SELF, buffer);
112 if (node->type) goto open_self;
117 /* Link the loaded EAP-Type */
118 node->handle = lt_dlopenext(buffer);
119 if (node->handle == NULL) {
121 radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
122 eaptype_name, lt_dlerror());
126 node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
128 radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
129 buffer, eaptype_name, lt_dlerror());
130 lt_dlclose(node->handle); /* ignore any errors */
135 #if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
138 cf_log_module(cs, "Linked to sub-module %s", buffer);
140 cf_log_module(cs, "Instantiating eap-%s", eaptype_name);
142 if ((node->type->attach) &&
143 ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
145 radlog(L_ERR, "rlm_eap: Failed to initialize type %s",
147 lt_dlclose(node->handle);
157 * Call the appropriate handle with the right eap_type.
159 static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
162 REQUEST *request = handler->request;
163 const char *module = request->module;
165 RDEBUG2("processing type %s", atype->typename);
166 request->module = atype->typename;
168 rad_assert(atype != NULL);
170 switch (handler->stage) {
172 if (!atype->type->initiate(atype->type_data, handler))
178 * The called function updates the EAP reply packet.
180 if (!atype->type->authorize ||
181 !atype->type->authorize(atype->type_data, handler))
187 * The called function updates the EAP reply packet.
189 if (!atype->type->authenticate ||
190 !atype->type->authenticate(atype->type_data, handler))
195 /* Should never enter here */
196 RDEBUG("Internal sanity check failed on eap_type");
201 request->module = module;
206 * Based on TYPE, call the appropriate EAP-type handler
207 * Default to the configured EAP-Type
208 * for all Unsupported EAP-Types
210 int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
213 unsigned int default_eap_type = inst->default_eap_type;
217 const char *eaptype_name;
218 REQUEST *request = handler->request;
220 eaptype = &handler->eap_ds->response->type;
223 * Don't trust anyone.
225 if ((eaptype->type == 0) ||
226 (eaptype->type > PW_EAP_MAX_TYPES)) {
227 RDEBUG2("Asked to select bad type");
232 * Multiple levels of nesting are invalid.
234 if (handler->request->parent && handler->request->parent->parent) {
235 RDEBUG2("Multiple levels of TLS nesting is invalid.");
240 * Figure out what to do.
242 switch(eaptype->type) {
243 case PW_EAP_IDENTITY:
244 RDEBUG2("EAP Identity");
247 * Allow per-user configuration of EAP types.
249 vp = pairfind(handler->request->config_items,
251 if (vp) default_eap_type = vp->vp_integer;
257 if ((default_eap_type < PW_EAP_MD5) ||
258 (default_eap_type > PW_EAP_MAX_TYPES) ||
259 (inst->types[default_eap_type] == NULL)) {
260 RDEBUG2("No such EAP type %s",
261 eaptype_type2name(default_eap_type,
262 namebuf, sizeof(namebuf)));
266 handler->stage = INITIATE;
267 handler->eap_type = default_eap_type;
270 * Wild & crazy stuff! For TTLS & PEAP, we
271 * initiate a TLS session, and then pass that
272 * session data to TTLS or PEAP for the
273 * authenticate stage.
275 * Handler->eap_type holds the TRUE type.
277 if ((default_eap_type == PW_EAP_TTLS) ||
278 (default_eap_type == PW_EAP_PEAP)) {
279 default_eap_type = PW_EAP_TLS;
282 if ((default_eap_type == PW_EAP_TNC) &&
283 !handler->request->parent) {
284 RDEBUG2("ERROR: EAP-TNC must be run inside of a TLS method.");
288 if (eaptype_call(inst->types[default_eap_type],
290 RDEBUG2("Default EAP type %s failed in initiate",
291 eaptype_type2name(default_eap_type,
292 namebuf, sizeof(namebuf)));
299 * The NAK data is the preferred EAP type(s) of
302 * RFC 3748 says to list one or more proposed
303 * alternative types, one per octet, or to use
304 * 0 for no alternative.
309 * Delete old data, if necessary.
311 if (handler->opaque && handler->free_opaque) {
312 handler->free_opaque(handler->opaque);
313 handler->free_opaque = NULL;
314 handler->opaque = NULL;
317 if (eaptype->data == NULL) {
318 RDEBUG2("Empty NAK packet, cannot decide what EAP type the client wants.");
323 * Pick one type out of the one they asked for,
324 * as they may have asked for many.
326 default_eap_type = 0;
327 vp = pairfind(handler->request->config_items,
329 for (i = 0; i < eaptype->length; i++) {
331 * It is invalid to request identity,
332 * notification & nak in nak.
334 * Type 0 is valid, and means there are no
337 if (eaptype->data[i] < PW_EAP_MD5) {
338 RDEBUG2("NAK asked for bad type %d",
343 if ((eaptype->data[i] > PW_EAP_MAX_TYPES) ||
344 !inst->types[eaptype->data[i]]) {
347 dv = dict_valbyattr(PW_EAP_TYPE, 0, eaptype->data[i]);
349 RDEBUG2("NAK asked for unsupported type %s",
352 RDEBUG2("NAK asked for unsupported type %d",
358 eaptype_name = eaptype_type2name(eaptype->data[i],
363 * Prevent a firestorm if the client is confused.
365 if (handler->eap_type == eaptype->data[i]) {
366 RDEBUG2("ERROR! Our request for %s was NAK'd with a request for %s. Skipping the requested type.",
367 eaptype_name, eaptype_name);
372 * Enforce per-user configuration of EAP
375 if (vp && (vp->vp_integer != eaptype->data[i])) {
377 RDEBUG2("Client wants %s, while we require %s. Skipping the requested type.",
379 eaptype_type2name(vp->vp_integer,
385 default_eap_type = eaptype->data[i];
390 * We probably want to return 'fail' here...
392 if (!default_eap_type) {
393 RDEBUG2("No common EAP types found.");
396 eaptype_name = eaptype_type2name(default_eap_type,
397 namebuf, sizeof(namebuf));
398 RDEBUG2("EAP-NAK asked for EAP-Type/%s",
405 * Key off of the configured sub-modules.
408 eaptype_name = eaptype_type2name(eaptype->type,
411 RDEBUG2("EAP/%s", eaptype_name);
414 * We haven't configured it, it doesn't exit.
416 if (!inst->types[eaptype->type]) {
417 RDEBUG2("EAP type %d is unsupported",
422 rad_assert(handler->stage == AUTHENTICATE);
423 handler->eap_type = eaptype->type;
424 if (eaptype_call(inst->types[eaptype->type],
426 RDEBUG2("Handler failed in EAP/%s",
438 * compose EAP reply packet in EAP-Message attr of RADIUS. If
439 * EAP exceeds 253, frame it in multiple EAP-Message attrs.
441 * Set the RADIUS reply codes based on EAP request codes. Append
442 * any additonal VPs to RADIUS reply
444 int eap_compose(EAP_HANDLER *handler)
447 eap_packet_t *eap_packet;
448 REQUEST *request = handler->request;
449 EAP_DS *eap_ds = handler->eap_ds;
450 EAP_PACKET *reply = eap_ds->request;
454 * The Id for the EAP packet to the NAS wasn't set.
457 * LEAP requires the Id to be incremented on EAP-Success
458 * in Stage 4, so that we can carry on the conversation
459 * where the client asks us to authenticate ourselves
462 if (!eap_ds->set_request_id) {
464 * Id serves to suppport request/response
465 * retransmission in the EAP layer and as such
466 * must be different for 'adjacent' packets
467 * except in case of success/failure-replies.
469 * RFC2716 (EAP-TLS) requires this to be
470 * incremented, RFC2284 only makes the above-
471 * mentioned restriction.
473 reply->id = handler->eap_ds->response->id;
475 switch (reply->code) {
477 * The Id is a simple "ack" for success
480 * RFC 3748 section 4.2 says
482 * ... The Identifier field MUST match
483 * the Identifier field of the Response
484 * packet that it is sent in response
492 * We've sent a response to their
493 * request, the Id is incremented.
499 RDEBUG2("Underlying EAP-Type set EAP ID to %d",
504 * For Request & Response packets, set the EAP sub-type,
505 * if the EAP sub-module didn't already set it.
507 * This allows the TLS module to be "morphic", and means
508 * that the TTLS and PEAP modules can call it to do most
509 * of their dirty work.
511 if (((eap_ds->request->code == PW_EAP_REQUEST) ||
512 (eap_ds->request->code == PW_EAP_RESPONSE)) &&
513 (eap_ds->request->type.type == 0)) {
514 rad_assert(handler->eap_type >= PW_EAP_MD5);
515 rad_assert(handler->eap_type <= PW_EAP_MAX_TYPES);
517 eap_ds->request->type.type = handler->eap_type;
521 * FIXME: We malloc memory for the eap packet, and then
522 * immediately copy that data into VALUE_PAIRs. This
523 * could be done more efficiently...
525 if (eap_wireformat(reply) == EAP_INVALID) {
526 return RLM_MODULE_INVALID;
528 eap_packet = (eap_packet_t *)reply->packet;
530 vp = eap_packet2vp(eap_packet);
531 if (!vp) return RLM_MODULE_INVALID;
532 pairadd(&(request->reply->vps), vp);
535 * EAP-Message is always associated with
536 * Message-Authenticator but not vice-versa.
538 * Don't add a Message-Authenticator if it's already
541 vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0);
543 vp = paircreate(PW_MESSAGE_AUTHENTICATOR, 0, PW_TYPE_OCTETS);
544 memset(vp->vp_octets, 0, AUTH_VECTOR_LEN);
545 vp->length = AUTH_VECTOR_LEN;
546 pairadd(&(request->reply->vps), vp);
549 /* Set request reply code, but only if it's not already set. */
550 rcode = RLM_MODULE_OK;
551 if (!request->reply->code) switch(reply->code) {
552 case PW_EAP_RESPONSE:
553 request->reply->code = PW_AUTHENTICATION_ACK;
554 rcode = RLM_MODULE_HANDLED; /* leap weirdness */
557 request->reply->code = PW_AUTHENTICATION_ACK;
558 rcode = RLM_MODULE_OK;
561 request->reply->code = PW_AUTHENTICATION_REJECT;
562 rcode = RLM_MODULE_REJECT;
565 request->reply->code = PW_ACCESS_CHALLENGE;
566 rcode = RLM_MODULE_HANDLED;
570 * When we're pulling MS-CHAPv2 out of EAP-MS-CHAPv2,
571 * we do so WITHOUT setting a reply code, as the
572 * request is being proxied.
574 if (request->options & RAD_REQUEST_OPTION_PROXY_EAP) {
575 return RLM_MODULE_HANDLED;
578 /* Should never enter here */
579 radlog(L_ERR, "rlm_eap: reply code %d is unknown, Rejecting the request.", reply->code);
580 request->reply->code = PW_AUTHENTICATION_REJECT;
581 reply->code = PW_EAP_FAILURE;
582 rcode = RLM_MODULE_REJECT;
590 * Radius criteria, EAP-Message is invalid without Message-Authenticator
591 * For EAP_START, send Access-Challenge with EAP Identity request.
593 int eap_start(rlm_eap_t *inst, REQUEST *request)
595 VALUE_PAIR *vp, *proxy;
598 eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE, 0);
599 if (eap_msg == NULL) {
600 RDEBUG2("No EAP-Message, not doing EAP");
605 * Look for EAP-Type = None (FreeRADIUS specific attribute)
606 * this allows you to NOT do EAP for some users.
608 vp = pairfind(request->packet->vps, PW_EAP_TYPE, 0);
609 if (vp && vp->vp_integer == 0) {
610 RDEBUG2("Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
615 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
617 * Checks for Message-Authenticator are handled by rad_recv().
621 * Check for a Proxy-To-Realm. Don't get excited over LOCAL
624 proxy = pairfind(request->config_items, PW_PROXY_TO_REALM, 0);
629 * If it's a LOCAL realm, then we're not proxying
632 realm = realm_find(proxy->vp_strvalue);
633 if (!realm || (realm && (realm->auth_pool == NULL))) {
639 * Check the length before de-referencing the contents.
641 * Lengths of zero are required by the RFC for EAP-Start,
642 * but we've never seen them in practice.
644 * Lengths of two are what we see in practice as
647 if ((eap_msg->length == 0) || (eap_msg->length == 2)) {
652 * It's a valid EAP-Start, but the request
653 * was marked as being proxied. So we don't
654 * do EAP, as the home server will do it.
658 RDEBUG2("Request is supposed to be proxied to Realm %s. Not doing EAP.", proxy->vp_strvalue);
662 RDEBUG2("Got EAP_START message");
663 if ((eap_ds = eap_ds_alloc()) == NULL) {
664 RDEBUG2("EAP Start failed in allocation");
669 * It's an EAP-Start packet. Tell them to stop wasting
670 * our time, and give us an EAP-Identity packet.
672 * Hmm... we should probably check the contents of the
673 * EAP-Start packet for something...
675 eap_ds->request->code = PW_EAP_REQUEST;
676 eap_ds->request->type.type = PW_EAP_IDENTITY;
679 * We don't have a handler, but eap_compose needs one,
680 * (for various reasons), so we fake it out here.
682 memset(&handler, 0, sizeof(handler));
683 handler.request = request;
684 handler.eap_ds = eap_ds;
686 eap_compose(&handler);
688 eap_ds_free(&eap_ds);
690 } /* end of handling EAP-Start */
693 * The EAP packet header is 4 bytes, plus one byte of
694 * EAP sub-type. Short packets are discarded, unless
697 if (eap_msg->length < (EAP_HEADER_LEN + 1)) {
698 if (proxy) goto do_proxy;
700 RDEBUG2("Ignoring EAP-Message which is too short to be meaningful.");
705 * Create an EAP-Type containing the EAP-type
708 vp = paircreate(PW_EAP_TYPE, 0, PW_TYPE_INTEGER);
710 vp->vp_integer = eap_msg->vp_octets[4];
711 pairadd(&(request->packet->vps), vp);
715 * If the request was marked to be proxied, do it now.
716 * This is done after checking for a valid length
717 * (which may not be good), and after adding the EAP-Type
718 * attribute. This lets other modules selectively cancel
719 * proxying based on EAP-Type.
721 if (proxy) goto do_proxy;
724 * From now on, we're supposed to be handling the
725 * EAP packet. We better understand it...
729 * We're allowed only a few codes. Request, Response,
730 * Success, or Failure.
732 if ((eap_msg->vp_octets[0] == 0) ||
733 (eap_msg->vp_octets[0] > PW_EAP_MAX_CODES)) {
734 RDEBUG2("Unknown EAP packet");
736 RDEBUG2("EAP packet type %s id %d length %d",
737 eap_codes[eap_msg->vp_octets[0]],
738 eap_msg->vp_octets[1],
743 * We handle request and responses. The only other defined
744 * codes are success and fail. The client SHOULD NOT be
745 * sending success/fail packets to us, as it doesn't make
748 if ((eap_msg->vp_octets[0] != PW_EAP_REQUEST) &&
749 (eap_msg->vp_octets[0] != PW_EAP_RESPONSE)) {
750 RDEBUG2("Ignoring EAP packet which we don't know how to handle.");
755 * We've been told to ignore unknown EAP types, AND it's
756 * an unknown type. Return "NOOP", which will cause the
757 * eap_authorize() to return NOOP.
759 * EAP-Identity, Notification, and NAK are all handled
760 * internally, so they never have handlers.
762 if ((eap_msg->vp_octets[4] >= PW_EAP_MD5) &&
763 inst->ignore_unknown_eap_types &&
764 ((eap_msg->vp_octets[4] == 0) ||
765 (eap_msg->vp_octets[4] > PW_EAP_MAX_TYPES) ||
766 (inst->types[eap_msg->vp_octets[4]] == NULL))) {
767 RDEBUG2(" Ignoring Unknown EAP type");
772 * They're NAKing the EAP type we wanted to use, and
773 * asking for one which we don't support.
775 * NAK is code + id + length1 + length + NAK
776 * + requested EAP type(s).
778 * We know at this point that we can't handle the
779 * request. We could either return an EAP-Fail here, but
780 * it's not too critical.
782 * By returning "noop", we can ensure that authorize()
783 * returns NOOP, and another module may choose to proxy
786 if ((eap_msg->vp_octets[4] == PW_EAP_NAK) &&
787 (eap_msg->length >= (EAP_HEADER_LEN + 2)) &&
788 inst->ignore_unknown_eap_types &&
789 ((eap_msg->vp_octets[5] == 0) ||
790 (eap_msg->vp_octets[5] > PW_EAP_MAX_TYPES) ||
791 (inst->types[eap_msg->vp_octets[5]] == NULL))) {
792 RDEBUG2("Ignoring NAK with request for unknown EAP type");
796 if ((eap_msg->vp_octets[4] == PW_EAP_TTLS) ||
797 (eap_msg->vp_octets[4] == PW_EAP_PEAP)) {
798 RDEBUG2("Continuing tunnel setup.");
803 * Later EAP messages are longer than the 'start'
804 * message, so if everything is OK, this function returns
805 * 'no start found', so that the rest of the EAP code can
806 * use the State attribute to match this EAP-Message to
807 * an ongoing conversation.
809 RDEBUG2("No EAP Start, assuming it's an on-going EAP conversation");
815 * compose EAP FAILURE packet in EAP-Message
817 void eap_fail(EAP_HANDLER *handler)
820 * Delete any previous replies.
822 pairdelete(&handler->request->reply->vps, PW_EAP_MESSAGE, 0);
823 pairdelete(&handler->request->reply->vps, PW_STATE, 0);
825 eap_packet_free(&handler->eap_ds->request);
826 handler->eap_ds->request = eap_packet_alloc();
828 handler->eap_ds->request->code = PW_EAP_FAILURE;
829 eap_compose(handler);
833 * compose EAP SUCCESS packet in EAP-Message
835 void eap_success(EAP_HANDLER *handler)
837 handler->eap_ds->request->code = PW_EAP_SUCCESS;
838 eap_compose(handler);
842 * Basic EAP packet verfications & validations
844 static int eap_validation(REQUEST *request, eap_packet_t *eap_packet)
848 memcpy(&len, eap_packet->length, sizeof(uint16_t));
852 * High level EAP packet checks
854 if ((len <= EAP_HEADER_LEN) ||
855 ((eap_packet->code != PW_EAP_RESPONSE) &&
856 (eap_packet->code != PW_EAP_REQUEST)) ||
857 (eap_packet->data[0] <= 0) ||
858 (eap_packet->data[0] > PW_EAP_MAX_TYPES)) {
860 radlog_request(L_AUTH, 0, request,
861 "Badly formatted EAP Message: Ignoring the packet");
865 /* we don't expect notification, but we send it */
866 if (eap_packet->data[0] == PW_EAP_NOTIFICATION) {
867 radlog_request(L_AUTH, 0, request, "Got NOTIFICATION, "
868 "Ignoring the packet");
877 * Get the user Identity only from EAP-Identity packets
879 static char *eap_identity(REQUEST *request, eap_packet_t *eap_packet)
885 if ((eap_packet == NULL) ||
886 (eap_packet->code != PW_EAP_RESPONSE) ||
887 (eap_packet->data[0] != PW_EAP_IDENTITY)) {
891 memcpy(&len, eap_packet->length, sizeof(uint16_t));
894 if ((len <= 5) || (eap_packet->data[1] == 0x00)) {
895 RDEBUG("UserIdentity Unknown ");
900 identity = rad_malloc(size + 1);
901 memcpy(identity, &eap_packet->data[1], size);
902 identity[size] = '\0';
909 * Create our Request-Response data structure with the eap packet
911 static EAP_DS *eap_buildds(eap_packet_t **eap_packet_p)
913 EAP_DS *eap_ds = NULL;
914 eap_packet_t *eap_packet = *eap_packet_p;
918 if ((eap_ds = eap_ds_alloc()) == NULL) {
922 eap_ds->response->packet = (unsigned char *)eap_packet;
923 eap_ds->response->code = eap_packet->code;
924 eap_ds->response->id = eap_packet->id;
925 eap_ds->response->type.type = eap_packet->data[0];
927 memcpy(&len, eap_packet->length, sizeof(uint16_t));
929 eap_ds->response->length = len;
932 * We've eaten the eap packet into the eap_ds.
934 *eap_packet_p = NULL;
937 * First 5 bytes in eap, are code + id + length(2) + type.
939 * The rest is type-specific data. We skip type while
940 * getting typedata from data.
942 typelen = len - 5/*code + id + length + type */;
945 * Since the packet contains the complete
946 * eap_packet, typedata will be a ptr in packet
949 eap_ds->response->type.data = eap_ds->response->packet + 5/*code+id+length+type*/;
950 eap_ds->response->type.length = typelen;
952 eap_ds->response->type.length = 0;
953 eap_ds->response->type.data = NULL;
961 * If identity response then create a fresh handler & fill the identity
962 * else handler MUST be in our list, get that.
963 * This handler creation cannot fail
965 * username contains REQUEST->username which might have been stripped.
966 * identity contains the one sent in EAP-Identity response
968 EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
971 EAP_HANDLER *handler = NULL;
972 eap_packet_t *eap_packet = *eap_packet_p;
976 * Ensure it's a valid EAP-Request, or EAP-Response.
978 if (eap_validation(request, eap_packet) == EAP_INVALID) {
980 *eap_packet_p = NULL;
985 * EAP_HANDLER MUST be found in the list if it is not
986 * EAP-Identity response
988 if (eap_packet->data[0] != PW_EAP_IDENTITY) {
989 handler = eaplist_find(inst, request, eap_packet);
990 if (handler == NULL) {
991 /* Either send EAP_Identity or EAP-Fail */
992 RDEBUG("Either EAP-request timed out OR"
993 " EAP-response to an unknown EAP-request");
995 *eap_packet_p = NULL;
1000 * Even more paranoia. Without this, some weird
1001 * clients could do crazy things.
1003 * It's ok to send EAP sub-type NAK in response
1004 * to a request for a particular type, but it's NOT
1005 * OK to blindly return data for another type.
1007 if ((eap_packet->data[0] != PW_EAP_NAK) &&
1008 (eap_packet->data[0] != handler->eap_type)) {
1009 RDEBUG("Response appears to match, but EAP type is wrong.");
1010 free(*eap_packet_p);
1011 *eap_packet_p = NULL;
1015 vp = pairfind(request->packet->vps, PW_USER_NAME, 0);
1018 * NAS did not set the User-Name
1019 * attribute, so we set it here and
1020 * prepend it to the beginning of the
1021 * request vps so that autz's work
1024 RDEBUG2("Broken NAS did not set User-Name, setting from EAP Identity");
1025 vp = pairmake("User-Name", handler->identity, T_OP_EQ);
1027 RDEBUG("Out of memory");
1028 free(*eap_packet_p);
1029 *eap_packet_p = NULL;
1032 vp->next = request->packet->vps;
1033 request->packet->vps = vp;
1037 * A little more paranoia. If the NAS
1038 * *did* set the User-Name, and it doesn't
1039 * match the identity, (i.e. If they
1040 * change their User-Name part way through
1041 * the EAP transaction), then reject the
1042 * request as the NAS is doing something
1045 if (strncmp(handler->identity, vp->vp_strvalue,
1046 MAX_STRING_LEN) != 0) {
1047 RDEBUG("Identity does not match User-Name. Authentication failed.");
1048 free(*eap_packet_p);
1049 *eap_packet_p = NULL;
1053 } else { /* packet was EAP identity */
1054 handler = eap_handler_alloc(inst);
1055 if (handler == NULL) {
1056 RDEBUG("Out of memory.");
1057 free(*eap_packet_p);
1058 *eap_packet_p = NULL;
1063 * All fields in the handler are set to zero.
1065 handler->identity = eap_identity(request, eap_packet);
1066 if (handler->identity == NULL) {
1067 RDEBUG("Identity Unknown, authentication failed");
1068 free(*eap_packet_p);
1069 *eap_packet_p = NULL;
1070 eap_handler_free(inst, handler);
1074 vp = pairfind(request->packet->vps, PW_USER_NAME, 0);
1077 * NAS did not set the User-Name
1078 * attribute, so we set it here and
1079 * prepend it to the beginning of the
1080 * request vps so that autz's work
1083 RDEBUG2("WARNING NAS did not set User-Name. Setting it locally from EAP Identity");
1084 vp = pairmake("User-Name", handler->identity, T_OP_EQ);
1086 RDEBUG("Out of memory");
1087 free(*eap_packet_p);
1088 *eap_packet_p = NULL;
1089 eap_handler_free(inst, handler);
1092 vp->next = request->packet->vps;
1093 request->packet->vps = vp;
1096 * Paranoia. If the NAS *did* set the
1097 * User-Name, and it doesn't match the
1098 * identity, the NAS is doing something
1099 * funny, so reject the request.
1101 if (strncmp(handler->identity, vp->vp_strvalue,
1102 MAX_STRING_LEN) != 0) {
1103 RDEBUG("Identity does not match User-Name, setting from EAP Identity.");
1104 free(*eap_packet_p);
1105 *eap_packet_p = NULL;
1106 eap_handler_free(inst, handler);
1112 handler->eap_ds = eap_buildds(eap_packet_p);
1113 if (handler->eap_ds == NULL) {
1114 free(*eap_packet_p);
1115 *eap_packet_p = NULL;
1116 eap_handler_free(inst, handler);
1120 handler->timestamp = request->timestamp;
1121 handler->request = request; /* LEAP needs this */