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