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