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