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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000-2003 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 static const char rcsid[] = "$Id$";
61 static const char *eap_codes[] = {
62 "", /* 0 is invalid */
70 * Load all the required eap authentication types.
71 * Get all the supported EAP-types from config file.
73 int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
79 snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_type2name(eap_type));
81 /* Link the loaded EAP-Type */
82 handle = lt_dlopenext(buffer);
84 radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
85 eaptype_type2name(eap_type), lt_dlerror());
89 /* Make room for the EAP-Type */
90 node = (EAP_TYPES *)malloc(sizeof(EAP_TYPES));
92 radlog(L_ERR, "rlm_eap: out of memory");
95 memset(node, 0, sizeof(*node));
97 /* fill in the structure */
98 node->handle = handle;
100 node->typename = eaptype_type2name(eap_type);
101 node->type_data = NULL;
103 node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
105 radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
106 buffer, eaptype_type2name(eap_type), lt_dlerror());
107 lt_dlclose(node->handle); /* ignore any errors */
111 if ((node->type->attach) &&
112 ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
114 radlog(L_ERR, "rlm_eap: Failed to initialize type %s",
115 eaptype_type2name(eap_type));
116 lt_dlclose(node->handle);
121 DEBUG("rlm_eap: Loaded and initialized type %s", eaptype_type2name(eap_type));
127 * Call the appropriate handle with the right eap_type.
129 static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
133 DEBUG2(" rlm_eap: processing type %s", atype->typename);
135 rad_assert(atype != NULL);
137 switch (handler->stage) {
139 if (!atype->type->initiate(atype->type_data, handler))
145 * The called function updates the EAP reply packet.
147 if (!atype->type->authorize ||
148 !atype->type->authorize(atype->type_data, handler))
154 * The called function updates the EAP reply packet.
156 if (!atype->type->authenticate ||
157 !atype->type->authenticate(atype->type_data, handler))
162 /* Should never enter here */
163 radlog(L_DBG, "rlm_eap: Invalid operation on eap_type");
172 * Based on TYPE, call the appropriate EAP-type handler
173 * Default to the configured EAP-Type
174 * for all Unsupported EAP-Types
176 int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
178 int default_eap_type = inst->default_eap_type;
182 eaptype = &handler->eap_ds->response->type;
185 * Don't trust anyone.
187 if ((eaptype->type == 0) ||
188 (eaptype->type > PW_EAP_MAX_TYPES)) {
189 DEBUG2(" rlm_eap: Asked to select bad type");
194 * Figure out what to do.
196 switch(eaptype->type) {
197 case PW_EAP_IDENTITY:
198 DEBUG2(" rlm_eap: EAP Identity");
201 * Allow per-user configuration of EAP types.
203 vp = pairfind(handler->request->config_items,
205 if (vp) default_eap_type = vp->lvalue;
211 if ((default_eap_type < PW_EAP_MD5) ||
212 (default_eap_type > PW_EAP_MAX_TYPES) ||
213 (inst->types[default_eap_type] == NULL)) {
214 DEBUG2(" rlm_eap: No such EAP type %d",
219 handler->stage = INITIATE;
220 handler->eap_type = default_eap_type;
223 * Wild & crazy stuff! For TTLS & PEAP, we
224 * initiate a TLS session, and then pass that
225 * session data to TTLS or PEAP for the
226 * authenticate stage.
228 * Handler->eap_type holds the TRUE type.
230 if ((default_eap_type == PW_EAP_TTLS) ||
231 (default_eap_type == PW_EAP_PEAP)) {
232 default_eap_type = PW_EAP_TLS;
237 * We don't do TLS inside of TLS, as it's a bad
240 if (((handler->request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) &&
241 (default_eap_type == PW_EAP_TLS)) {
242 DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS");
246 if (eaptype_call(inst->types[default_eap_type],
248 DEBUG2(" rlm_eap: Default EAP type %s failed in initiate", eaptype_type2name(default_eap_type));
255 * The one byte of NAK data is the preferred EAP type
258 DEBUG2(" rlm_eap: EAP NAK");
261 * Delete old data, if necessary.
263 if (handler->opaque && handler->free_opaque) {
264 handler->free_opaque(handler->opaque);
265 handler->free_opaque = NULL;
266 handler->opaque = NULL;
270 * It is invalid to request identity,
271 * notification & nak in nak
273 if (eaptype->data == NULL) {
274 DEBUG2(" rlm_eap: Empty NAK packet, cannot decide what EAP type the client wants.");
278 if ((eaptype->data[0] < PW_EAP_MD5) ||
279 (eaptype->data[0] > PW_EAP_MAX_TYPES)) {
280 DEBUG2(" rlm_eap: NAK asked for bad type %d",
285 default_eap_type = eaptype->data[0];
286 DEBUG2(" rlm_eap: EAP-NAK asked for EAP-Type/%s",
287 eaptype_type2name(default_eap_type));
290 * Prevent a firestorm if the client is confused.
292 if (handler->eap_type == default_eap_type) {
293 DEBUG2(" rlm_eap: ERROR! Our request for %s was NAK'd with a request for %s, what is the client thinking?",
294 eaptype_type2name(default_eap_type),
295 eaptype_type2name(default_eap_type));
300 * Enforce per-user configuration of EAP types.
302 vp = pairfind(handler->request->config_items,
304 if (vp && (vp->lvalue != default_eap_type)) {
305 DEBUG2(" rlm_eap: Client wants %s, while we require %s, rejecting the user.",
306 eaptype_type2name(default_eap_type),
307 eaptype_type2name(vp->lvalue));
314 * Key off of the configured sub-modules.
317 DEBUG2(" rlm_eap: EAP/%s",
318 eaptype_type2name(eaptype->type));
321 * We haven't configured it, it doesn't exit.
323 if (!inst->types[eaptype->type]) {
324 DEBUG2(" rlm_eap: EAP type %d is unsupported",
329 rad_assert(handler->stage == AUTHENTICATE);
330 handler->eap_type = eaptype->type;
331 if (eaptype_call(inst->types[eaptype->type],
333 DEBUG2(" rlm_eap: Handler failed in EAP/%s",
334 eaptype_type2name(eaptype->type));
345 * EAP packet format to be sent over the wire
347 * i.e. code+id+length+data where data = null/type+typedata
350 static int eap_wireformat(EAP_PACKET *reply)
353 uint16_t total_length = 0;
355 if (reply == NULL) return EAP_INVALID;
357 total_length = EAP_HEADER_LEN;
358 if (reply->code < 3) {
359 total_length += 1/*EAPtype*/;
360 if (reply->type.data && reply->type.length > 0) {
361 total_length += reply->type.length;
365 reply->packet = (unsigned char *)malloc(total_length);
366 hdr = (eap_packet_t *)reply->packet;
368 radlog(L_ERR, "rlm_eap: out of memory");
372 hdr->code = (reply->code & 0xFF);
373 hdr->id = (reply->id & 0xFF);
374 total_length = htons(total_length);
375 memcpy(hdr->length, &total_length, sizeof(uint16_t));
378 * Request and Response packets are special.
380 if ((reply->code == PW_EAP_REQUEST) ||
381 (reply->code == PW_EAP_RESPONSE)) {
382 hdr->data[0] = (reply->type.type & 0xFF);
385 * Here since we cannot know the typedata format and length
387 * Type_data is expected to be wired by each EAP-Type
389 * Zero length/No typedata is supported as long as
392 if (reply->type.data && reply->type.length > 0) {
393 memcpy(&hdr->data[1], reply->type.data, reply->type.length);
394 free(reply->type.data);
395 reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;
403 * compose EAP reply packet in EAP-Message attr of RADIUS. If
404 * EAP exceeds 253, frame it in multiple EAP-Message attrs.
406 * Set the RADIUS reply codes based on EAP request codes. Append
407 * any additonal VPs to RADIUS reply
409 int eap_compose(EAP_HANDLER *handler)
411 uint16_t eap_len, len;
414 eap_packet_t *eap_packet;
416 REQUEST *request = handler->request;
417 EAP_DS *eap_ds = handler->eap_ds;
418 EAP_PACKET *reply = eap_ds->request;
422 * The Id for the EAP packet to the NAS wasn't set.
425 * LEAP requires the Id to be incremented on EAP-Success
426 * in Stage 4, so that we can carry on the conversation
427 * where the client asks us to authenticate ourselves
430 if (!eap_ds->set_request_id) {
432 * Id serves to suppport request/response
433 * retransmission in the EAP layer and as such
434 * must be different for 'adjacent' packets
435 * except in case of success/failure-replies.
437 * RFC2716 (EAP-TLS) requires this to be
438 * incremented, RFC2284 only makes the above-
439 * mentioned restriction.
441 reply->id = handler->eap_ds->response->id;
443 switch (reply->code) {
445 * The Id is a simple "ack" for success
453 * We've sent a response to their
454 * request, the Id is incremented.
460 DEBUG2(" rlm_eap: Underlying EAP-Type set EAP ID to %d",
465 * For Request & Response packets, set the EAP sub-type,
466 * if the EAP sub-module didn't already set it.
468 * This allows the TLS module to be "morphic", and means
469 * that the TTLS and PEAP modules can call it to do most
470 * of their dirty work.
472 if (((eap_ds->request->code == PW_EAP_REQUEST) ||
473 (eap_ds->request->code == PW_EAP_RESPONSE)) &&
474 (eap_ds->request->type.type == 0)) {
475 rad_assert(handler->eap_type >= PW_EAP_MD5);
476 rad_assert(handler->eap_type <= PW_EAP_MAX_TYPES);
478 eap_ds->request->type.type = handler->eap_type;
482 if (eap_wireformat(reply) == EAP_INVALID) {
483 return RLM_MODULE_INVALID;
485 eap_packet = (eap_packet_t *)reply->packet;
487 memcpy(&eap_len, &(eap_packet->length), sizeof(uint16_t));
488 len = eap_len = ntohs(eap_len);
489 ptr = (unsigned char *)eap_packet;
501 * create a value pair & append it to the request reply list
502 * This memory gets freed up when request is freed up
504 eap_msg = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);
505 memcpy(eap_msg->strvalue, ptr, len);
506 eap_msg->length = len;
507 pairadd(&(request->reply->vps), eap_msg);
513 * EAP-Message is always associated with
514 * Message-Authenticator but not vice-versa.
516 * Don't add a Message-Authenticator if it's already
519 vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);
521 vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
522 memset(vp->strvalue, 0, AUTH_VECTOR_LEN);
523 vp->length = AUTH_VECTOR_LEN;
524 pairadd(&(request->reply->vps), vp);
527 /* Set request reply code, but only if it's not already set. */
528 rcode = RLM_MODULE_OK;
529 if (!request->reply->code) switch(reply->code) {
530 case PW_EAP_RESPONSE:
531 request->reply->code = PW_AUTHENTICATION_ACK;
532 rcode = RLM_MODULE_HANDLED; /* leap weirdness */
535 request->reply->code = PW_AUTHENTICATION_ACK;
536 rcode = RLM_MODULE_OK;
539 request->reply->code = PW_AUTHENTICATION_REJECT;
540 rcode = RLM_MODULE_REJECT;
543 request->reply->code = PW_ACCESS_CHALLENGE;
544 rcode = RLM_MODULE_HANDLED;
547 /* Should never enter here */
548 radlog(L_ERR, "rlm_eap: reply code %d is unknown, Rejecting the request.", reply->code);
549 request->reply->code = PW_AUTHENTICATION_REJECT;
550 rcode = RLM_MODULE_REJECT;
558 * Radius criteria, EAP-Message is invalid without Message-Authenticator
559 * For EAP_START, send Access-Challenge with EAP Identity request.
561 int eap_start(rlm_eap_t *inst, REQUEST *request)
568 eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE);
569 if (eap_msg == NULL) {
570 DEBUG2(" rlm_eap: No EAP-Message, not doing EAP");
575 * Look for EAP-Type = None (FreeRADIUS specific attribute)
576 * this allows you to NOT do EAP for some users.
578 vp = pairfind(request->packet->vps, PW_EAP_TYPE);
579 if (vp && vp->lvalue == 0) {
580 DEBUG2(" rlm_eap: Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
585 * http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
587 * This is handled by rad_recv().
591 * We're allowed only a few codes. Request, Response,
592 * Success, or Failure.
594 if ((eap_msg->strvalue[0] == 0) ||
595 (eap_msg->strvalue[0] > PW_EAP_MAX_CODES)) {
596 DEBUG2(" rlm_eap: Unknown EAP packet");
598 DEBUG2(" rlm_eap: EAP packet type %s id %d length %d",
599 eap_codes[eap_msg->strvalue[0]],
600 eap_msg->strvalue[1],
605 * If we've been configured to proxy, do nothing.
607 * Note that we don't check if the realm is local.
608 * We figure that anyone bright enough to add
609 * Proxy-To-Realm is bright enough to NOT do so
610 * when it's a local realm.
612 if (pairfind(request->config_items, PW_PROXY_TO_REALM) != NULL) {
613 DEBUG2(" rlm_eap: Request is supposed to be proxied. Not doing EAP.");
618 * Not a start message. Don't start anything.
620 * Later EAP messages are longer than the 'start' message,
621 * so this function returns 'no start found', so that
622 * the rest of the EAP code can use the State attribute
623 * to match this EAP-Message to an ongoing conversation.
625 if (eap_msg->length != EAP_START) {
626 DEBUG2(" rlm_eap: No EAP Start, assuming it's an on-going EAP conversation");
629 * Add the 'EAP-Type' attribute to the request,
630 * if it's part of an EAP conversation, and the
631 * EAP sub-type is in the EAP packet.
633 * Store the EAP type in the request, so modules
634 * outside of EAP can check & use it.
636 if (((eap_msg->strvalue[0] == PW_EAP_REQUEST) ||
637 (eap_msg->strvalue[0] == PW_EAP_RESPONSE)) &&
638 (eap_msg->length >= (EAP_HEADER_LEN + 1))) {
640 * Create an EAP-Type of the type which
641 * was NAK'd, or of the type in the packet.
643 vp = paircreate(PW_EAP_TYPE, PW_TYPE_INTEGER);
645 vp->lvalue = eap_msg->strvalue[4];
646 pairadd(&(request->packet->vps), vp);
650 * We've been told to ignore unknown EAP
651 * types, AND it's an unknown type.
652 * Return "NOOP", which will cause the
653 * eap_authorize() to return NOOP.
655 * EAP-Identity, Notification, and NAK
656 * are all handled internally, so they
657 * never have handlers.
659 if ((eap_msg->strvalue[4] >= PW_EAP_MD5) &&
660 inst->ignore_unknown_eap_types &&
661 ((eap_msg->strvalue[4] == 0) ||
662 (eap_msg->strvalue[4] > PW_EAP_MAX_TYPES) ||
663 (inst->types[eap_msg->strvalue[4]] == NULL))) {
664 DEBUG2(" rlm_eap: Ignoring Unknown EAP type");
669 * They're NAKing the EAP type we wanted
670 * to use, and asking for one which we don't
673 * NAK is code + id + length1 + length + NAK
674 * + requested EAP type.
676 * We know at this point that we can't
677 * handle the request. We could either
678 * return an EAP-Fail here, but it's not
681 * By returning "noop", we can ensure
682 * that authorize() returns NOOP, and
683 * another module may choose to proxy
686 if ((eap_msg->strvalue[4] == PW_EAP_NAK) &&
687 (eap_msg->length >= (EAP_HEADER_LEN + 2)) &&
688 inst->ignore_unknown_eap_types &&
689 ((eap_msg->strvalue[5] == 0) ||
690 (eap_msg->strvalue[5] > PW_EAP_MAX_TYPES) ||
691 (inst->types[eap_msg->strvalue[5]] == NULL))) {
692 DEBUG2(" rlm_eap: Ignoring NAK with request for unknown EAP type");
695 } /* else it's not an EAP-Request or EAP-Response */
698 * No EAP-Start found.
703 DEBUG2(" rlm_eap: Got EAP_START message");
704 if ((eap_ds = eap_ds_alloc()) == NULL) {
705 DEBUG2(" rlm_eap: EAP Start failed in allocation");
710 * It's an EAP-Start packet. Tell them to stop wasting
711 * our time, and give us an EAP-Identity packet.
713 * Hmm... we should probably check the contents of the
714 * EAP-Start packet for something...
716 eap_ds->request->code = PW_EAP_REQUEST;
717 eap_ds->request->type.type = PW_EAP_IDENTITY;
720 * We don't have a handler, but eap_compose needs one,
721 * (for various reasons), so we fake it out here.
723 memset(&handler, 0, sizeof(handler));
724 handler.request = request;
725 handler.eap_ds = eap_ds;
727 eap_compose(&handler);
729 eap_ds_free(&eap_ds);
734 * compose EAP FAILURE packet in EAP-Message
736 void eap_fail(EAP_HANDLER *handler)
738 handler->eap_ds->request->code = PW_EAP_FAILURE;
739 eap_compose(handler);
743 * compose EAP SUCCESS packet in EAP-Message
745 void eap_success(EAP_HANDLER *handler)
747 handler->eap_ds->request->code = PW_EAP_SUCCESS;
748 eap_compose(handler);
752 * Basic EAP packet verfications & validations
754 static int eap_validation(eap_packet_t *eap_packet)
758 memcpy(&len, eap_packet->length, sizeof(uint16_t));
762 * High level EAP packet checks
764 if ((len <= EAP_HEADER_LEN) ||
765 ((eap_packet->code != PW_EAP_RESPONSE) &&
766 (eap_packet->code != PW_EAP_REQUEST)) ||
767 (eap_packet->data[0] <= 0) ||
768 (eap_packet->data[0] > PW_EAP_MAX_TYPES)) {
770 radlog(L_AUTH, "rlm_eap: Incorrect EAP Message, "
771 "Ignoring the packet");
775 /* we don't expect notification, but we send it */
776 if (eap_packet->data[0] == PW_EAP_NOTIFICATION) {
777 radlog(L_AUTH, "rlm_eap: Got NOTIFICATION, "
778 "Ignoring the packet");
787 * Get the user Identity only from EAP-Identity packets
789 static char *eap_identity(eap_packet_t *eap_packet)
795 if ((eap_packet == NULL) ||
796 (eap_packet->code != PW_EAP_RESPONSE) ||
797 (eap_packet->data[0] != PW_EAP_IDENTITY)) {
801 memcpy(&len, eap_packet->length, sizeof(uint16_t));
804 if ((len <= 5) || (eap_packet->data[1] == 0x00)) {
805 radlog(L_ERR, "rlm_eap: UserIdentity Unknown ");
810 identity = (char *)malloc(size + 1);
811 if (identity == NULL) {
812 radlog(L_ERR, "rlm_eap: out of memory");
815 memcpy(identity, &eap_packet->data[1], size);
816 identity[size] = '\0';
823 * Create our Request-Response data structure with the eap packet
825 static EAP_DS *eap_buildds(eap_packet_t **eap_packet_p)
827 EAP_DS *eap_ds = NULL;
828 eap_packet_t *eap_packet = *eap_packet_p;
832 if ((eap_ds = eap_ds_alloc()) == NULL) {
836 eap_ds->response->packet = (unsigned char *)eap_packet;
837 eap_ds->response->code = eap_packet->code;
838 eap_ds->response->id = eap_packet->id;
839 eap_ds->response->type.type = eap_packet->data[0];
841 memcpy(&len, eap_packet->length, sizeof(uint16_t));
843 eap_ds->response->length = len;
846 * We've eaten the eap packet into the eap_ds.
848 *eap_packet_p = NULL;
851 * First 5 bytes in eap, are code + id + length(2) + type.
853 * The rest is type-specific data. We skip type while
854 * getting typedata from data.
856 typelen = len - 5/*code + id + length + type */;
859 * Since the packet contains the complete
860 * eap_packet, typedata will be a ptr in packet
863 eap_ds->response->type.data = eap_ds->response->packet + 5/*code+id+length+type*/;
864 eap_ds->response->type.length = typelen;
866 eap_ds->response->type.length = 0;
867 eap_ds->response->type.data = NULL;
875 * If identity response then create a fresh handler & fill the identity
876 * else handler MUST be in our list, get that.
877 * This handler creation cannot fail
879 * username contains REQUEST->username which might have been stripped.
880 * identity contains the one sent in EAP-Identity response
882 EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
885 EAP_HANDLER *handler = NULL;
886 eap_packet_t *eap_packet = *eap_packet_p;
890 * Ensure it's a valid EAP-Request, or EAP-Response.
892 if (eap_validation(eap_packet) == EAP_INVALID) {
894 *eap_packet_p = NULL;
899 * EAP_HANDLER MUST be found in the list if it is not
900 * EAP-Identity response
902 if (eap_packet->data[0] != PW_EAP_IDENTITY) {
903 handler = eaplist_find(inst, request, eap_packet);
904 if (handler == NULL) {
905 /* Either send EAP_Identity or EAP-Fail */
906 radlog(L_ERR, "rlm_eap: Either EAP-request timed out OR"
907 " EAP-response to an unknown EAP-request");
909 *eap_packet_p = NULL;
914 * Even more paranoia. Without this, some weird
915 * clients could do crazy things.
917 * It's ok to send EAP sub-type NAK in response
918 * to a request for a particular type, but it's NOT
919 * OK to blindly return data for another type.
921 if ((eap_packet->data[0] != PW_EAP_NAK) &&
922 (eap_packet->data[0] != handler->eap_type)) {
923 radlog(L_ERR, "rlm_eap: Response appears to match, but EAP type is wrong.");
925 *eap_packet_p = NULL;
929 vp = pairfind(request->packet->vps, PW_USER_NAME);
932 * NAS did not set the User-Name
933 * attribute, so we set it here and
934 * prepend it to the beginning of the
935 * request vps so that autz's work
938 radlog(L_INFO, "rlm_eap: Broken NAS did not set User-Name, setting from EAP Identity");
939 vp = pairmake("User-Name", handler->identity, T_OP_EQ);
941 radlog(L_ERR, "rlm_eap: out of memory");
943 *eap_packet_p = NULL;
946 vp->next = request->packet->vps;
947 request->packet->vps = vp;
951 * A little more paranoia. If the NAS
952 * *did* set the User-Name, and it doesn't
953 * match the identity, (i.e. If they
954 * change their User-Name part way through
955 * the EAP transaction), then reject the
956 * request as the NAS is doing something
959 if (strncmp(handler->identity, vp->strvalue,
960 MAX_STRING_LEN) != 0) {
961 radlog(L_ERR, "rlm_eap: Identity does not match User-Name. Authentication failed.");
963 *eap_packet_p = NULL;
967 } else { /* packet was EAP identity */
968 handler = eap_handler_alloc();
969 if (handler == NULL) {
970 radlog(L_ERR, "rlm_eap: out of memory");
972 *eap_packet_p = NULL;
977 * All fields in the handler are set to zero.
979 handler->identity = eap_identity(eap_packet);
980 if (handler->identity == NULL) {
981 radlog(L_ERR, "rlm_eap: Identity Unknown, authentication failed");
983 *eap_packet_p = NULL;
984 eap_handler_free(&handler);
988 vp = pairfind(request->packet->vps, PW_USER_NAME);
991 * NAS did not set the User-Name
992 * attribute, so we set it here and
993 * prepend it to the beginning of the
994 * request vps so that autz's work
997 radlog(L_INFO, "rlm_eap: WARNING NAS did not set User-Name. Setting it locally from EAP Identity");
998 vp = pairmake("User-Name", handler->identity, T_OP_EQ);
1000 radlog(L_ERR, "rlm_eap: out of memory");
1001 free(*eap_packet_p);
1002 *eap_packet_p = NULL;
1005 vp->next = request->packet->vps;
1006 request->packet->vps = vp;
1009 * Paranoia. If the NAS *did* set the
1010 * User-Name, and it doesn't match the
1011 * identity, the NAS is doing something
1012 * funny, so reject the request.
1014 if (strncmp(handler->identity, vp->strvalue,
1015 MAX_STRING_LEN) != 0) {
1016 radlog(L_ERR, "rlm_eap: Identity does not match User-Name, setting from EAP Identity.");
1017 free(*eap_packet_p);
1018 *eap_packet_p = NULL;
1019 eap_handler_free(&handler);
1025 handler->eap_ds = eap_buildds(eap_packet_p);
1026 if (handler->eap_ds == NULL) {
1027 free(*eap_packet_p);
1028 *eap_packet_p = NULL;
1029 eap_handler_free(&handler);
1033 handler->timestamp = time(NULL);
1034 handler->request = request; /* LEAP needs this */