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