Update the GPL boilerplate with the new address of the FSF.
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_ttls / ttls.c
1 /*
2  * rlm_eap_ttls.c  contains the interfaces that are called from eap
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 2003 Alan DeKok <aland@freeradius.org>
21  */
22 #include "eap_ttls.h"
23
24 /*
25  *    0                   1                   2                   3
26  *    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
27  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28  *   |                           AVP Code                            |
29  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30  *   |V M r r r r r r|                  AVP Length                   |
31  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32  *   |                        Vendor-ID (opt)                        |
33  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34  *   |    Data ...
35  *   +-+-+-+-+-+-+-+-+
36  */
37
38 /*
39  *      Verify that the diameter packet is valid.
40  */
41 static int diameter_verify(const uint8_t *data, unsigned int data_len)
42 {
43         uint32_t attr;
44         uint32_t length;
45         unsigned int offset;
46         unsigned int data_left = data_len;
47
48         while (data_left > 0) {
49                 rad_assert(data_left <= data_len);
50                 memcpy(&attr, data, sizeof(attr));
51                 data += 4;
52                 attr = ntohl(attr);
53                 if (attr > 255) {
54                         DEBUG2("  rlm_eap_ttls:  Non-RADIUS attribute in tunneled authentication is not supported");
55                         return 0;
56                 }
57
58                 memcpy(&length, data , sizeof(length));
59                 data += 4;
60                 length = ntohl(length);
61
62                 /*
63                  *      A "vendor" flag, with a vendor ID of zero,
64                  *      is equivalent to no vendor.  This is stupid.
65                  */
66                 offset = 8;
67                 if ((length & (1 << 31)) != 0) {
68                         int attribute;
69                         uint32_t vendor;
70                         DICT_ATTR *da;
71
72                         memcpy(&vendor, data, sizeof(vendor));
73                         vendor = ntohl(vendor);
74
75                         if (vendor > 65535) {
76                                 DEBUG2("  rlm_eap_ttls: Vendor codes larger than 65535 are not supported");
77                                 return 0;
78                         }
79
80                         attribute = (vendor << 16) | attr;
81
82                         da = dict_attrbyvalue(attribute);
83
84                         /*
85                          *      SHOULD check ((length & (1 << 30)) != 0)
86                          *      for the mandatory bit.
87                          */
88                         if (!da) {
89                                 DEBUG2("  rlm_eap_ttls: Fatal! Vendor %u, Attribute %u was not found in our dictionary. ",
90                                        vendor, attr);
91                                 return 0;
92                         }
93
94                         data += 4; /* skip the vendor field */
95                         offset += 4; /* offset to value field */
96                 }
97
98                 /*
99                  *      Ignore the M bit.  We support all RADIUS attributes...
100                  */
101
102                 /*
103                  *      Get the length.  If it's too big, die.
104                  */
105                 length &= 0x00ffffff;
106
107                 /*
108                  *      Too short or too long is bad.
109                  *
110                  *      FIXME: EAP-Message
111                  */
112                 if (length < offset) {
113                         DEBUG2("  rlm_eap_ttls: Tunneled attribute %d is too short (%d)to contain anything useful.", attr, length);
114                         return 0;
115                 }
116
117                 if (length > (MAX_STRING_LEN + 8)) {
118                         DEBUG2("  rlm_eap_ttls: Tunneled attribute %d is too long (%d) to pack into a RADIUS attribute.", attr, length);
119                         return 0;
120                 }
121                     
122                 if (length > data_left) {
123                         DEBUG2("  rlm_eap_ttls: Tunneled attribute %d is longer than room left in the packet (%d > %d).", attr, length, data_left);
124                         return 0;
125                 }
126
127                 /*
128                  *      Check for broken implementations, which don't
129                  *      pad the AVP to a 4-octet boundary.
130                  */
131                 if (data_left == length) break;
132
133                 /*
134                  *      The length does NOT include the padding, so
135                  *      we've got to account for it here by rounding up
136                  *      to the nearest 4-byte boundary.
137                  */
138                 length += 0x03;
139                 length &= ~0x03;
140
141                 /*
142                  *      If the rest of the diameter packet is larger than
143                  *      this attribute, continue.
144                  *
145                  *      Otherwise, if the attribute over-flows the end
146                  *      of the packet, die.
147                  */
148                 if (data_left < length) {
149                         DEBUG2("  rlm_eap_ttls: ERROR! Diameter attribute overflows packet!");
150                         return 0;
151                 }
152         
153                 /*
154                  *      Check again for equality, now that we're padded
155                  *      length to a multiple of 4 octets.
156                  */
157                 if (data_left == length) break;
158
159                 /*
160                  *      data_left > length, continue.
161                  */
162                 data_left -= length;
163                 data += length - offset;
164         }
165
166         /*
167          *      We got this far.  It looks OK.
168          */
169         return 1;
170 }
171
172
173 /*
174  *      Convert diameter attributes to our VALUE_PAIR's
175  */
176 static VALUE_PAIR *diameter2vp(SSL *ssl,
177                                const uint8_t *data, unsigned int data_len)
178 {
179         uint32_t        attr;
180         uint32_t        length;
181         unsigned int    offset;
182         int             size;
183         unsigned int    data_left = data_len;
184         VALUE_PAIR      *first = NULL;
185         VALUE_PAIR      **last = &first;
186         VALUE_PAIR      *vp;
187
188         while (data_left > 0) {
189                 rad_assert(data_left <= data_len);
190                 memcpy(&attr, data, sizeof(attr));
191                 data += 4;
192                 attr = ntohl(attr);
193
194                 memcpy(&length, data, sizeof(length));
195                 data += 4;
196                 length = ntohl(length);
197
198                 /*
199                  *      Ignore the M bit.  We support all RADIUS attributes...
200                  */
201
202                 /*
203                  *      A "vendor" flag, with a vendor ID of zero,
204                  *      is equivalent to no vendor.  This is stupid.
205                  */
206                 offset = 8;
207                 if ((length & (1 << 31)) != 0) {
208                         uint32_t vendor;
209
210                         memcpy(&vendor, data, sizeof(vendor));
211                         vendor = ntohl(vendor);
212
213                         attr |= (vendor << 16);
214
215                         data += 4; /* skip the vendor field, it's zero */
216                         offset += 4; /* offset to value field */
217                 }
218
219                 /*
220                  *      Get the length.
221                  */
222                 length &= 0x00ffffff;
223
224                 /*
225                  *      diameter code + length, and it must fit in
226                  *      a VALUE_PAIR.
227                  */
228                 rad_assert(length <= (offset + MAX_STRING_LEN));
229
230                 /*
231                  *      Get the size of the value portion of the
232                  *      attribute.
233                  */
234                 size = length - offset;
235
236                 /*
237                  *      Create it.
238                  */
239                 vp = paircreate(attr, PW_TYPE_OCTETS);
240                 if (!vp) {
241                         DEBUG2("  rlm_eap_ttls: Failure in creating VP");
242                         pairfree(&first);
243                         return NULL;
244                 }
245
246                 /*
247                  *      If it's a type from our dictionary, then
248                  *      we need to put the data in a relevant place.
249                  */
250                 switch (vp->type) {
251                 case PW_TYPE_INTEGER:
252                 case PW_TYPE_DATE:
253                         if (size != vp->length) {
254                                 DEBUG2("  rlm_eap_ttls: Invalid length attribute %d",
255                                        attr);
256                                 pairfree(&first);
257                                 return NULL;
258                         }
259                         memcpy(&vp->lvalue, data, vp->length);
260                         
261                         /*
262                          *      Stored in host byte order: change it.
263                          */
264                         vp->lvalue = ntohl(vp->lvalue);
265                         break;
266                         
267                 case PW_TYPE_IPADDR:
268                         if (size != vp->length) {
269                                 DEBUG2("  rlm_eap_ttls: Invalid length attribute %d",
270                                        attr);
271                                 pairfree(&first);
272                                 return NULL;
273                         }
274                   memcpy(&vp->lvalue, data, vp->length);
275                   
276                   /*
277                    *    Stored in network byte order: don't change it.
278                    */
279                   break;
280
281                   /*
282                    *    String, octet, etc.  Copy the data from the
283                    *    value field over verbatim.
284                    *
285                    *    FIXME: Ipv6 attributes ?
286                    *
287                    */
288                 default:
289                         vp->length = size;
290                         memcpy(vp->vp_strvalue, data, vp->length);
291                         break;
292                 }
293
294                 /*
295                  *      User-Password is NUL padded to a multiple
296                  *      of 16 bytes.  Let's chop it to something
297                  *      more reasonable.
298                  *
299                  *      NOTE: This means that the User-Password
300                  *      attribute CANNOT EVER have embedded zeros in it!
301                  */
302                 switch (vp->attribute) {
303                 case PW_USER_PASSWORD:
304                         rad_assert(vp->length <= 128); /* RFC requirements */
305
306                         /*
307                          *      If the password is exactly 16 octets,
308                          *      it won't be zero-terminated.
309                          */
310                         vp->vp_strvalue[vp->length] = '\0';
311                         vp->length = strlen(vp->vp_strvalue);
312                         break;
313
314                         /*
315                          *      Ensure that the client is using the
316                          *      correct challenge.  This weirdness is
317                          *      to protect against against replay
318                          *      attacks, where anyone observing the
319                          *      CHAP exchange could pose as that user,
320                          *      by simply choosing to use the same
321                          *      challenge.
322                          *
323                          *      By using a challenge based on
324                          *      information from the current session,
325                          *      we can guarantee that the client is
326                          *      not *choosing* a challenge.
327                          *
328                          *      We're a little forgiving in that we
329                          *      have loose checks on the length, and
330                          *      we do NOT check the Id (first octet of
331                          *      the response to the challenge)
332                          *
333                          *      But if the client gets the challenge correct,
334                          *      we're not too worried about the Id.
335                          */
336                 case PW_CHAP_CHALLENGE:
337                 case PW_MSCHAP_CHALLENGE:
338                         if ((vp->length < 8) ||
339                             (vp->length > 16)) {
340                                 DEBUG2("  TTLS: Tunneled challenge has invalid length");
341                                 pairfree(&first);
342                                 return NULL;
343
344                         } else {
345                                 int i;
346                                 uint8_t challenge[16];
347
348                                 eapttls_gen_challenge(ssl, challenge,
349                                                       sizeof(challenge));
350
351                                 for (i = 0; i < vp->length; i++) {
352                                         if (challenge[i] != vp->vp_strvalue[i]) {
353                                                 DEBUG2("  TTLS: Tunneled challenge is incorrect");
354                                                 pairfree(&first);
355                                                 return NULL;
356                                         }
357                                 }
358                         }
359                         break;
360
361                 default:
362                         break;
363                 } /* switch over checking/re-writing of attributes. */
364
365                 /*
366                  *      Update the list.
367                  */
368                 *last = vp;
369                 last = &(vp->next);
370
371                 /*
372                  *      Catch non-aligned attributes.
373                  */
374                 if (data_left == length) break;
375
376                 /*
377                  *      The length does NOT include the padding, so
378                  *      we've got to account for it here by rounding up
379                  *      to the nearest 4-byte boundary.
380                  */
381                 length += 0x03;
382                 length &= ~0x03;
383
384                 rad_assert(data_left >= length);
385                 data_left -= length;
386                 data += length - offset; /* already updated */
387         }
388
389         /*
390          *      We got this far.  It looks OK.
391          */
392         return first;
393 }
394
395 /*
396  *      Convert VALUE_PAIR's to diameter attributes, and write them
397  *      to an SSL session.
398  *
399  *      The ONLY VALUE_PAIR's which may be passed to this function
400  *      are ones which can go inside of a RADIUS (i.e. diameter)
401  *      packet.  So no server-configuration attributes, or the like.
402  */
403 static int vp2diameter(tls_session_t *tls_session, VALUE_PAIR *first)
404 {
405         /*
406          *      RADIUS packets are no more than 4k in size, so if
407          *      we've got more than 4k of data to write, it's very
408          *      bad.
409          */
410         uint8_t         buffer[4096];
411         uint8_t         *p;
412         uint32_t        attr;
413         uint32_t        length;
414         uint32_t        vendor;
415         size_t          total;
416         VALUE_PAIR      *vp;
417
418         p = buffer;
419         total = 0;
420
421         for (vp = first; vp != NULL; vp = vp->next) {
422                 /*
423                  *      Too much data: die.
424                  */
425                 if ((total + vp->length + 12) >= sizeof(buffer)) {
426                         DEBUG2("  TTLS output buffer is full!");
427                         return 0;
428                 }
429
430                 /*
431                  *      Hmm... we don't group multiple EAP-Messages
432                  *      together.  Maybe we should...
433                  */
434
435                 /*
436                  *      Length is no more than 253, due to RADIUS
437                  *      issues.
438                  */
439                 length = vp->length;
440                 vendor = (vp->attribute >> 16) & 0xffff;
441                 if (vendor != 0) {
442                         attr = vp->attribute & 0xffff;
443                         length |= (1 << 31);
444                 } else {
445                         attr = vp->attribute;
446                 }
447
448                 /*
449                  *      Hmm... set the M bit for all attributes?
450                  */
451                 length |= (1 << 30);
452
453                 attr = ntohl(attr);
454
455                 memcpy(p, &attr, sizeof(attr));
456                 p += 4;
457                 total += 4;
458
459                 length += 8;    /* includes 8 bytes of attr & length */
460
461                 if (vendor != 0) {
462                         length += 4; /* include 4 bytes of vendor */
463
464                         length = ntohl(length);
465                         memcpy(p, &length, sizeof(length));
466                         p += 4;
467                         total += 4;
468
469                         vendor = ntohl(vendor);
470                         memcpy(p, &vendor, sizeof(vendor));
471                         p += 4;
472                         total += 4;
473                 } else {
474                         length = ntohl(length);
475                         memcpy(p, &length, sizeof(length));
476                         p += 4;
477                         total += 4;
478                 }
479
480                 switch (vp->type) {
481                 case PW_TYPE_INTEGER:
482                 case PW_TYPE_DATE:
483                         attr = ntohl(vp->lvalue); /* stored in host order */
484                         memcpy(p, &attr, sizeof(attr));
485                         length = 4;
486                         break;
487
488                 case PW_TYPE_IPADDR:
489                         attr = vp->lvalue; /* stored in network order */
490                         memcpy(p, &attr, sizeof(attr));
491                         length = 4;
492                         break;
493
494                 case PW_TYPE_STRING:
495                 case PW_TYPE_OCTETS:
496                 default:
497                         memcpy(p, vp->vp_strvalue, vp->length);
498                         length = vp->length;
499                         break;
500                 }
501
502                 /*
503                  *      Skip to the end of the data.
504                  */
505                 p += length;
506                 total += length;
507
508                 /*
509                  *      Align the data to a multiple of 4 bytes.
510                  */
511                 if ((total & 0x03) != 0) {
512                         unsigned int i;
513
514                         length = 4 - (total & 0x03);
515                         for (i = 0; i < length; i++) {
516                                 *p = '\0';
517                                 p++;
518                                 total++;
519                         }
520                 }
521         } /* loop over the VP's to write. */
522
523         /*
524          *      Write the data in the buffer to the SSL session.
525          */
526         if (total > 0) {
527 #ifndef NDEBUG
528                 unsigned int i;
529
530                 if (debug_flag > 2) {
531                         for (i = 0; i < total; i++) {
532                                 if ((i & 0x0f) == 0) printf("  TTLS tunnel data out %04x: ", i);
533
534                                 printf("%02x ", buffer[i]);
535
536                                 if ((i & 0x0f) == 0x0f) printf("\n");
537                         }
538                         if ((total & 0x0f) != 0) printf("\n");
539                 }
540 #endif
541
542                 (tls_session->record_plus)(&tls_session->clean_in, buffer, total);
543
544                 /*
545                  *      FIXME: Check the return code.
546                  */
547                 tls_handshake_send(tls_session);
548         }
549
550         /*
551          *      Everything's OK.
552          */
553         return 1;
554 }
555
556 /*
557  *      Use a reply packet to determine what to do.
558  */
559 static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
560                          REQUEST *request, RADIUS_PACKET *reply)
561 {
562         int rcode = RLM_MODULE_REJECT;
563         VALUE_PAIR *vp;
564         ttls_tunnel_t *t = tls_session->opaque;
565
566         handler = handler;      /* -Wunused */
567
568         /*
569          *      If the response packet was Access-Accept, then
570          *      we're OK.  If not, die horribly.
571          *
572          *      FIXME: Take MS-CHAP2-Success attribute, and
573          *      tunnel it back to the client, to authenticate
574          *      ourselves to the client.
575          *
576          *      FIXME: If we have an Access-Challenge, then
577          *      the Reply-Message is tunneled back to the client.
578          *
579          *      FIXME: If we have an EAP-Message, then that message
580          *      must be tunneled back to the client.
581          *
582          *      FIXME: If we have an Access-Challenge with a State
583          *      attribute, then do we tunnel that to the client, or
584          *      keep track of it ourselves?
585          *
586          *      FIXME: EAP-Messages can only start with 'identity',
587          *      NOT 'eap start', so we should check for that....
588          */
589         switch (reply->code) {
590         case PW_AUTHENTICATION_ACK:
591                 DEBUG2("  TTLS: Got tunneled Access-Accept");
592
593                 rcode = RLM_MODULE_OK;
594
595                 /*
596                  *      MS-CHAP2-Success means that we do NOT return
597                  *      an Access-Accept, but instead tunnel that
598                  *      attribute to the client, and keep going with
599                  *      the TTLS session.  Once the client accepts
600                  *      our identity, it will respond with an empty
601                  *      packet, and we will send EAP-Success.
602                  */
603                 vp = NULL;
604                 pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS);
605                 if (vp) {
606 #if 1
607                         /*
608                          *      FIXME: Tunneling MS-CHAP2-Success causes
609                          *      the only client we have access to, to die.
610                          *
611                          *      We don't want that...
612                          */
613                         pairfree(&vp);
614 #else
615                         DEBUG2("  TTLS: Got MS-CHAP2-Success, tunneling it to the client in a challenge.");
616                         rcode = RLM_MODULE_HANDLED;
617                         t->authenticated = TRUE;
618 #endif
619                 } else { /* no MS-CHAP2-Success */
620                         /*
621                          *      Can only have EAP-Message if there's
622                          *      no MS-CHAP2-Success.  (FIXME: EAP-MSCHAP?)
623                          *
624                          *      We also do NOT tunnel the EAP-Success
625                          *      attribute back to the client, as the client
626                          *      can figure it out, from the non-tunneled
627                          *      EAP-Success packet.
628                          */
629                         pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);
630                         pairfree(&vp);
631                 }
632
633                 /*
634                  *      Handle the ACK, by tunneling any necessary reply
635                  *      VP's back to the client.
636                  */
637                 if (vp) {
638                         vp2diameter(tls_session, vp);
639                         pairfree(&vp);
640                 }
641
642                 /*
643                  *      If we've been told to use the attributes from
644                  *      the reply, then do so.
645                  *
646                  *      WARNING: This may leak information about the
647                  *      tunneled user!
648                  */
649                 if (t->use_tunneled_reply) {
650                         pairdelete(&reply->vps, PW_PROXY_STATE);
651                         pairadd(&request->reply->vps, reply->vps);
652                         reply->vps = NULL;
653                 }
654                 break;
655
656
657         case PW_AUTHENTICATION_REJECT:
658                 DEBUG2("  TTLS: Got tunneled Access-Reject");
659                 rcode = RLM_MODULE_REJECT;
660                 break;
661
662                 /*
663                  *      Handle Access-Challenge, but only if we
664                  *      send tunneled reply data.  This is because
665                  *      an Access-Challenge means that we MUST tunnel
666                  *      a Reply-Message to the client.
667                  */
668         case PW_ACCESS_CHALLENGE:
669                 DEBUG2("  TTLS: Got tunneled Access-Challenge");
670
671                 /*
672                  *      Keep the State attribute, if necessary.
673                  *
674                  *      Get rid of the old State, too.
675                  */
676                 pairfree(&t->state);
677                 pairmove2(&t->state, &reply->vps, PW_STATE);
678
679                 /*
680                  *      We should really be a bit smarter about this,
681                  *      and move over only those attributes which
682                  *      are relevant to the authentication request,
683                  *      but that's a lot more work, and this "dumb"
684                  *      method works in 99.9% of the situations.
685                  */
686                 vp = NULL;
687                 pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);
688
689                 /*
690                  *      There MUST be a Reply-Message in the challenge,
691                  *      which we tunnel back to the client.
692                  *
693                  *      If there isn't one in the reply VP's, then
694                  *      we MUST create one, with an empty string as
695                  *      it's value.
696                  */
697                 pairmove2(&vp, &reply->vps, PW_REPLY_MESSAGE);
698
699                 /*
700                  *      Handle the ACK, by tunneling any necessary reply
701                  *      VP's back to the client.
702                  */
703                 if (vp) {
704                         vp2diameter(tls_session, vp);
705                         pairfree(&vp);
706                 }
707                 rcode = RLM_MODULE_HANDLED;
708                 break;
709
710         default:
711                 DEBUG2("  TTLS: Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);
712                 rcode = RLM_MODULE_INVALID;
713                 break;
714         }
715
716         return rcode;
717 }
718
719
720 /*
721  *      Do post-proxy processing,
722  */
723 static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
724 {
725         int rcode;
726         tls_session_t *tls_session = (tls_session_t *) data;
727         REQUEST *fake;
728
729         DEBUG2("  TTLS: Passing reply from proxy back into the tunnel.");
730
731         /*
732          *      If there was a fake request associated with the proxied
733          *      request, do more processing of it.
734          */
735         fake = (REQUEST *) request_data_get(handler->request,
736                                             handler->request->proxy,
737                                             REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);
738         
739         /*
740          *      Do the callback, if it exists, and if it was a success.
741          */
742         if (fake && (handler->request->proxy_reply->code == PW_AUTHENTICATION_ACK)) {
743                 VALUE_PAIR *vp;
744                 REQUEST *request = handler->request;
745
746                 /*
747                  *      Terrible hacks.
748                  */
749                 rad_assert(fake->packet == NULL);
750                 fake->packet = request->proxy;
751                 request->proxy = NULL;
752
753                 rad_assert(fake->reply == NULL);
754                 fake->reply = request->proxy_reply;
755                 request->proxy_reply = NULL;
756
757                 /*
758                  *      Perform a post-auth stage for the tunneled
759                  *      session.
760                  */
761                 fake->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;
762                 rcode = rad_postauth(fake);
763                 DEBUG2("  POST-AUTH %d", rcode);
764
765 #ifndef NDEBUG
766                 if (debug_flag > 0) {
767                         printf("  TTLS: Final reply from tunneled session code %d\n",
768                                fake->reply->code);
769                         
770                         for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {
771                                 putchar('\t');vp_print(stdout, vp);putchar('\n');
772                         }
773                 }
774 #endif
775
776                 /*
777                  *      Terrible hacks.
778                  */
779                 request->proxy = fake->packet;
780                 fake->packet = NULL;
781                 request->proxy_reply = fake->reply;
782                 fake->reply = NULL;
783
784                 /*
785                  *      And we're done with this request.
786                  */
787
788                 switch (rcode) {
789                 case RLM_MODULE_FAIL:
790                         request_free(&fake);
791                         eaptls_fail(handler->eap_ds, 0);
792                         return 0;
793                         break;
794                         
795                 default:  /* Don't Do Anything */
796                         DEBUG2(" TTLS: Got reply %d",
797                                request->proxy_reply->code);
798                         break;
799                 }       
800         }
801         request_free(&fake);    /* robust if fake == NULL */
802
803         /*
804          *      Process the reply from the home server.
805          */
806         rcode = process_reply(handler, tls_session, handler->request,
807                               handler->request->proxy_reply);
808
809         /*
810          *      The proxy code uses the reply from the home server as
811          *      the basis for the reply to the NAS.  We don't want that,
812          *      so we toss it, after we've had our way with it.
813          */
814         pairfree(&handler->request->proxy_reply->vps);
815
816         switch (rcode) {
817         case RLM_MODULE_REJECT:
818                 DEBUG2("  TTLS: Reply was rejected");
819                 break;
820
821         case RLM_MODULE_HANDLED:
822                 DEBUG2("  TTLS: Reply was handled");
823                 eaptls_request(handler->eap_ds, tls_session);
824                 return 1;
825
826         case RLM_MODULE_OK:
827                 DEBUG2("  TTLS: Reply was OK");
828                 eaptls_success(handler->eap_ds, 0);
829                 eaptls_gen_mppe_keys(&handler->request->reply->vps,
830                                      tls_session->ssl,
831                                      "ttls keying material");
832                 return 1;
833
834         default:
835                 DEBUG2("  TTLS: Reply was unknown.");
836                 break;
837         }
838
839         eaptls_fail(handler->eap_ds, 0);
840         return 0;
841 }
842
843
844 /*
845  *      Free a request.
846  */
847 static void my_request_free(void *data)
848 {
849         REQUEST *request = (REQUEST *)data;
850
851         request_free(&request);
852 }
853
854
855 /*
856  *      Process the "diameter" contents of the tunneled data.
857  */
858 int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
859 {
860         int err;
861         int rcode = PW_AUTHENTICATION_REJECT;
862         REQUEST *fake;
863         VALUE_PAIR *vp;
864         ttls_tunnel_t *t;
865         const uint8_t *data;
866         unsigned int data_len;
867         char buffer[1024];
868         REQUEST *request = handler->request;
869
870         /*
871          *      Grab the dirty data, and copy it to our buffer.
872          *
873          *      I *really* don't like these 'record_t' things...
874          */
875         data_len = (tls_session->record_minus)(&tls_session->dirty_in, buffer, sizeof(buffer));
876         data = buffer;
877
878         /*
879          *      Write the data from the dirty buffer (i.e. packet
880          *      data) into the buffer which we will give to SSL for
881          *      decoding.
882          *
883          *      Some of this code COULD technically go into the TLS
884          *      module, in eaptls_process(), where it returns EAPTLS_OK.
885          *
886          *      Similarly, the writing of data to the SSL context could
887          *      go there, too...
888          */
889         BIO_write(tls_session->into_ssl, buffer, data_len);
890         (tls_session->record_init)(&tls_session->clean_out);
891
892         /*
893          *      Read (and decrypt) the tunneled data from the SSL session,
894          *      and put it into the decrypted data buffer.
895          */
896         err = SSL_read(tls_session->ssl, tls_session->clean_out.data,
897                        sizeof(tls_session->clean_out.data));
898         if (err < 0) {
899                 /*
900                  *      FIXME: Call SSL_get_error() to see what went
901                  *      wrong.
902                  */
903                 radlog(L_INFO, "rlm_eap_ttls: SSL_read Error");
904                 return PW_AUTHENTICATION_REJECT;
905         }
906
907         t = (ttls_tunnel_t *) tls_session->opaque;
908
909         /*
910          *      If there's no data, maybe this is an ACK to an
911          *      MS-CHAP2-Success.
912          */
913         if (err == 0) {
914                 if (t->authenticated) {
915                         DEBUG2("  TTLS: Got ACK, and the user was already authenticated.");
916                         return PW_AUTHENTICATION_ACK;
917                 } /* else no session, no data, die. */
918
919                 /*
920                  *      FIXME: Call SSL_get_error() to see what went
921                  *      wrong.
922                  */
923                 radlog(L_INFO, "rlm_eap_ttls: SSL_read Error");
924                 return PW_AUTHENTICATION_REJECT;
925         }
926
927         data_len = tls_session->clean_out.used = err;
928         data = tls_session->clean_out.data;
929
930 #ifndef NDEBUG
931         if (debug_flag > 2) {
932                 unsigned int i;
933
934                 for (i = 0; i < data_len; i++) {
935                         if ((i & 0x0f) == 0) printf("  TTLS tunnel data in %04x: ", i);
936
937                         printf("%02x ", data[i]);
938
939                         if ((i & 0x0f) == 0x0f) printf("\n");
940                 }
941                 if ((data_len & 0x0f) != 0) printf("\n");
942         }
943 #endif
944
945         if (!diameter_verify(data, data_len)) {
946                 return PW_AUTHENTICATION_REJECT;
947         }
948
949         /*
950          *      Allocate a fake REQUEST structe.
951          */
952         fake = request_alloc_fake(request);
953
954         rad_assert(fake->packet->vps == NULL);
955
956         /*
957          *      Add the tunneled attributes to the fake request.
958          */
959         fake->packet->vps = diameter2vp(tls_session->ssl, data, data_len);
960         if (!fake->packet->vps) {
961                 return PW_AUTHENTICATION_REJECT;
962         }
963
964         /*
965          *      Tell the request that it's a fake one.
966          */
967         vp = pairmake("Freeradius-Proxied-To", "127.0.0.1", T_OP_EQ);
968         if (vp) {
969                 pairadd(&fake->packet->vps, vp);
970         }
971
972 #ifndef NDEBUG
973         if (debug_flag > 0) {
974                 printf("  TTLS: Got tunneled request\n");
975                 
976                 for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {
977                         putchar('\t');vp_print(stdout, vp);putchar('\n');
978                 }
979         }
980 #endif
981
982         /*
983          *      Update other items in the REQUEST data structure.
984          */
985         fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
986         fake->password = pairfind(fake->packet->vps, PW_PASSWORD);
987
988         /*
989          *      No User-Name, try to create one from stored data.
990          */
991         if (!fake->username) {
992                 /*
993                  *      No User-Name in the stored data, look for
994                  *      an EAP-Identity, and pull it out of there.
995                  */
996                 if (!t->username) {
997                         vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE);
998                         if (vp &&
999                             (vp->length >= EAP_HEADER_LEN + 2) &&
1000                             (vp->vp_strvalue[0] == PW_EAP_RESPONSE) &&
1001                             (vp->vp_strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
1002                             (vp->vp_strvalue[EAP_HEADER_LEN + 1] != 0)) {
1003                                 /*
1004                                  *      Create & remember a User-Name
1005                                  */
1006                                 t->username = pairmake("User-Name", "", T_OP_EQ);
1007                                 rad_assert(t->username != NULL);
1008
1009                                 memcpy(t->username->vp_strvalue, vp->vp_strvalue + 5,
1010                                        vp->length - 5);
1011                                 t->username->length = vp->length - 5;
1012                                 t->username->vp_strvalue[t->username->length] = 0;
1013
1014                                 DEBUG2("  TTLS: Got tunneled identity of %s",
1015                                        t->username->vp_strvalue);
1016
1017                                 /*
1018                                  *      If there's a default EAP type,
1019                                  *      set it here.
1020                                  */
1021                                 if (t->default_eap_type != 0) {
1022                                         DEBUG2("  TTLS: Setting default EAP type for tunneled EAP session.");
1023                                         vp = paircreate(PW_EAP_TYPE,
1024                                                         PW_TYPE_INTEGER);
1025                                         rad_assert(vp != NULL);
1026                                         vp->lvalue = t->default_eap_type;
1027                                         pairadd(&fake->config_items, vp);
1028                                 }
1029
1030                         } else {
1031                                 /*
1032                                  *      Don't reject the request outright,
1033                                  *      as it's permitted to do EAP without
1034                                  *      user-name.
1035                                  */
1036                                 DEBUG2("  rlm_eap_ttls: WARNING! No EAP-Identity found to start EAP conversation.");
1037                         }
1038                 } /* else there WAS a t->username */
1039
1040                 if (t->username) {
1041                         vp = paircopy(t->username);
1042                         pairadd(&fake->packet->vps, vp);
1043                         fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
1044                 }
1045         } /* else the request ALREADY had a User-Name */
1046
1047         /*
1048          *      Add the State attribute, too, if it exists.
1049          */
1050         if (t->state) {
1051                 DEBUG2("  TTLS: Adding old state with %02x %02x",
1052                        t->state->vp_strvalue[0], t->state->vp_strvalue[1]);
1053                 vp = paircopy(t->state);
1054                 if (vp) pairadd(&fake->packet->vps, vp);
1055         }
1056
1057         /*
1058          *      If this is set, we copy SOME of the request attributes
1059          *      from outside of the tunnel to inside of the tunnel.
1060          *
1061          *      We copy ONLY those attributes which do NOT already
1062          *      exist in the tunneled request.
1063          */
1064         if (t->copy_request_to_tunnel) {
1065                 VALUE_PAIR *copy;
1066
1067                 for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
1068                         /*
1069                          *      The attribute is a server-side thingy,
1070                          *      don't copy it.
1071                          */
1072                         if ((vp->attribute > 255) &&
1073                             (((vp->attribute >> 16) & 0xffff) == 0)) {
1074                                 continue;
1075                         }
1076
1077                         /*
1078                          *      The outside attribute is already in the
1079                          *      tunnel, don't copy it.
1080                          *
1081                          *      This works for BOTH attributes which
1082                          *      are originally in the tunneled request,
1083                          *      AND attributes which are copied there
1084                          *      from below.
1085                          */
1086                         if (pairfind(fake->packet->vps, vp->attribute)) {
1087                                 continue;
1088                         }
1089
1090                         /*
1091                          *      Some attributes are handled specially.
1092                          */
1093                         switch (vp->attribute) {
1094                                 /*
1095                                  *      NEVER copy Message-Authenticator,
1096                                  *      EAP-Message, or State.  They're
1097                                  *      only for outside of the tunnel.
1098                                  */
1099                         case PW_USER_NAME:
1100                         case PW_USER_PASSWORD:
1101                         case PW_CHAP_PASSWORD:
1102                         case PW_CHAP_CHALLENGE:
1103                         case PW_PROXY_STATE:
1104                         case PW_MESSAGE_AUTHENTICATOR:
1105                         case PW_EAP_MESSAGE:
1106                         case PW_STATE:
1107                                 continue;
1108                                 break;
1109
1110                                 /*
1111                                  *      By default, copy it over.
1112                                  */
1113                         default:
1114                                 break;
1115                         }
1116
1117                         /*
1118                          *      Don't copy from the head, we've already
1119                          *      checked it.
1120                          */
1121                         copy = paircopy2(vp, vp->attribute);
1122                         pairadd(&fake->packet->vps, copy);
1123                 }
1124         }
1125
1126 #ifndef NDEBUG
1127         if (debug_flag > 0) {
1128           printf("  TTLS: Sending tunneled request\n");
1129
1130           for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {
1131             putchar('\t');vp_print(stdout, vp);putchar('\n');
1132           }
1133         }
1134 #endif
1135
1136         /*
1137          *      Call authentication recursively, which will
1138          *      do PAP, CHAP, MS-CHAP, etc.
1139          */
1140         rad_authenticate(fake);
1141
1142         /*
1143          *      Note that we don't do *anything* with the reply
1144          *      attributes.
1145          */
1146 #ifndef NDEBUG
1147         if (debug_flag > 0) {
1148           printf("  TTLS: Got tunneled reply RADIUS code %d\n",
1149                  fake->reply->code);
1150
1151           for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {
1152             putchar('\t');vp_print(stdout, vp);putchar('\n');
1153           }
1154         }
1155 #endif
1156
1157         /*
1158          *      Decide what to do with the reply.
1159          */
1160         switch (fake->reply->code) {
1161         case 0:                 /* No reply code, must be proxied... */
1162                 vp = pairfind(fake->config_items, PW_PROXY_TO_REALM);
1163                 if (vp) {
1164                         eap_tunnel_data_t *tunnel;
1165                         DEBUG2("  TTLS: Tunneled authentication will be proxied to %s", vp->vp_strvalue);
1166
1167                         /*
1168                          *      Tell the original request that it's going
1169                          *      to be proxied.
1170                          */
1171                         pairmove2(&(request->config_items),
1172                                   &(fake->config_items),
1173                                   PW_PROXY_TO_REALM);
1174
1175                         /*
1176                          *      Seed the proxy packet with the
1177                          *      tunneled request.
1178                          */
1179                         rad_assert(request->proxy == NULL);
1180                         request->proxy = fake->packet;
1181                         fake->packet = NULL;
1182                         rad_free(&fake->reply);
1183                         fake->reply = NULL;
1184
1185                         /*
1186                          *      Set up the callbacks for the tunnel
1187                          */
1188                         tunnel = rad_malloc(sizeof(*tunnel));
1189                         memset(tunnel, 0, sizeof(*tunnel));
1190
1191                         tunnel->tls_session = tls_session;
1192                         tunnel->callback = eapttls_postproxy;
1193
1194                         /*
1195                          *      Associate the callback with the request.
1196                          */
1197                         rcode = request_data_add(request,
1198                                                  request->proxy,
1199                                                  REQUEST_DATA_EAP_TUNNEL_CALLBACK,
1200                                                  tunnel, free);
1201                         rad_assert(rcode == 0);
1202                         
1203                         /*
1204                          *      rlm_eap.c has taken care of associating
1205                          *      the handler with the fake request.
1206                          *
1207                          *      So we associate the fake request with
1208                          *      this request.
1209                          */
1210                         rcode = request_data_add(request,
1211                                                  request->proxy,
1212                                                  REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK,
1213                                                  fake, my_request_free);
1214                         rad_assert(rcode == 0);
1215                         fake = NULL;
1216
1217                         /*
1218                          *      Didn't authenticate the packet, but
1219                          *      we're proxying it.
1220                          */
1221                         rcode = PW_STATUS_CLIENT;
1222
1223                 } else {
1224                         DEBUG2("  TTLS: No tunneled reply was found for request %d , and the request was not proxied: rejecting the user.",
1225                                request->number);
1226                         rcode = PW_AUTHENTICATION_REJECT;
1227                 }
1228                 break;
1229
1230         default:
1231                 /*
1232                  *      Returns RLM_MODULE_FOO, and we want to return
1233                  *      PW_FOO
1234                  */
1235                 rcode = process_reply(handler, tls_session, request,
1236                                       fake->reply);
1237                 switch (rcode) {
1238                 case RLM_MODULE_REJECT:
1239                         rcode = PW_AUTHENTICATION_REJECT;
1240                         break;
1241                         
1242                 case RLM_MODULE_HANDLED:
1243                         rcode = PW_ACCESS_CHALLENGE;
1244                         break;
1245                         
1246                 case RLM_MODULE_OK:
1247                         rcode = PW_AUTHENTICATION_ACK;
1248                         break;
1249                         
1250                 default:
1251                         rcode = PW_AUTHENTICATION_REJECT;
1252                         break;
1253                 }
1254                 break;
1255         }
1256
1257         request_free(&fake);
1258
1259         return rcode;
1260 }