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