Fixes from clang / scan-build
[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         rad_assert(request != NULL);
622         rad_assert(handler->request == request);
623
624         /*
625          *      If the response packet was Access-Accept, then
626          *      we're OK.  If not, die horribly.
627          *
628          *      FIXME: Take MS-CHAP2-Success attribute, and
629          *      tunnel it back to the client, to authenticate
630          *      ourselves to the client.
631          *
632          *      FIXME: If we have an Access-Challenge, then
633          *      the Reply-Message is tunneled back to the client.
634          *
635          *      FIXME: If we have an EAP-Message, then that message
636          *      must be tunneled back to the client.
637          *
638          *      FIXME: If we have an Access-Challenge with a State
639          *      attribute, then do we tunnel that to the client, or
640          *      keep track of it ourselves?
641          *
642          *      FIXME: EAP-Messages can only start with 'identity',
643          *      NOT 'eap start', so we should check for that....
644          */
645         switch (reply->code) {
646         case PW_AUTHENTICATION_ACK:
647                 RDEBUG("Got tunneled Access-Accept");
648
649                 rcode = RLM_MODULE_OK;
650
651                 /*
652                  *      MS-CHAP2-Success means that we do NOT return
653                  *      an Access-Accept, but instead tunnel that
654                  *      attribute to the client, and keep going with
655                  *      the TTLS session.  Once the client accepts
656                  *      our identity, it will respond with an empty
657                  *      packet, and we will send EAP-Success.
658                  */
659                 vp = NULL;
660                 pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS, VENDORPEC_MICROSOFT);
661                 if (vp) {
662                         RDEBUG("Got MS-CHAP2-Success, tunneling it to the client in a challenge.");
663                         rcode = RLM_MODULE_HANDLED;
664                         t->authenticated = TRUE;
665
666                         /*
667                          *      Delete MPPE keys & encryption policy.  We don't
668                          *      want these here.
669                          */
670                         pairdelete(&reply->vps, 7, VENDORPEC_MICROSOFT);
671                         pairdelete(&reply->vps, 8, VENDORPEC_MICROSOFT);
672                         pairdelete(&reply->vps, 16, VENDORPEC_MICROSOFT);
673                         pairdelete(&reply->vps, 17, VENDORPEC_MICROSOFT);
674
675                         /*
676                          *      Use the tunneled reply, but not now.
677                          */
678                         if (t->use_tunneled_reply) {
679                                 t->accept_vps = reply->vps;
680                                 reply->vps = NULL;
681                         }
682
683                 } else { /* no MS-CHAP2-Success */
684                         /*
685                          *      Can only have EAP-Message if there's
686                          *      no MS-CHAP2-Success.  (FIXME: EAP-MSCHAP?)
687                          *
688                          *      We also do NOT tunnel the EAP-Success
689                          *      attribute back to the client, as the client
690                          *      can figure it out, from the non-tunneled
691                          *      EAP-Success packet.
692                          */
693                         pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE, 0);
694                         pairfree(&vp);
695                 }
696
697                 /*
698                  *      Handle the ACK, by tunneling any necessary reply
699                  *      VP's back to the client.
700                  */
701                 if (vp) {
702                         vp2diameter(request, tls_session, vp);
703                         pairfree(&vp);
704                 }
705
706                 /*
707                  *      If we've been told to use the attributes from
708                  *      the reply, then do so.
709                  *
710                  *      WARNING: This may leak information about the
711                  *      tunneled user!
712                  */
713                 if (t->use_tunneled_reply) {
714                         pairdelete(&reply->vps, PW_PROXY_STATE, 0);
715                         pairadd(&request->reply->vps, reply->vps);
716                         reply->vps = NULL;
717                 }
718                 break;
719
720
721         case PW_AUTHENTICATION_REJECT:
722                 RDEBUG("Got tunneled Access-Reject");
723                 rcode = RLM_MODULE_REJECT;
724                 break;
725
726                 /*
727                  *      Handle Access-Challenge, but only if we
728                  *      send tunneled reply data.  This is because
729                  *      an Access-Challenge means that we MUST tunnel
730                  *      a Reply-Message to the client.
731                  */
732         case PW_ACCESS_CHALLENGE:
733                 RDEBUG("Got tunneled Access-Challenge");
734
735                 /*
736                  *      Keep the State attribute, if necessary.
737                  *
738                  *      Get rid of the old State, too.
739                  */
740                 pairfree(&t->state);
741                 pairmove2(&t->state, &reply->vps, PW_STATE, 0);
742
743                 /*
744                  *      We should really be a bit smarter about this,
745                  *      and move over only those attributes which
746                  *      are relevant to the authentication request,
747                  *      but that's a lot more work, and this "dumb"
748                  *      method works in 99.9% of the situations.
749                  */
750                 vp = NULL;
751                 pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE, 0);
752
753                 /*
754                  *      There MUST be a Reply-Message in the challenge,
755                  *      which we tunnel back to the client.
756                  *
757                  *      If there isn't one in the reply VP's, then
758                  *      we MUST create one, with an empty string as
759                  *      it's value.
760                  */
761                 pairmove2(&vp, &reply->vps, PW_REPLY_MESSAGE, 0);
762
763                 /*
764                  *      Handle the ACK, by tunneling any necessary reply
765                  *      VP's back to the client.
766                  */
767                 if (vp) {
768                         vp2diameter(request, tls_session, vp);
769                         pairfree(&vp);
770                 }
771                 rcode = RLM_MODULE_HANDLED;
772                 break;
773
774         default:
775                 RDEBUG("Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);
776                 rcode = RLM_MODULE_INVALID;
777                 break;
778         }
779
780         return rcode;
781 }
782
783
784 #ifdef WITH_PROXY
785 /*
786  *      Do post-proxy processing,
787  */
788 static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
789 {
790         int rcode;
791         tls_session_t *tls_session = (tls_session_t *) data;
792         REQUEST *fake, *request = handler->request;
793
794         rad_assert(request != NULL);
795         RDEBUG("Passing reply from proxy back into the tunnel.");
796
797         /*
798          *      If there was a fake request associated with the proxied
799          *      request, do more processing of it.
800          */
801         fake = (REQUEST *) request_data_get(handler->request,
802                                             handler->request->proxy,
803                                             REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);
804
805         /*
806          *      Do the callback, if it exists, and if it was a success.
807          */
808         if (fake && (handler->request->proxy_reply->code == PW_AUTHENTICATION_ACK)) {
809                 /*
810                  *      Terrible hacks.
811                  */
812                 rad_assert(fake->packet == NULL);
813                 fake->packet = request->proxy;
814                 fake->packet->src_ipaddr = request->packet->src_ipaddr;
815                 request->proxy = NULL;
816
817                 rad_assert(fake->reply == NULL);
818                 fake->reply = request->proxy_reply;
819                 request->proxy_reply = NULL;
820
821                 if ((debug_flag > 0) && fr_log_fp) {
822                         fprintf(fr_log_fp, "server %s {\n",
823                                 (fake->server == NULL) ? "" : fake->server);
824                 }
825
826                 /*
827                  *      Perform a post-auth stage for the tunneled
828                  *      session.
829                  */
830                 fake->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;
831                 rcode = rad_postauth(fake);
832                 RDEBUG2("post-auth returns %d", rcode);
833
834                 if ((debug_flag > 0) && fr_log_fp) {
835                         fprintf(fr_log_fp, "} # server %s\n",
836                                 (fake->server == NULL) ? "" : fake->server);
837                         
838                         RDEBUG("Final reply from tunneled session code %d",
839                                fake->reply->code);
840                         debug_pair_list(fake->reply->vps);
841                 }
842
843                 /*
844                  *      Terrible hacks.
845                  */
846                 request->proxy = fake->packet;
847                 fake->packet = NULL;
848                 request->proxy_reply = fake->reply;
849                 fake->reply = NULL;
850
851                 /*
852                  *      And we're done with this request.
853                  */
854
855                 switch (rcode) {
856                 case RLM_MODULE_FAIL:
857                         request_free(&fake);
858                         eaptls_fail(handler, 0);
859                         return 0;
860                         break;
861
862                 default:  /* Don't Do Anything */
863                         RDEBUG2("Got reply %d",
864                                request->proxy_reply->code);
865                         break;
866                 }
867         }
868         request_free(&fake);    /* robust if fake == NULL */
869
870         /*
871          *      Process the reply from the home server.
872          */
873         rcode = process_reply(handler, tls_session, handler->request,
874                               handler->request->proxy_reply);
875
876         /*
877          *      The proxy code uses the reply from the home server as
878          *      the basis for the reply to the NAS.  We don't want that,
879          *      so we toss it, after we've had our way with it.
880          */
881         pairfree(&handler->request->proxy_reply->vps);
882
883         switch (rcode) {
884         case RLM_MODULE_REJECT:
885                 RDEBUG("Reply was rejected");
886                 break;
887
888         case RLM_MODULE_HANDLED:
889                 RDEBUG("Reply was handled");
890                 eaptls_request(handler->eap_ds, tls_session);
891                 return 1;
892
893         case RLM_MODULE_OK:
894                 RDEBUG("Reply was OK");
895
896                 /*
897                  *      Success: Automatically return MPPE keys.
898                  */
899                 return eaptls_success(handler, 0);
900
901         default:
902                 RDEBUG("Reply was unknown.");
903                 break;
904         }
905
906         eaptls_fail(handler, 0);
907         return 0;
908 }
909
910
911 /*
912  *      Free a request.
913  */
914 static void my_request_free(void *data)
915 {
916         REQUEST *request = (REQUEST *)data;
917
918         request_free(&request);
919 }
920 #endif  /* WITH_PROXY */
921
922 /*
923  *      Process the "diameter" contents of the tunneled data.
924  */
925 int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
926 {
927         int rcode = PW_AUTHENTICATION_REJECT;
928         REQUEST *fake;
929         VALUE_PAIR *vp;
930         ttls_tunnel_t *t;
931         const uint8_t *data;
932         size_t data_len;
933         REQUEST *request = handler->request;
934
935         rad_assert(request != NULL);
936
937         /*
938          *      Just look at the buffer directly, without doing
939          *      record_minus.
940          */
941         data_len = tls_session->clean_out.used;
942         tls_session->clean_out.used = 0;
943         data = tls_session->clean_out.data;
944
945         t = (ttls_tunnel_t *) tls_session->opaque;
946
947         /*
948          *      If there's no data, maybe this is an ACK to an
949          *      MS-CHAP2-Success.
950          */
951         if (data_len == 0) {
952                 if (t->authenticated) {
953                         RDEBUG("Got ACK, and the user was already authenticated.");
954                         return PW_AUTHENTICATION_ACK;
955                 } /* else no session, no data, die. */
956
957                 /*
958                  *      FIXME: Call SSL_get_error() to see what went
959                  *      wrong.
960                  */
961                 RDEBUG2("SSL_read Error");
962                 return PW_AUTHENTICATION_REJECT;
963         }
964
965 #ifndef NDEBUG
966         if ((debug_flag > 2) && fr_log_fp) {
967                 size_t i;
968
969                 for (i = 0; i < data_len; i++) {
970                         if ((i & 0x0f) == 0) fprintf(fr_log_fp, "  TTLS tunnel data in %04x: ", (int) i);
971
972                         fprintf(fr_log_fp, "%02x ", data[i]);
973
974                         if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");
975                 }
976                 if ((data_len & 0x0f) != 0) fprintf(fr_log_fp, "\n");
977         }
978 #endif
979
980         if (!diameter_verify(request, data, data_len)) {
981                 return PW_AUTHENTICATION_REJECT;
982         }
983
984         /*
985          *      Allocate a fake REQUEST structe.
986          */
987         fake = request_alloc_fake(request);
988
989         rad_assert(fake->packet->vps == NULL);
990
991         /*
992          *      Add the tunneled attributes to the fake request.
993          */
994         fake->packet->vps = diameter2vp(request, tls_session->ssl, data, data_len);
995         if (!fake->packet->vps) {
996                 request_free(&fake);
997                 return PW_AUTHENTICATION_REJECT;
998         }
999
1000         /*
1001          *      Tell the request that it's a fake one.
1002          */
1003         vp = pairmake("Freeradius-Proxied-To", "127.0.0.1", T_OP_EQ);
1004         if (vp) {
1005                 pairadd(&fake->packet->vps, vp);
1006         }
1007
1008         if ((debug_flag > 0) && fr_log_fp) {
1009                 RDEBUG("Got tunneled request");
1010
1011                 debug_pair_list(fake->packet->vps);
1012         }
1013
1014         /*
1015          *      Update other items in the REQUEST data structure.
1016          */
1017         fake->username = pairfind(fake->packet->vps, PW_USER_NAME, 0);
1018         fake->password = pairfind(fake->packet->vps, PW_USER_PASSWORD, 0);
1019
1020         /*
1021          *      No User-Name, try to create one from stored data.
1022          */
1023         if (!fake->username) {
1024                 /*
1025                  *      No User-Name in the stored data, look for
1026                  *      an EAP-Identity, and pull it out of there.
1027                  */
1028                 if (!t->username) {
1029                         vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE, 0);
1030                         if (vp &&
1031                             (vp->length >= EAP_HEADER_LEN + 2) &&
1032                             (vp->vp_strvalue[0] == PW_EAP_RESPONSE) &&
1033                             (vp->vp_strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
1034                             (vp->vp_strvalue[EAP_HEADER_LEN + 1] != 0)) {
1035                                 /*
1036                                  *      Create & remember a User-Name
1037                                  */
1038                                 t->username = pairmake("User-Name", "", T_OP_EQ);
1039                                 rad_assert(t->username != NULL);
1040
1041                                 memcpy(t->username->vp_strvalue, vp->vp_strvalue + 5,
1042                                        vp->length - 5);
1043                                 t->username->length = vp->length - 5;
1044                                 t->username->vp_strvalue[t->username->length] = 0;
1045
1046                                 RDEBUG("Got tunneled identity of %s",
1047                                        t->username->vp_strvalue);
1048
1049                                 /*
1050                                  *      If there's a default EAP type,
1051                                  *      set it here.
1052                                  */
1053                                 if (t->default_eap_type != 0) {
1054                                         RDEBUG("Setting default EAP type for tunneled EAP session.");
1055                                         vp = paircreate(PW_EAP_TYPE, 0,
1056                                                         PW_TYPE_INTEGER);
1057                                         rad_assert(vp != NULL);
1058                                         vp->vp_integer = t->default_eap_type;
1059                                         pairadd(&fake->config_items, vp);
1060                                 }
1061
1062                         } else {
1063                                 /*
1064                                  *      Don't reject the request outright,
1065                                  *      as it's permitted to do EAP without
1066                                  *      user-name.
1067                                  */
1068                                 RDEBUG2("WARNING! No EAP-Identity found to start EAP conversation.");
1069                         }
1070                 } /* else there WAS a t->username */
1071
1072                 if (t->username) {
1073                         vp = paircopy(t->username);
1074                         pairadd(&fake->packet->vps, vp);
1075                         fake->username = pairfind(fake->packet->vps, PW_USER_NAME, 0);
1076                 }
1077         } /* else the request ALREADY had a User-Name */
1078
1079         /*
1080          *      Add the State attribute, too, if it exists.
1081          */
1082         if (t->state) {
1083                 vp = paircopy(t->state);
1084                 if (vp) pairadd(&fake->packet->vps, vp);
1085         }
1086
1087         /*
1088          *      If this is set, we copy SOME of the request attributes
1089          *      from outside of the tunnel to inside of the tunnel.
1090          *
1091          *      We copy ONLY those attributes which do NOT already
1092          *      exist in the tunneled request.
1093          */
1094         if (t->copy_request_to_tunnel) {
1095                 VALUE_PAIR *copy;
1096
1097                 for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
1098                         /*
1099                          *      The attribute is a server-side thingy,
1100                          *      don't copy it.
1101                          */
1102                         if ((vp->attribute > 255) &&
1103                             (vp->vendor == 0)) {
1104                                 continue;
1105                         }
1106
1107                         /*
1108                          *      The outside attribute is already in the
1109                          *      tunnel, don't copy it.
1110                          *
1111                          *      This works for BOTH attributes which
1112                          *      are originally in the tunneled request,
1113                          *      AND attributes which are copied there
1114                          *      from below.
1115                          */
1116                         if (pairfind(fake->packet->vps, vp->attribute, vp->vendor)) {
1117                                 continue;
1118                         }
1119
1120                         /*
1121                          *      Some attributes are handled specially.
1122                          */
1123                         switch (vp->attribute) {
1124                                 /*
1125                                  *      NEVER copy Message-Authenticator,
1126                                  *      EAP-Message, or State.  They're
1127                                  *      only for outside of the tunnel.
1128                                  */
1129                         case PW_USER_NAME:
1130                         case PW_USER_PASSWORD:
1131                         case PW_CHAP_PASSWORD:
1132                         case PW_CHAP_CHALLENGE:
1133                         case PW_PROXY_STATE:
1134                         case PW_MESSAGE_AUTHENTICATOR:
1135                         case PW_EAP_MESSAGE:
1136                         case PW_STATE:
1137                                 continue;
1138                                 break;
1139
1140                                 /*
1141                                  *      By default, copy it over.
1142                                  */
1143                         default:
1144                                 break;
1145                         }
1146
1147                         /*
1148                          *      Don't copy from the head, we've already
1149                          *      checked it.
1150                          */
1151                         copy = paircopy2(vp, vp->attribute, vp->vendor);
1152                         pairadd(&fake->packet->vps, copy);
1153                 }
1154         }
1155
1156         if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0)) != NULL) {
1157                 fake->server = vp->vp_strvalue;
1158
1159         } else if (t->virtual_server) {
1160                 fake->server = t->virtual_server;
1161
1162         } /* else fake->server == request->server */
1163
1164
1165         if ((debug_flag > 0) && fr_log_fp) {
1166                 RDEBUG("Sending tunneled request");
1167
1168                 debug_pair_list(fake->packet->vps);
1169
1170                 fprintf(fr_log_fp, "server %s {\n",
1171                         (fake->server == NULL) ? "" : fake->server);
1172         }
1173
1174         /*
1175          *      Call authentication recursively, which will
1176          *      do PAP, CHAP, MS-CHAP, etc.
1177          */
1178         rad_authenticate(fake);
1179
1180         /*
1181          *      Note that we don't do *anything* with the reply
1182          *      attributes.
1183          */
1184         if ((debug_flag > 0) && fr_log_fp) {
1185                 fprintf(fr_log_fp, "} # server %s\n",
1186                         (fake->server == NULL) ? "" : fake->server);
1187
1188                 RDEBUG("Got tunneled reply code %d", fake->reply->code);
1189                 
1190                 debug_pair_list(fake->reply->vps);
1191         }
1192
1193         /*
1194          *      Decide what to do with the reply.
1195          */
1196         switch (fake->reply->code) {
1197         case 0:                 /* No reply code, must be proxied... */
1198 #ifdef WITH_PROXY
1199           vp = pairfind(fake->config_items, PW_PROXY_TO_REALM, 0);
1200                 if (vp) {
1201                         eap_tunnel_data_t *tunnel;
1202                         RDEBUG("Tunneled authentication will be proxied to %s", vp->vp_strvalue);
1203
1204                         /*
1205                          *      Tell the original request that it's going
1206                          *      to be proxied.
1207                          */
1208                         pairmove2(&(request->config_items),
1209                                   &(fake->config_items),
1210                                   PW_PROXY_TO_REALM, 0);
1211
1212                         /*
1213                          *      Seed the proxy packet with the
1214                          *      tunneled request.
1215                          */
1216                         rad_assert(request->proxy == NULL);
1217                         request->proxy = fake->packet;
1218                         memset(&request->proxy->src_ipaddr, 0,
1219                                sizeof(request->proxy->src_ipaddr));
1220                         memset(&request->proxy->src_ipaddr, 0,
1221                                sizeof(request->proxy->src_ipaddr));
1222                         request->proxy->src_port = 0;
1223                         request->proxy->dst_port = 0;
1224                         fake->packet = NULL;
1225                         rad_free(&fake->reply);
1226                         fake->reply = NULL;
1227
1228                         /*
1229                          *      Set up the callbacks for the tunnel
1230                          */
1231                         tunnel = rad_malloc(sizeof(*tunnel));
1232                         memset(tunnel, 0, sizeof(*tunnel));
1233
1234                         tunnel->tls_session = tls_session;
1235                         tunnel->callback = eapttls_postproxy;
1236
1237                         /*
1238                          *      Associate the callback with the request.
1239                          */
1240                         rcode = request_data_add(request,
1241                                                  request->proxy,
1242                                                  REQUEST_DATA_EAP_TUNNEL_CALLBACK,
1243                                                  tunnel, free);
1244                         rad_assert(rcode == 0);
1245
1246                         /*
1247                          *      rlm_eap.c has taken care of associating
1248                          *      the handler with the fake request.
1249                          *
1250                          *      So we associate the fake request with
1251                          *      this request.
1252                          */
1253                         rcode = request_data_add(request,
1254                                                  request->proxy,
1255                                                  REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK,
1256                                                  fake, my_request_free);
1257                         rad_assert(rcode == 0);
1258                         fake = NULL;
1259
1260                         /*
1261                          *      Didn't authenticate the packet, but
1262                          *      we're proxying it.
1263                          */
1264                         rcode = PW_STATUS_CLIENT;
1265
1266                 } else
1267 #endif  /* WITH_PROXY */
1268                   {
1269                         RDEBUG("No tunneled reply was found for request %d , and the request was not proxied: rejecting the user.",
1270                                request->number);
1271                         rcode = PW_AUTHENTICATION_REJECT;
1272                 }
1273                 break;
1274
1275         default:
1276                 /*
1277                  *      Returns RLM_MODULE_FOO, and we want to return
1278                  *      PW_FOO
1279                  */
1280                 rcode = process_reply(handler, tls_session, request,
1281                                       fake->reply);
1282                 switch (rcode) {
1283                 case RLM_MODULE_REJECT:
1284                         rcode = PW_AUTHENTICATION_REJECT;
1285                         break;
1286
1287                 case RLM_MODULE_HANDLED:
1288                         rcode = PW_ACCESS_CHALLENGE;
1289                         break;
1290
1291                 case RLM_MODULE_OK:
1292                         rcode = PW_AUTHENTICATION_ACK;
1293                         break;
1294
1295                 default:
1296                         rcode = PW_AUTHENTICATION_REJECT;
1297                         break;
1298                 }
1299                 break;
1300         }
1301
1302         request_free(&fake);
1303
1304         return rcode;
1305 }