import from HEAD:
[freeradius.git] / src / modules / rlm_eap / eap.c
1 /*
2  * eap.c    rfc2284 & rfc2869 implementation
3  *
4  * Version:     $Id$
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
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>
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
57 #include "rlm_eap.h"
58
59 static const char rcsid[] = "$Id$";
60
61 static const char *eap_codes[] = {
62   "",                           /* 0 is invalid */
63   "request",
64   "response",
65   "success",
66   "failure"
67 };
68
69 /*
70  * Load all the required eap authentication types.
71  * Get all the supported EAP-types from config file.
72  */
73 int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
74 {
75         char            buffer[64];
76         char            namebuf[64];
77         const char      *eaptype_name;
78         lt_dlhandle     handle;
79         EAP_TYPES       *node;
80
81         eaptype_name = eaptype_type2name(eap_type, namebuf, sizeof(namebuf));
82         snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_name);
83
84         /* Link the loaded EAP-Type */
85         handle = lt_dlopenext(buffer);
86         if (handle == NULL) {
87                 radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
88                        eaptype_name, lt_dlerror());
89                 return -1;
90         }
91
92         /* Make room for the EAP-Type */
93         node = (EAP_TYPES *)malloc(sizeof(EAP_TYPES));
94         if (node == NULL) {
95                 radlog(L_ERR, "rlm_eap: out of memory");
96                 return -1;
97         }
98         memset(node, 0, sizeof(*node));
99
100         /* fill in the structure */
101         node->handle = handle;
102         node->cs = cs;
103
104         /*
105          *      In general, this is a terrible idea.  It works here
106          *      solely because the eap_type2name function returns a
107          *      'static const char *' pointer sometimes, and we can
108          *      ONLY link to module which are named in that static
109          *      array.
110          */
111         node->typename = eaptype_name;
112         node->type_data = NULL;
113
114         node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
115         if (!node->type) {
116                 radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
117                                 buffer, eaptype_name, lt_dlerror());
118                 lt_dlclose(node->handle);       /* ignore any errors */
119                 free(node);
120                 return -1;
121         }
122         if ((node->type->attach) &&
123             ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
124
125                 radlog(L_ERR, "rlm_eap: Failed to initialize type %s",
126                        eaptype_name);
127                 lt_dlclose(node->handle);
128                 free(node);
129                 return -1;
130         }
131
132         DEBUG("rlm_eap: Loaded and initialized type %s", eaptype_name);
133         *type = node;
134         return 0;
135 }
136
137 /*
138  * Call the appropriate handle with the right eap_type.
139  */
140 static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
141 {
142         int rcode = 1;
143
144         DEBUG2("  rlm_eap: processing type %s", atype->typename);
145
146         rad_assert(atype != NULL);
147
148         switch (handler->stage) {
149         case INITIATE:
150                 if (!atype->type->initiate(atype->type_data, handler))
151                         rcode = 0;
152                 break;
153
154         case AUTHORIZE:
155                 /*
156                  *   The called function updates the EAP reply packet.
157                  */
158                 if (!atype->type->authorize ||
159                     !atype->type->authorize(atype->type_data, handler))
160                         rcode = 0;
161                 break;
162
163         case AUTHENTICATE:
164                 /*
165                  *   The called function updates the EAP reply packet.
166                  */
167                 if (!atype->type->authenticate ||
168                     !atype->type->authenticate(atype->type_data, handler))
169                         rcode = 0;
170                 break;
171
172         default:
173                 /* Should never enter here */
174                 radlog(L_DBG, "rlm_eap: Invalid operation on eap_type");
175                 rcode = 0;
176                 break;
177         }
178
179         return rcode;
180 }
181
182 /*
183  * Based on TYPE, call the appropriate EAP-type handler
184  * Default to the configured EAP-Type
185  * for all Unsupported EAP-Types
186  */
187 int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
188 {
189         unsigned int    default_eap_type = inst->default_eap_type;
190         eaptype_t       *eaptype;
191         VALUE_PAIR      *vp;
192         char            namebuf[64];
193         const char      *eaptype_name;
194
195         eaptype = &handler->eap_ds->response->type;
196
197         /*
198          *      Don't trust anyone.
199          */
200         if ((eaptype->type == 0) ||
201             (eaptype->type > PW_EAP_MAX_TYPES)) {
202                 DEBUG2(" rlm_eap: Asked to select bad type");
203                 return EAP_INVALID;
204         }
205
206         /*
207          *      Figure out what to do.
208          */
209         switch(eaptype->type) {
210         case PW_EAP_IDENTITY:
211                 DEBUG2("  rlm_eap: EAP Identity");
212
213                 /*
214                  *      Allow per-user configuration of EAP types.
215                  */
216                 vp = pairfind(handler->request->config_items,
217                               PW_EAP_TYPE);
218                 if (vp) default_eap_type = vp->lvalue;
219
220         do_initiate:
221                 /*
222                  *      Ensure it's valid.
223                  */
224                 if ((default_eap_type < PW_EAP_MD5) ||
225                     (default_eap_type > PW_EAP_MAX_TYPES) ||
226                     (inst->types[default_eap_type] == NULL)) {
227                         DEBUG2(" rlm_eap: No such EAP type %s",
228                                eaptype_type2name(default_eap_type,
229                                                  namebuf, sizeof(namebuf)));
230                         return EAP_INVALID;
231                 }
232
233                 handler->stage = INITIATE;
234                 handler->eap_type = default_eap_type;
235
236                 /*
237                  *      Wild & crazy stuff!  For TTLS & PEAP, we
238                  *      initiate a TLS session, and then pass that
239                  *      session data to TTLS or PEAP for the
240                  *      authenticate stage.
241                  *
242                  *      Handler->eap_type holds the TRUE type.
243                  */
244                 if ((default_eap_type == PW_EAP_TTLS) ||
245                     (default_eap_type == PW_EAP_PEAP)) {
246                         default_eap_type = PW_EAP_TLS;
247                 }
248
249
250                 /*
251                  *      We don't do TLS inside of TLS, as it's a bad
252                  *      idea...
253                  */
254                 if (((handler->request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) &&
255                     (default_eap_type == PW_EAP_TLS)) {
256                         DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS");
257                         return EAP_INVALID;
258                 }
259
260                 if (eaptype_call(inst->types[default_eap_type],
261                                  handler) == 0) {
262                         DEBUG2(" rlm_eap: Default EAP type %s failed in initiate",
263                                eaptype_type2name(default_eap_type,
264                                                  namebuf, sizeof(namebuf)));
265                         return EAP_INVALID;
266                 }
267                 break;
268
269         case PW_EAP_NAK:
270                 /*
271                  *      The NAK data is the preferred EAP type(s) of
272                  *      the client.
273                  *
274                  *      RFC 3748 says to list one or more proposed
275                  *      alternative types, one per octet, or to use
276                  *      0 for no alternative.
277                  */
278                 DEBUG2("  rlm_eap: EAP NAK");
279
280                 /*
281                  *      Delete old data, if necessary.
282                  */
283                 if (handler->opaque && handler->free_opaque) {
284                         handler->free_opaque(handler->opaque);
285                         handler->free_opaque = NULL;
286                         handler->opaque = NULL;
287                 }
288
289                 /*
290                  *      It is invalid to request identity,
291                  *      notification & nak in nak
292                  */
293                 if (eaptype->data == NULL) {
294                         DEBUG2(" rlm_eap: Empty NAK packet, cannot decide what EAP type the client wants.");
295                         return EAP_INVALID;
296                 }
297
298                 /*
299                  *      FIXME: Pick one type out of the one they asked
300                  *      for, as they may have asked for many.
301                  */
302                 if ((eaptype->data[0] < PW_EAP_MD5) ||
303                     (eaptype->data[0] > PW_EAP_MAX_TYPES)) {
304                         DEBUG2(" rlm_eap: NAK asked for bad type %d",
305                                eaptype->data[0]);
306                         return EAP_INVALID;
307                 }
308
309                 default_eap_type = eaptype->data[0];
310                 eaptype_name = eaptype_type2name(default_eap_type,
311                                                  namebuf, sizeof(namebuf));
312                 DEBUG2(" rlm_eap: EAP-NAK asked for EAP-Type/%s",
313                        eaptype_name);
314
315                 /*
316                  *      Prevent a firestorm if the client is confused.
317                  */
318                 if (handler->eap_type == default_eap_type) {
319                         DEBUG2(" rlm_eap: ERROR! Our request for %s was NAK'd with a request for %s, what is the client thinking?",
320                                eaptype_name, eaptype_name);
321                         return EAP_INVALID;
322                 }
323
324                 /*
325                  *      Enforce per-user configuration of EAP types.
326                  */
327                 vp = pairfind(handler->request->config_items,
328                               PW_EAP_TYPE);
329                 if (vp && (vp->lvalue != default_eap_type)) {
330                         char    mynamebuf[64];
331                         DEBUG2("  rlm_eap: Client wants %s, while we require %s, rejecting the user.",
332                                eaptype_name,
333                                eaptype_type2name(vp->lvalue,
334                                                  mynamebuf,
335                                                  sizeof(mynamebuf)));
336                         return EAP_INVALID;
337                 }
338                 goto do_initiate;
339                 break;
340
341                 /*
342                  *      Key off of the configured sub-modules.
343                  */
344                 default:
345                         eaptype_name = eaptype_type2name(eaptype->type,
346                                                          namebuf,
347                                                          sizeof(namebuf));
348                         DEBUG2("  rlm_eap: EAP/%s", eaptype_name);
349
350                         /*
351                          *      We haven't configured it, it doesn't exit.
352                          */
353                         if (!inst->types[eaptype->type]) {
354                                 DEBUG2(" rlm_eap: EAP type %d is unsupported",
355                                        eaptype->type);
356                                 return EAP_INVALID;
357                         }
358
359                         rad_assert(handler->stage == AUTHENTICATE);
360                         handler->eap_type = eaptype->type;
361                         if (eaptype_call(inst->types[eaptype->type],
362                                          handler) == 0) {
363                                 DEBUG2(" rlm_eap: Handler failed in EAP/%s",
364                                        eaptype_name);
365                                 return EAP_INVALID;
366                         }
367                 break;
368         }
369
370         return EAP_OK;
371 }
372
373
374 /*
375  *      EAP packet format to be sent over the wire
376  *
377  *      i.e. code+id+length+data where data = null/type+typedata
378  *      based on code.
379  */
380 static int eap_wireformat(EAP_PACKET *reply)
381 {
382         eap_packet_t    *hdr;
383         uint16_t total_length = 0;
384
385         if (reply == NULL) return EAP_INVALID;
386
387         total_length = EAP_HEADER_LEN;
388         if (reply->code < 3) {
389                 total_length += 1/*EAPtype*/;
390                 if (reply->type.data && reply->type.length > 0) {
391                         total_length += reply->type.length;
392                 }
393         }
394
395         reply->packet = (unsigned char *)malloc(total_length);
396         hdr = (eap_packet_t *)reply->packet;
397         if (!hdr) {
398                 radlog(L_ERR, "rlm_eap: out of memory");
399                 return EAP_INVALID;
400         }
401
402         hdr->code = (reply->code & 0xFF);
403         hdr->id = (reply->id & 0xFF);
404         total_length = htons(total_length);
405         memcpy(hdr->length, &total_length, sizeof(uint16_t));
406
407         /*
408          *      Request and Response packets are special.
409          */
410         if ((reply->code == PW_EAP_REQUEST) ||
411             (reply->code == PW_EAP_RESPONSE)) {
412                 hdr->data[0] = (reply->type.type & 0xFF);
413
414                 /*
415                  * Here since we cannot know the typedata format and length
416                  *
417                  * Type_data is expected to be wired by each EAP-Type
418                  *
419                  * Zero length/No typedata is supported as long as
420                  * type is defined
421                  */
422                 if (reply->type.data && reply->type.length > 0) {
423                         memcpy(&hdr->data[1], reply->type.data, reply->type.length);
424                         free(reply->type.data);
425                         reply->type.data = reply->packet + EAP_HEADER_LEN + 1/*EAPtype*/;
426                 }
427         }
428
429         return EAP_VALID;
430 }
431
432 /*
433  *      compose EAP reply packet in EAP-Message attr of RADIUS.  If
434  *      EAP exceeds 253, frame it in multiple EAP-Message attrs.
435  *
436  *      Set the RADIUS reply codes based on EAP request codes.  Append
437  *      any additonal VPs to RADIUS reply
438  */
439 int eap_compose(EAP_HANDLER *handler)
440 {
441         uint16_t eap_len, len;
442         VALUE_PAIR *eap_msg;
443         VALUE_PAIR *vp;
444         eap_packet_t *eap_packet;
445         unsigned char   *ptr;
446         REQUEST *request = handler->request;
447         EAP_DS *eap_ds = handler->eap_ds;
448         EAP_PACKET *reply = eap_ds->request;
449         int rcode;
450
451         /*
452          *      The Id for the EAP packet to the NAS wasn't set.
453          *      Do so now.
454          *
455          *      LEAP requires the Id to be incremented on EAP-Success
456          *      in Stage 4, so that we can carry on the conversation
457          *      where the client asks us to authenticate ourselves
458          *      in stage 5.
459          */
460         if (!eap_ds->set_request_id) {
461                 /*
462                  *      Id serves to suppport request/response
463                  *      retransmission in the EAP layer and as such
464                  *      must be different for 'adjacent' packets
465                  *      except in case of success/failure-replies.
466                  *
467                  *      RFC2716 (EAP-TLS) requires this to be
468                  *      incremented, RFC2284 only makes the above-
469                  *      mentioned restriction.
470                  */
471                 reply->id = handler->eap_ds->response->id;
472
473                 switch (reply->code) {
474                         /*
475                          *      The Id is a simple "ack" for success
476                          *      and failure.
477                          *
478                          *      RFC 3748 section 4.2 says
479                          *
480                          *      ... The Identifier field MUST match
481                          *      the Identifier field of the Response
482                          *      packet that it is sent in response
483                          *      to.
484                          */
485                 case PW_EAP_SUCCESS:
486                 case PW_EAP_FAILURE:
487                         break;
488
489                         /*
490                          *      We've sent a response to their
491                          *      request, the Id is incremented.
492                          */
493                 default:
494                         ++reply->id;
495                 }
496         } else {
497                 DEBUG2("  rlm_eap: Underlying EAP-Type set EAP ID to %d",
498                        reply->id);
499         }
500
501         /*
502          *      For Request & Response packets, set the EAP sub-type,
503          *      if the EAP sub-module didn't already set it.
504          *
505          *      This allows the TLS module to be "morphic", and means
506          *      that the TTLS and PEAP modules can call it to do most
507          *      of their dirty work.
508          */
509         if (((eap_ds->request->code == PW_EAP_REQUEST) ||
510              (eap_ds->request->code == PW_EAP_RESPONSE)) &&
511             (eap_ds->request->type.type == 0)) {
512                 rad_assert(handler->eap_type >= PW_EAP_MD5);
513                 rad_assert(handler->eap_type <= PW_EAP_MAX_TYPES);
514
515                 eap_ds->request->type.type = handler->eap_type;
516         }
517
518
519         if (eap_wireformat(reply) == EAP_INVALID) {
520                 return RLM_MODULE_INVALID;
521         }
522         eap_packet = (eap_packet_t *)reply->packet;
523
524         memcpy(&eap_len, &(eap_packet->length), sizeof(uint16_t));
525         len = eap_len = ntohs(eap_len);
526         ptr = (unsigned char *)eap_packet;
527
528         do {
529                 if (eap_len > 253) {
530                         len = 253;
531                         eap_len -= 253;
532                 } else {
533                         len = eap_len;
534                         eap_len = 0;
535                 }
536
537                 /*
538                  * create a value pair & append it to the request reply list
539                  * This memory gets freed up when request is freed up
540                  */
541                 eap_msg = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);
542                 memcpy(eap_msg->strvalue, ptr, len);
543                 eap_msg->length = len;
544                 pairadd(&(request->reply->vps), eap_msg);
545                 ptr += len;
546                 eap_msg = NULL;
547         } while (eap_len);
548
549         /*
550          *      EAP-Message is always associated with
551          *      Message-Authenticator but not vice-versa.
552          *
553          *      Don't add a Message-Authenticator if it's already
554          *      there.
555          */
556         vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);
557         if (!vp) {
558                 vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
559                 memset(vp->strvalue, 0, AUTH_VECTOR_LEN);
560                 vp->length = AUTH_VECTOR_LEN;
561                 pairadd(&(request->reply->vps), vp);
562         }
563
564         /* Set request reply code, but only if it's not already set. */
565         rcode = RLM_MODULE_OK;
566         if (!request->reply->code) switch(reply->code) {
567         case PW_EAP_RESPONSE:
568                 request->reply->code = PW_AUTHENTICATION_ACK;
569                 rcode = RLM_MODULE_HANDLED; /* leap weirdness */
570                 break;
571         case PW_EAP_SUCCESS:
572                 request->reply->code = PW_AUTHENTICATION_ACK;
573                 rcode = RLM_MODULE_OK;
574                 break;
575         case PW_EAP_FAILURE:
576                 request->reply->code = PW_AUTHENTICATION_REJECT;
577                 rcode = RLM_MODULE_REJECT;
578                 break;
579         case PW_EAP_REQUEST:
580                 request->reply->code = PW_ACCESS_CHALLENGE;
581                 rcode = RLM_MODULE_HANDLED;
582                 break;
583         default:
584                 /*
585                  *      When we're pulling MS-CHAPv2 out of EAP-MS-CHAPv2,
586                  *      we do so WITHOUT setting a reply code, as the
587                  *      request is being proxied.
588                  */
589                 if (request->options & RAD_REQUEST_OPTION_PROXY_EAP) {
590                         return RLM_MODULE_HANDLED;
591                 }
592
593                 /* Should never enter here */
594                 radlog(L_ERR, "rlm_eap: reply code %d is unknown, Rejecting the request.", reply->code);
595                 request->reply->code = PW_AUTHENTICATION_REJECT;
596                 reply->code = PW_EAP_FAILURE;
597                 rcode = RLM_MODULE_REJECT;
598                 break;
599         }
600
601         return rcode;
602 }
603
604 /*
605  * Radius criteria, EAP-Message is invalid without Message-Authenticator
606  * For EAP_START, send Access-Challenge with EAP Identity request.
607  */
608 int eap_start(rlm_eap_t *inst, REQUEST *request)
609 {
610         VALUE_PAIR *vp, *proxy;
611         VALUE_PAIR *eap_msg;
612
613         eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE);
614         if (eap_msg == NULL) {
615                 DEBUG2("  rlm_eap: No EAP-Message, not doing EAP");
616                 return EAP_NOOP;
617         }
618
619         /*
620          *      Look for EAP-Type = None (FreeRADIUS specific attribute)
621          *      this allows you to NOT do EAP for some users.
622          */
623         vp = pairfind(request->packet->vps, PW_EAP_TYPE);
624         if (vp && vp->lvalue == 0) {
625                 DEBUG2("  rlm_eap: Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
626                 return EAP_NOOP;
627         }
628
629         /*
630          *      http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
631          *
632          *      Checks for Message-Authenticator are handled by rad_recv().
633          */
634
635         /*
636          *      Check for a Proxy-To-Realm.  Don't get excited over LOCAL
637          *      realms (sigh).
638          */
639         proxy = pairfind(request->config_items, PW_PROXY_TO_REALM);
640         if (proxy) {
641                 REALM *realm;
642
643                 /*
644                  *      If it's a LOCAL realm, then we're not proxying
645                  *      to it.
646                  */
647                 realm = realm_find(proxy->strvalue, 0);
648                 if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {
649                         proxy = NULL;
650                 }
651         }
652
653         /*
654          *      Check the length before de-referencing the contents.
655          *
656          *      Lengths of zero are required by the RFC for EAP-Start,
657          *      but we've never seen them in practice.
658          *
659          *      Lengths of two are what we see in practice as
660          *      EAP-Starts.
661          */
662         if ((eap_msg->length == 0) || (eap_msg->length == 2)) {
663                 EAP_DS *eap_ds;
664                 EAP_HANDLER handler;
665
666                 /*
667                  *      It's a valid EAP-Start, but the request
668                  *      was marked as being proxied.  So we don't
669                  *      do EAP, as the home server will do it.
670                  */
671                 if (proxy) {
672                 do_proxy:
673                         DEBUG2("  rlm_eap: Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->strvalue);
674                         return EAP_NOOP;
675                 }
676                 
677                 DEBUG2("  rlm_eap: Got EAP_START message");
678                 if ((eap_ds = eap_ds_alloc()) == NULL) {
679                         DEBUG2("  rlm_eap: EAP Start failed in allocation");
680                         return EAP_FAIL;
681                 }
682                 
683                 /*
684                  *      It's an EAP-Start packet.  Tell them to stop wasting
685                  *      our time, and give us an EAP-Identity packet.
686                  *
687                  *      Hmm... we should probably check the contents of the
688                  *      EAP-Start packet for something...
689                  */
690                 eap_ds->request->code = PW_EAP_REQUEST;
691                 eap_ds->request->type.type = PW_EAP_IDENTITY;
692                 
693                 /*
694                  *      We don't have a handler, but eap_compose needs one,
695                  *      (for various reasons), so we fake it out here.
696                  */
697                 memset(&handler, 0, sizeof(handler));
698                 handler.request = request;
699                 handler.eap_ds = eap_ds;
700                 
701                 eap_compose(&handler);
702                 
703                 eap_ds_free(&eap_ds);
704                 return EAP_FOUND;
705         } /* end of handling EAP-Start */
706
707         /*
708          *      The EAP packet header is 4 bytes, plus one byte of
709          *      EAP sub-type.  Short packets are discarded, unless
710          *      we're proxying.
711          */
712         if (eap_msg->length < (EAP_HEADER_LEN + 1)) {
713                 if (proxy) goto do_proxy;
714
715                 DEBUG2("  rlm_eap: Ignoring EAP-Message which is too short to be meaningful.");
716                 return EAP_FAIL;
717         }
718
719         /*
720          *      Create an EAP-Type containing the EAP-type
721          *      from the packet.
722          */
723         vp = paircreate(PW_EAP_TYPE, PW_TYPE_INTEGER);
724         if (vp) {
725                 vp->lvalue = eap_msg->strvalue[4];
726                 pairadd(&(request->packet->vps), vp);
727         }
728
729         /*
730          *      If the request was marked to be proxied, do it now.
731          *      This is done after checking for a valid length
732          *      (which may not be good), and after adding the EAP-Type
733          *      attribute.  This lets other modules selectively cancel
734          *      proxying based on EAP-Type.
735          */
736         if (proxy) goto do_proxy;
737
738         /*
739          *      From now on, we're supposed to be handling the
740          *      EAP packet.  We better understand it...
741          */
742
743         /*
744          *      We're allowed only a few codes.  Request, Response,
745          *      Success, or Failure.
746          */
747         if ((eap_msg->strvalue[0] == 0) ||
748             (eap_msg->strvalue[0] > PW_EAP_MAX_CODES)) {
749                 DEBUG2("  rlm_eap: Unknown EAP packet");
750         } else {
751                 DEBUG2("  rlm_eap: EAP packet type %s id %d length %d",
752                        eap_codes[eap_msg->strvalue[0]],
753                        eap_msg->strvalue[1],
754                        eap_msg->length);
755         }
756
757         /*
758          *      We handle request and responses.  The only other defined
759          *      codes are success and fail.  The client SHOULD NOT be
760          *      sending success/fail packets to us, as it doesn't make
761          *      sense.
762          */
763         if ((eap_msg->strvalue[0] != PW_EAP_REQUEST) &&
764             (eap_msg->strvalue[0] != PW_EAP_RESPONSE)) {
765                 DEBUG2("  rlm_eap: Ignoring EAP packet which we don't know how to handle.");
766                 return EAP_FAIL;
767         }
768
769         /*
770          *      We've been told to ignore unknown EAP types, AND it's
771          *      an unknown type.  Return "NOOP", which will cause the
772          *      eap_authorize() to return NOOP.
773          *
774          *      EAP-Identity, Notification, and NAK are all handled
775          *      internally, so they never have handlers.
776          */
777         if ((eap_msg->strvalue[4] >= PW_EAP_MD5) &&
778             inst->ignore_unknown_eap_types &&
779             ((eap_msg->strvalue[4] == 0) ||
780              (eap_msg->strvalue[4] > PW_EAP_MAX_TYPES) ||
781              (inst->types[eap_msg->strvalue[4]] == NULL))) {
782                 DEBUG2("  rlm_eap:  Ignoring Unknown EAP type");
783                 return EAP_NOOP;
784         }
785                 
786         /*
787          *      They're NAKing the EAP type we wanted to use, and
788          *      asking for one which we don't support.
789          *
790          *      NAK is code + id + length1 + length + NAK
791          *             + requested EAP type(s).
792          *
793          *      We know at this point that we can't handle the
794          *      request.  We could either return an EAP-Fail here, but
795          *      it's not too critical.
796          *
797          *      By returning "noop", we can ensure that authorize()
798          *      returns NOOP, and another module may choose to proxy
799          *      the request.
800          */
801         if ((eap_msg->strvalue[4] == PW_EAP_NAK) &&
802             (eap_msg->length >= (EAP_HEADER_LEN + 2)) &&
803             inst->ignore_unknown_eap_types &&
804             ((eap_msg->strvalue[5] == 0) ||
805              (eap_msg->strvalue[5] > PW_EAP_MAX_TYPES) ||
806              (inst->types[eap_msg->strvalue[5]] == NULL))) {
807                 DEBUG2("  rlm_eap: Ignoring NAK with request for unknown EAP type");
808                 return EAP_NOOP;
809         }
810
811         /*
812          *      Later EAP messages are longer than the 'start'
813          *      message, so if everything is OK, this function returns
814          *      'no start found', so that the rest of the EAP code can
815          *      use the State attribute to match this EAP-Message to
816          *      an ongoing conversation.
817          */
818         DEBUG2("  rlm_eap: No EAP Start, assuming it's an on-going EAP conversation");
819
820         return EAP_NOTFOUND;
821 }
822
823 /*
824  *      compose EAP FAILURE packet in EAP-Message
825  */
826 void eap_fail(EAP_HANDLER *handler)
827 {
828         handler->eap_ds->request->code = PW_EAP_FAILURE;
829         eap_compose(handler);
830 }
831
832 /*
833  *      compose EAP SUCCESS packet in EAP-Message
834  */
835 void eap_success(EAP_HANDLER *handler)
836 {
837         handler->eap_ds->request->code = PW_EAP_SUCCESS;
838         eap_compose(handler);
839 }
840
841 /*
842  * Basic EAP packet verfications & validations
843  */
844 static int eap_validation(eap_packet_t *eap_packet)
845 {
846         uint16_t len;
847
848         memcpy(&len, eap_packet->length, sizeof(uint16_t));
849         len = ntohs(len);
850
851         /*
852          *      High level EAP packet checks
853          */
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)) {
859
860                 radlog(L_AUTH, "rlm_eap: Incorrect EAP Message, "
861                                 "Ignoring the packet");
862                 return EAP_INVALID;
863         }
864
865         /* we don't expect notification, but we send it */
866         if (eap_packet->data[0] == PW_EAP_NOTIFICATION) {
867                 radlog(L_AUTH, "rlm_eap: Got NOTIFICATION, "
868                                 "Ignoring the packet");
869                 return EAP_INVALID;
870         }
871
872         return EAP_VALID;
873 }
874
875
876 /*
877  *  Get the user Identity only from EAP-Identity packets
878  */
879 static char *eap_identity(eap_packet_t *eap_packet)
880 {
881         int size;
882         uint16_t len;
883         char *identity;
884
885         if ((eap_packet == NULL) ||
886             (eap_packet->code != PW_EAP_RESPONSE) ||
887             (eap_packet->data[0] != PW_EAP_IDENTITY)) {
888                 return NULL;
889         }
890
891         memcpy(&len, eap_packet->length, sizeof(uint16_t));
892         len = ntohs(len);
893
894         if ((len <= 5) || (eap_packet->data[1] == 0x00)) {
895                 radlog(L_ERR, "rlm_eap: UserIdentity Unknown ");
896                 return NULL;
897         }
898
899         size = len - 5;
900         identity = (char *)malloc(size + 1);
901         if (identity == NULL) {
902                 radlog(L_ERR, "rlm_eap: out of memory");
903                 return NULL;
904         }
905         memcpy(identity, &eap_packet->data[1], size);
906         identity[size] = '\0';
907
908         return identity;
909 }
910
911
912 /*
913  *      Create our Request-Response data structure with the eap packet
914  */
915 static EAP_DS *eap_buildds(eap_packet_t **eap_packet_p)
916 {
917         EAP_DS          *eap_ds = NULL;
918         eap_packet_t    *eap_packet = *eap_packet_p;
919         int             typelen;
920         uint16_t        len;
921
922         if ((eap_ds = eap_ds_alloc()) == NULL) {
923                 return NULL;
924         }
925
926         eap_ds->response->packet = (unsigned char *)eap_packet;
927         eap_ds->response->code = eap_packet->code;
928         eap_ds->response->id = eap_packet->id;
929         eap_ds->response->type.type = eap_packet->data[0];
930
931         memcpy(&len, eap_packet->length, sizeof(uint16_t));
932         len = ntohs(len);
933         eap_ds->response->length = len;
934
935         /*
936          *      We've eaten the eap packet into the eap_ds.
937          */
938         *eap_packet_p = NULL;
939
940         /*
941          *      First 5 bytes in eap, are code + id + length(2) + type.
942          *
943          *      The rest is type-specific data.  We skip type while
944          *      getting typedata from data.
945          */
946         typelen = len - 5/*code + id + length + type */;
947         if (typelen > 0) {
948                 /*
949                  *      Since the packet contains the complete
950                  *      eap_packet, typedata will be a ptr in packet
951                  *      to its typedata
952                  */
953                 eap_ds->response->type.data = eap_ds->response->packet + 5/*code+id+length+type*/;
954                 eap_ds->response->type.length = typelen;
955         } else {
956                 eap_ds->response->type.length = 0;
957                 eap_ds->response->type.data = NULL;
958         }
959
960         return eap_ds;
961 }
962
963
964 /*
965  * If identity response then create a fresh handler & fill the identity
966  * else handler MUST be in our list, get that.
967  * This handler creation cannot fail
968  *
969  * username contains REQUEST->username which might have been stripped.
970  * identity contains the one sent in EAP-Identity response
971  */
972 EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
973                          REQUEST *request)
974 {
975         EAP_HANDLER     *handler = NULL;
976         eap_packet_t    *eap_packet = *eap_packet_p;
977         VALUE_PAIR      *vp;
978
979         /*
980          *      Ensure it's a valid EAP-Request, or EAP-Response.
981          */
982         if (eap_validation(eap_packet) == EAP_INVALID) {
983                 free(*eap_packet_p);
984                 *eap_packet_p = NULL;
985                 return NULL;
986         }
987
988         /*
989          *      EAP_HANDLER MUST be found in the list if it is not
990          *      EAP-Identity response
991          */
992         if (eap_packet->data[0] != PW_EAP_IDENTITY) {
993                 handler = eaplist_find(inst, request, eap_packet);
994                 if (handler == NULL) {
995                         /* Either send EAP_Identity or EAP-Fail */
996                         radlog(L_ERR, "rlm_eap: Either EAP-request timed out OR"
997                                 " EAP-response to an unknown EAP-request");
998                         free(*eap_packet_p);
999                         *eap_packet_p = NULL;
1000                         return NULL;
1001                 }
1002
1003                 /*
1004                  *      Even more paranoia.  Without this, some weird
1005                  *      clients could do crazy things.
1006                  *
1007                  *      It's ok to send EAP sub-type NAK in response
1008                  *      to a request for a particular type, but it's NOT
1009                  *      OK to blindly return data for another type.
1010                  */
1011                 if ((eap_packet->data[0] != PW_EAP_NAK) &&
1012                     (eap_packet->data[0] != handler->eap_type)) {
1013                         radlog(L_ERR, "rlm_eap: Response appears to match, but EAP type is wrong.");
1014                         free(*eap_packet_p);
1015                         *eap_packet_p = NULL;
1016                         return NULL;
1017                 }
1018
1019                vp = pairfind(request->packet->vps, PW_USER_NAME);
1020                if (!vp) {
1021                        /*
1022                         *       NAS did not set the User-Name
1023                         *       attribute, so we set it here and
1024                         *       prepend it to the beginning of the
1025                         *       request vps so that autz's work
1026                         *       correctly
1027                         */
1028                        radlog(L_INFO, "rlm_eap: Broken NAS did not set User-Name, setting from EAP Identity");
1029                        vp = pairmake("User-Name", handler->identity, T_OP_EQ);
1030                        if (vp == NULL) {
1031                                radlog(L_ERR, "rlm_eap: out of memory");
1032                                free(*eap_packet_p);
1033                                *eap_packet_p = NULL;
1034                                return NULL;
1035                        }
1036                        vp->next = request->packet->vps;
1037                        request->packet->vps = vp;
1038
1039                } else {
1040                        /*
1041                         *      A little more paranoia.  If the NAS
1042                         *      *did* set the User-Name, and it doesn't
1043                         *      match the identity, (i.e. If they
1044                         *      change their User-Name part way through
1045                         *      the EAP transaction), then reject the
1046                         *      request as the NAS is doing something
1047                         *      funny.
1048                         */
1049                        if (strncmp(handler->identity, vp->strvalue,
1050                                    MAX_STRING_LEN) != 0) {
1051                                radlog(L_ERR, "rlm_eap: Identity does not match User-Name.  Authentication failed.");
1052                                free(*eap_packet_p);
1053                                *eap_packet_p = NULL;
1054                                return NULL;
1055                        }
1056                }
1057         } else {                /* packet was EAP identity */
1058                 handler = eap_handler_alloc();
1059                 if (handler == NULL) {
1060                         radlog(L_ERR, "rlm_eap: out of memory");
1061                         free(*eap_packet_p);
1062                         *eap_packet_p = NULL;
1063                         return NULL;
1064                 }
1065
1066                 /*
1067                  *      All fields in the handler are set to zero.
1068                  */
1069                 handler->identity = eap_identity(eap_packet);
1070                 if (handler->identity == NULL) {
1071                         radlog(L_ERR, "rlm_eap: Identity Unknown, authentication failed");
1072                         free(*eap_packet_p);
1073                         *eap_packet_p = NULL;
1074                         eap_handler_free(handler);
1075                         return NULL;
1076                 }
1077
1078                vp = pairfind(request->packet->vps, PW_USER_NAME);
1079                if (!vp) {
1080                        /*
1081                         *       NAS did not set the User-Name
1082                         *       attribute, so we set it here and
1083                         *       prepend it to the beginning of the
1084                         *       request vps so that autz's work
1085                         *       correctly
1086                         */
1087                        radlog(L_INFO, "rlm_eap: WARNING NAS did not set User-Name.  Setting it locally from EAP Identity");
1088                        vp = pairmake("User-Name", handler->identity, T_OP_EQ);
1089                        if (vp == NULL) {
1090                                radlog(L_ERR, "rlm_eap: out of memory");
1091                                free(*eap_packet_p);
1092                                *eap_packet_p = NULL;
1093                                return NULL;
1094                        }
1095                        vp->next = request->packet->vps;
1096                        request->packet->vps = vp;
1097                } else {
1098                        /*
1099                         *      Paranoia.  If the NAS *did* set the
1100                         *      User-Name, and it doesn't match the
1101                         *      identity, the NAS is doing something
1102                         *      funny, so reject the request.
1103                         */
1104                        if (strncmp(handler->identity, vp->strvalue,
1105                                    MAX_STRING_LEN) != 0) {
1106                                radlog(L_ERR, "rlm_eap: Identity does not match User-Name, setting from EAP Identity.");
1107                                free(*eap_packet_p);
1108                                *eap_packet_p = NULL;
1109                                eap_handler_free(handler);
1110                                return NULL;
1111                        }
1112                }
1113         }
1114
1115         handler->eap_ds = eap_buildds(eap_packet_p);
1116         if (handler->eap_ds == NULL) {
1117                 free(*eap_packet_p);
1118                 *eap_packet_p = NULL;
1119                 eap_handler_free(handler);
1120                 return NULL;
1121         }
1122
1123         handler->timestamp = request->timestamp;
1124         handler->request = request; /* LEAP needs this */
1125         return handler;
1126 }