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