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