~ubuntu-branches/ubuntu/hardy/freeradius/hardy-proposed

« back to all changes in this revision

Viewing changes to src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2006-12-16 20:45:11 UTC
  • mfrom: (3.1.10 feisty)
  • Revision ID: james.westby@ubuntu.com-20061216204511-3pbbsu4s8jtehsor
Tags: 1.1.3-3
Fix POSIX compliance problem in init script.  Closes: #403384. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * eap_tls.c
3
 
 *
4
 
 * Version:     $Id: eap_tls.c,v 1.22.2.1 2004/09/01 19:30:48 aland Exp $
5
 
 *
6
 
 *   This program is free software; you can redistribute it and/or modify
7
 
 *   it under the terms of the GNU General Public License as published by
8
 
 *   the Free Software Foundation; either version 2 of the License, or
9
 
 *   (at your option) any later version.
10
 
 *
11
 
 *   This program is distributed in the hope that it will be useful,
12
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *   GNU General Public License for more details.
15
 
 *
16
 
 *   You should have received a copy of the GNU General Public License
17
 
 *   along with this program; if not, write to the Free Software
18
 
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 *
20
 
 * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21
 
 * Copyright 2003  Alan DeKok <aland@freeradius.org>
22
 
 */
23
 
 
24
 
/*
25
 
 *
26
 
 *  TLS Packet Format in EAP
27
 
 *  --- ------ ------ -- ---
28
 
 * 0                   1                   2                   3
29
 
 * 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
30
 
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31
 
 * |     Code      |   Identifier  |            Length             |
32
 
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33
 
 * |     Type      |     Flags     |      TLS Message Length
34
 
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35
 
 * |     TLS Message Length        |       TLS Data...
36
 
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37
 
 *
38
 
 */
39
 
 
40
 
#include "eap_tls.h"
41
 
 
42
 
/*
43
 
 *      Allocate a new TLS_PACKET
44
 
 */
45
 
EAPTLS_PACKET *eaptls_alloc(void)
46
 
{
47
 
        EAPTLS_PACKET   *rp;
48
 
 
49
 
        if ((rp = malloc(sizeof(EAPTLS_PACKET))) == NULL) {
50
 
                radlog(L_ERR, "rlm_eap_tls: out of memory");
51
 
                return NULL;
52
 
        }
53
 
        memset(rp, 0, sizeof(EAPTLS_PACKET));
54
 
        return rp;
55
 
}
56
 
 
57
 
/*
58
 
 *      Free EAPTLS_PACKET
59
 
 */
60
 
void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr)
61
 
{
62
 
        EAPTLS_PACKET *eaptls_packet;
63
 
 
64
 
        if (!eaptls_packet_ptr) return;
65
 
        eaptls_packet = *eaptls_packet_ptr;
66
 
        if (eaptls_packet == NULL) return;
67
 
 
68
 
        if (eaptls_packet->data) {
69
 
                free(eaptls_packet->data);
70
 
                eaptls_packet->data = NULL;
71
 
        }
72
 
 
73
 
        free(eaptls_packet);
74
 
        *eaptls_packet_ptr = NULL;
75
 
}
76
 
 
77
 
/*
78
 
   The S flag is set only within the EAP-TLS start message
79
 
   sent from the EAP server to the peer.
80
 
*/
81
 
int eaptls_start(EAP_DS *eap_ds, int peap_flag)
82
 
{
83
 
        EAPTLS_PACKET   reply;
84
 
 
85
 
        reply.code = EAPTLS_START;
86
 
        reply.length = TLS_HEADER_LEN + 1/*flags*/;
87
 
 
88
 
        reply.flags = peap_flag;
89
 
        reply.flags = SET_START(reply.flags);
90
 
 
91
 
        reply.data = NULL;
92
 
        reply.dlen = 0;
93
 
 
94
 
        eaptls_compose(eap_ds, &reply);
95
 
 
96
 
        return 1;
97
 
}
98
 
 
99
 
int eaptls_success(EAP_DS *eap_ds, int peap_flag)
100
 
{
101
 
        EAPTLS_PACKET   reply;
102
 
 
103
 
        reply.code = EAPTLS_SUCCESS;
104
 
        reply.length = TLS_HEADER_LEN;
105
 
        reply.flags = peap_flag;
106
 
        reply.data = NULL;
107
 
        reply.dlen = 0;
108
 
 
109
 
        eaptls_compose(eap_ds, &reply);
110
 
 
111
 
        return 1;
112
 
}
113
 
 
114
 
int eaptls_fail(EAP_DS *eap_ds, int peap_flag)
115
 
{
116
 
        EAPTLS_PACKET   reply;
117
 
 
118
 
        reply.code = EAPTLS_FAIL;
119
 
        reply.length = TLS_HEADER_LEN;
120
 
        reply.flags = peap_flag;
121
 
        reply.data = NULL;
122
 
        reply.dlen = 0;
123
 
 
124
 
        eaptls_compose(eap_ds, &reply);
125
 
 
126
 
        return 1;
127
 
}
128
 
 
129
 
/*
130
 
   A single TLS record may be up to 16384 octets in length, but a TLS
131
 
   message may span multiple TLS records, and a TLS certificate message
132
 
   may in principle be as long as 16MB.
133
 
*/
134
 
 
135
 
/*
136
 
 *      Frame the Dirty data that needs to be send to the client in an
137
 
 *      EAP-Request.  We always embed the TLS-length in all EAP-TLS
138
 
 *      packets that we send, for easy reference purpose.  Handle
139
 
 *      fragmentation and sending the next fragment etc.
140
 
 */
141
 
int eaptls_request(EAP_DS *eap_ds, tls_session_t *ssn)
142
 
{
143
 
        EAPTLS_PACKET   reply;
144
 
        unsigned int    size;
145
 
        unsigned int    nlen;
146
 
        unsigned int    lbit = 0;
147
 
 
148
 
        /* This value determines whether we set (L)ength flag for
149
 
                EVERY packet we send and add corresponding
150
 
                "TLS Message Length" field.
151
 
 
152
 
        length_flag = TRUE;
153
 
                This means we include L flag and "TLS Msg Len" in EVERY
154
 
                packet we send out.
155
 
 
156
 
        length_flag = FALSE;
157
 
                This means we include L flag and "TLS Msg Len" **ONLY**
158
 
                in First packet of a fragment series. We do not use
159
 
                it anywhere else.
160
 
 
161
 
                Having L flag in every packet is prefered.
162
 
 
163
 
        */
164
 
        if (ssn->length_flag) {
165
 
                lbit = 4;
166
 
        }
167
 
        if (ssn->fragment == 0) {
168
 
                ssn->tls_msg_len = ssn->dirty_out.used;
169
 
        }
170
 
 
171
 
        reply.code = EAPTLS_REQUEST;
172
 
        reply.flags = ssn->peap_flag;
173
 
 
174
 
        /* Send data, NOT more than the FRAGMENT size */
175
 
        if (ssn->dirty_out.used > ssn->offset) {
176
 
                size = ssn->offset;
177
 
                reply.flags = SET_MORE_FRAGMENTS(reply.flags);
178
 
                /* Length MUST be included if it is the First Fragment */
179
 
                if (ssn->fragment == 0) {
180
 
                        lbit = 4;
181
 
                }
182
 
                ssn->fragment = 1;
183
 
        } else {
184
 
                size = ssn->dirty_out.used;
185
 
                ssn->fragment = 0;
186
 
        }
187
 
 
188
 
        reply.dlen = lbit + size;
189
 
        reply.length = TLS_HEADER_LEN + 1/*flags*/ + reply.dlen;
190
 
 
191
 
        reply.data = malloc(reply.dlen);
192
 
        if (lbit) {
193
 
                nlen = htonl(ssn->tls_msg_len);
194
 
                memcpy(reply.data, &nlen, lbit);
195
 
                reply.flags = SET_LENGTH_INCLUDED(reply.flags);
196
 
        }
197
 
        record_minus(&ssn->dirty_out, reply.data + lbit, size);
198
 
 
199
 
        eaptls_compose(eap_ds, &reply);
200
 
        free(reply.data);
201
 
        reply.data = NULL;
202
 
 
203
 
        return 1;
204
 
}
205
 
 
206
 
/*
207
 
 * Acknowledge received is for one of the following messages sent earlier
208
 
 * 1. Handshake completed Message, so now send, EAP-Success
209
 
 * 2. Alert Message, now send, EAP-Failure
210
 
 * 3. Fragment Message, now send, next Fragment
211
 
 */
212
 
static eaptls_status_t eaptls_ack_handler(EAP_HANDLER *handler)
213
 
{
214
 
        tls_session_t *tls_session;
215
 
 
216
 
        tls_session = (tls_session_t *)handler->opaque;
217
 
        if (tls_session == NULL){
218
 
                radlog(L_ERR, "rlm_eap_tls: Unexpected ACK received");
219
 
                return EAPTLS_FAIL;
220
 
        }
221
 
        if (tls_session->info.initialized == 0) {
222
 
                DEBUG("  rlm_eap_tls: No SSL info available. Waiting for more SSL data.");
223
 
                return EAPTLS_REQUEST;
224
 
        }
225
 
        if (tls_session->info.origin == 0) {
226
 
                radlog(L_ERR, "rlm_eap_tls: Unexpected ACK received");
227
 
                return EAPTLS_FAIL;
228
 
        }
229
 
 
230
 
        switch (tls_session->info.content_type) {
231
 
        case alert:
232
 
                DEBUG2("  rlm_eap_tls: ack alert");
233
 
                eaptls_fail(handler->eap_ds, tls_session->peap_flag);
234
 
                return EAPTLS_FAIL;
235
 
 
236
 
        case handshake:
237
 
                if (tls_session->info.handshake_type == finished) {
238
 
                        DEBUG2("  rlm_eap_tls: ack handshake is finished");
239
 
                        return EAPTLS_SUCCESS;
240
 
                }
241
 
 
242
 
                DEBUG2("  rlm_eap_tls: ack handshake fragment handler");
243
 
                /* Fragmentation handler, send next fragment */
244
 
                return EAPTLS_REQUEST;
245
 
 
246
 
                /*
247
 
                 *      For the rest of the conditions, switch over
248
 
                 *      to the default section below.
249
 
                 */
250
 
        default:
251
 
                DEBUG2("  rlm_eap_tls: ack default");
252
 
                radlog(L_ERR, "rlm_eap_tls: Invalid ACK received: %d",
253
 
                       tls_session->info.content_type);
254
 
                return EAPTLS_FAIL;
255
 
        }
256
 
}
257
 
 
258
 
/*
259
 
 *      Similarly, when the EAP server receives an EAP-Response with
260
 
 *      the M bit set, it MUST respond with an EAP-Request with
261
 
 *      EAP-Type=EAP-TLS and no data. This serves as a fragment ACK.
262
 
 *
263
 
 *      In order to prevent errors in the processing of fragments, the
264
 
 *      EAP server MUST use increment the Identifier value for each
265
 
 *      fragment ACK contained within an EAP-Request, and the peer
266
 
 *      MUST include this Identifier value in the subsequent fragment
267
 
 *      contained within an EAP- Reponse.
268
 
 *
269
 
 *      EAP server sends an ACK when it determines there are More
270
 
 *      fragments to receive to make the complete
271
 
 *      TLS-record/TLS-Message
272
 
 */
273
 
static int eaptls_send_ack(EAP_DS *eap_ds, int peap_flag)
274
 
{
275
 
        EAPTLS_PACKET   reply;
276
 
 
277
 
        reply.code = EAPTLS_ACK;
278
 
        reply.length = TLS_HEADER_LEN + 1/*flags*/;
279
 
        reply.flags = peap_flag;
280
 
        reply.data = NULL;
281
 
        reply.dlen = 0;
282
 
 
283
 
        eaptls_compose(eap_ds, &reply);
284
 
 
285
 
        return 1;
286
 
}
287
 
 
288
 
/*
289
 
 *      The S flag is set only within the EAP-TLS start message sent
290
 
 *      from the EAP server to the peer.
291
 
 *
292
 
 *      Similarly, when the EAP server receives an EAP-Response with
293
 
 *      the M bit set, it MUST respond with an EAP-Request with
294
 
 *      EAP-Type=EAP-TLS and no data. This serves as a fragment
295
 
 *      ACK. The EAP peer MUST wait.
296
 
 */
297
 
static eaptls_status_t eaptls_verify(EAP_HANDLER *handler)
298
 
{
299
 
        EAP_DS *eap_ds = handler->eap_ds;
300
 
        EAP_DS *prev_eap_ds = handler->prev_eapds;
301
 
        eaptls_packet_t *eaptls_packet, *eaptls_prev = NULL;
302
 
 
303
 
        /*
304
 
         *      We don't check ANY of the input parameters.  It's all
305
 
         *      code which works together, so if something is wrong,
306
 
         *      we SHOULD core dump.
307
 
         *
308
 
         *      e.g. if eap_ds is NULL, of if eap_ds->response is
309
 
         *      NULL, of if it's NOT an EAP-Response, or if the packet
310
 
         *      is too short.  See eap_validation()., in ../../eap.c
311
 
         *
312
 
         *      Also, eaptype_select() takes care of selecting the
313
 
         *      appropriate type, so we don't need to check
314
 
         *      eap_ds->response->type.type == PW_EAP_TLS, or anything
315
 
         *      else.
316
 
         */
317
 
        eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;
318
 
        if (prev_eap_ds && prev_eap_ds->response)
319
 
                eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;
320
 
 
321
 
        /*
322
 
         *      check for ACK
323
 
         *
324
 
         *      If there's no TLS data, or there's 1 byte of TLS data,
325
 
         *      with the flags set to zero, then it's an ACK.
326
 
         *
327
 
         *      Find if this is a reply to the previous request sent
328
 
         */
329
 
        if ((eaptls_packet == NULL) ||
330
 
            ((eap_ds->response->length == EAP_HEADER_LEN + 2) &&
331
 
             ((eaptls_packet->flags & 0xc0) == 0x00))) {
332
 
 
333
 
                if (prev_eap_ds->request->id == eap_ds->response->id) {
334
 
                        /*
335
 
                         *      Run the ACK handler directly from here.
336
 
                         */
337
 
                        radlog(L_INFO, "rlm_eap_tls: Received EAP-TLS ACK message");
338
 
                        return eaptls_ack_handler(handler);
339
 
                } else {
340
 
                        radlog(L_ERR, "rlm_eap_tls: Received Invalid EAP-TLS ACK message");
341
 
                        return EAPTLS_INVALID;
342
 
                }
343
 
        }
344
 
 
345
 
        /*
346
 
         *      We send TLS_START, but do not receive it.
347
 
         */
348
 
        if (TLS_START(eaptls_packet->flags)) {
349
 
                radlog(L_ERR, "rlm_eap_tls:  Received unexpected EAP-TLS Start message");
350
 
                return EAPTLS_INVALID;
351
 
        }
352
 
 
353
 
        /*
354
 
         *      The L bit (length included) is set to indicate the
355
 
         *      presence of the four octet TLS Message Length field,
356
 
         *      and MUST be set for the first fragment of a fragmented
357
 
         *      TLS message or set of messages.
358
 
         *
359
 
         *      The M bit (more fragments) is set on all but the last
360
 
         *      fragment.
361
 
         *
362
 
         *      The S bit (EAP-TLS start) is set in an EAP-TLS Start
363
 
         *      message. This differentiates the EAP-TLS Start message
364
 
         *      from a fragment acknowledgement.
365
 
         */
366
 
        if (TLS_LENGTH_INCLUDED(eaptls_packet->flags)) {
367
 
                if (TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
368
 
                        /*
369
 
                         * FIRST_FRAGMENT is identified
370
 
                         * 1. If there is no previous EAP-response received.
371
 
                         * 2. If EAP-response received, then its M bit not set.
372
 
                         *      (It is because Last fragment will not have M bit set)
373
 
                         */
374
 
                        if ((prev_eap_ds->response == NULL) ||
375
 
                            (eaptls_prev == NULL) ||
376
 
                            !TLS_MORE_FRAGMENTS(eaptls_prev->flags)) {
377
 
 
378
 
                                radlog(L_INFO, "rlm_eap_tls:  Received EAP-TLS First Fragment of the message");
379
 
                                return EAPTLS_FIRST_FRAGMENT;
380
 
                        } else {
381
 
 
382
 
                                radlog(L_INFO, "rlm_eap_tls:  More Fragments with length included");
383
 
                                return EAPTLS_MORE_FRAGMENTS_WITH_LENGTH;
384
 
                        }
385
 
                } else {
386
 
 
387
 
                        radlog(L_INFO, "rlm_eap_tls:  Length Included");
388
 
                        return EAPTLS_LENGTH_INCLUDED;
389
 
                }
390
 
        }
391
 
 
392
 
        if (TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
393
 
                radlog(L_INFO, "rlm_eap_tls:  More fragments to follow");
394
 
                return EAPTLS_MORE_FRAGMENTS;
395
 
        }
396
 
 
397
 
        /*
398
 
         *      None of the flags are set, but it's still a valid
399
 
         *      EAPTLS packet.
400
 
         */
401
 
        return EAPTLS_OK;
402
 
}
403
 
 
404
 
/*
405
 
 * EAPTLS_PACKET
406
 
 * code   =  EAP-code
407
 
 * id     =  EAP-id
408
 
 * length = code + id + length + flags + tlsdata
409
 
 *        =  1   +  1 +   2    +  1    +  X
410
 
 * length = EAP-length - 1(EAP-Type = 1 octet)
411
 
 * flags  = EAP-typedata[0] (1 octet)
412
 
 * dlen   = EAP-typedata[1-4] (4 octets), if L flag set
413
 
 *        = length - 5(code+id+length+flags), otherwise
414
 
 * data   = EAP-typedata[5-n], if L flag set
415
 
 *        = EAP-typedata[1-n], otherwise
416
 
 * packet = EAP-typedata (complete typedata)
417
 
 *
418
 
 * Points to consider during EAP-TLS data extraction
419
 
 * 1. In the received packet, No data will be present incase of ACK-NAK
420
 
 * 2. Incase if more fragments need to be received then ACK after retreiving this fragment.
421
 
 *
422
 
 *  RFC 2716 Section 4.2.  PPP EAP TLS Request Packet
423
 
 *
424
 
 *  0                   1                   2                   3
425
 
 *  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
426
 
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
427
 
 *  |     Code      |   Identifier  |            Length             |
428
 
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
429
 
 *  |     Type      |     Flags     |      TLS Message Length
430
 
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
431
 
 *  |     TLS Message Length        |       TLS Data...
432
 
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
433
 
 *
434
 
 *  The Length field is two octets and indicates the length of the EAP
435
 
 *  packet including the Code, Identifir, Length, Type, and TLS data
436
 
 *  fields.
437
 
 */
438
 
static EAPTLS_PACKET *eaptls_extract(EAP_DS *eap_ds, eaptls_status_t status)
439
 
{
440
 
        EAPTLS_PACKET   *tlspacket;
441
 
        uint32_t        data_len = 0;
442
 
        uint32_t        len = 0;
443
 
        uint8_t         *data = NULL;
444
 
 
445
 
        if (status  == EAPTLS_INVALID)
446
 
                return NULL;
447
 
 
448
 
        /*
449
 
         *      The main EAP code & eaptls_verify() take care of
450
 
         *      ensuring that the packet is OK, and that we can
451
 
         *      extract the various fields we want.
452
 
         *
453
 
         *      e.g. a TLS packet with zero data is allowed as an ACK,
454
 
         *      but we will never see it here, as we will simply
455
 
         *      send another fragment, instead of trying to extract
456
 
         *      the data.
457
 
         *
458
 
         *      MUST have TLS type octet, followed by flags, followed
459
 
         *      by data.
460
 
         */
461
 
        rad_assert(eap_ds->response->length > 2);
462
 
 
463
 
        tlspacket = eaptls_alloc();
464
 
        if (tlspacket == NULL) return NULL;
465
 
 
466
 
        /*
467
 
         *      Code & id for EAPTLS & EAP are same
468
 
         *      but eaptls_length = eap_length - 1(EAP-Type = 1 octet)
469
 
         *
470
 
         *      length = code + id + length + type + tlsdata
471
 
         *             =  1   +  1 +   2    +  1    +  X
472
 
         */
473
 
        tlspacket->code = eap_ds->response->code;
474
 
        tlspacket->id = eap_ds->response->id;
475
 
        tlspacket->length = eap_ds->response->length - 1; /* EAP type */
476
 
        tlspacket->flags = eap_ds->response->type.data[0];
477
 
 
478
 
        /*
479
 
         *      A quick sanity check of the flags.  If we've been told
480
 
         *      that there's a length, and there isn't one, then stop.
481
 
         */
482
 
        if (TLS_LENGTH_INCLUDED(tlspacket->flags) &&
483
 
            (tlspacket->length < 5)) { /* flags + TLS message length */
484
 
                radlog(L_ERR, "rlm_eap_tls: Invalid EAP-TLS packet received.  (Length bit is set, but no length was found.)");
485
 
                eaptls_free(&tlspacket);
486
 
                return NULL;
487
 
        }
488
 
 
489
 
        /*
490
 
         *      If the final TLS packet is larger than we can handle, die
491
 
         *      now.
492
 
         *
493
 
         *      Likewise, if the EAP packet says N bytes, and the TLS
494
 
         *      packet says there's fewer bytes, it's a problem.
495
 
         *
496
 
         *      FIXME: Try to ensure that the claimed length is
497
 
         *      consistent across multiple TLS fragments.
498
 
         */
499
 
        if (TLS_LENGTH_INCLUDED(tlspacket->flags)) {
500
 
                memcpy(&data_len, &eap_ds->response->type.data[1], 4);
501
 
                data_len = ntohl(data_len);
502
 
                if (data_len > MAX_RECORD_SIZE) {
503
 
                        radlog(L_ERR, "rlm_eap_tls: The EAP-TLS packet will contain more data than we can process.");
504
 
                        eaptls_free(&tlspacket);
505
 
                        return NULL;
506
 
                }
507
 
 
508
 
#if 0
509
 
                DEBUG2(" TLS: %d %d\n", data_len, tlspacket->length);
510
 
 
511
 
                if (data_len < tlspacket->length) {
512
 
                        radlog(L_ERR, "rlm_eap_tls: EAP-TLS packet claims to be smaller than the encapsulating EAP packet.");
513
 
                        eaptls_free(&tlspacket);
514
 
                        return NULL;
515
 
                }
516
 
#endif
517
 
        }
518
 
 
519
 
        switch (status) {
520
 
        /*
521
 
         *      The TLS Message Length field is four octets, and
522
 
         *      provides the total length of the TLS message or set of
523
 
         *      messages that is being fragmented; this simplifies
524
 
         *      buffer allocation.
525
 
         *
526
 
         *      Dynamic allocation of buffers as & when we know the
527
 
         *      length should solve the problem.
528
 
         */
529
 
        case EAPTLS_FIRST_FRAGMENT:
530
 
        case EAPTLS_LENGTH_INCLUDED:
531
 
        case EAPTLS_MORE_FRAGMENTS_WITH_LENGTH:
532
 
                if (tlspacket->length < 5) { /* flags + TLS message length */
533
 
                        radlog(L_ERR, "rlm_eap_tls: Invalid EAP-TLS packet received.  (Expected length, got none.)");
534
 
                        eaptls_free(&tlspacket);
535
 
                        return NULL;
536
 
                }
537
 
 
538
 
                /*
539
 
                 *      Extract all the TLS fragments from the
540
 
                 *      previous eap_ds Start appending this
541
 
                 *      fragment to the above ds
542
 
                 */
543
 
                memcpy(&data_len, &eap_ds->response->type.data[1], sizeof(uint32_t));
544
 
                data_len = ntohl(data_len);
545
 
                data = (eap_ds->response->type.data + 5/*flags+TLS-Length*/);
546
 
                len = eap_ds->response->type.length - 5/*flags+TLS-Length*/;
547
 
 
548
 
                /*
549
 
                 *      Hmm... this should be an error, too.
550
 
                 */
551
 
                if (data_len > len) {
552
 
                        data_len = len;
553
 
                }
554
 
                break;
555
 
 
556
 
                /*
557
 
                 *      Data length is implicit, from the EAP header.
558
 
                 */
559
 
        case EAPTLS_MORE_FRAGMENTS:
560
 
        case EAPTLS_OK:
561
 
                data_len = eap_ds->response->type.length - 1/*flags*/;
562
 
                data = eap_ds->response->type.data + 1/*flags*/;
563
 
                break;
564
 
 
565
 
        default:
566
 
                radlog(L_ERR, "rlm_eap_tls: Invalid EAP-TLS packet received");
567
 
                eaptls_free(&tlspacket);
568
 
                return NULL;
569
 
        }
570
 
 
571
 
        tlspacket->dlen = data_len;
572
 
        if (data_len) {
573
 
                tlspacket->data = (unsigned char *)malloc(data_len);
574
 
                if (tlspacket->data == NULL) {
575
 
                        radlog(L_ERR, "rlm_eap_tls: out of memory");
576
 
                        eaptls_free(&tlspacket);
577
 
                        return NULL;
578
 
                }
579
 
                memcpy(tlspacket->data, data, data_len);
580
 
        }
581
 
 
582
 
        return tlspacket;
583
 
}
584
 
 
585
 
 
586
 
 
587
 
/*
588
 
 * To process the TLS,
589
 
 *  INCOMING DATA:
590
 
 *      1. EAP-TLS should get the compelete TLS data from the peer.
591
 
 *      2. Store that data in a data structure with any other required info
592
 
 *      3. Handle that data structure to the TLS module.
593
 
 *      4. TLS module will perform its operations on the data and
594
 
 *      handle back to EAP-TLS
595
 
 *
596
 
 *  OUTGOING DATA:
597
 
 *      1. EAP-TLS if necessary will fragment it and send it to the
598
 
 *      destination.
599
 
 *
600
 
 *      During EAP-TLS initialization, TLS Context object will be
601
 
 *      initialized and stored.  For every new authentication
602
 
 *      requests, TLS will open a new session object and that session
603
 
 *      object should be maintained even after the session is
604
 
 *      completed for session resumption. (Probably later as a feature
605
 
 *      as we donot know who maintains these session objects ie,
606
 
 *      SSL_CTX (internally) or TLS module(explicitly). If TLS module,
607
 
 *      then how to let SSL API know about these sessions.)
608
 
 */
609
 
static void eaptls_operation(EAPTLS_PACKET *eaptls_packet UNUSED,
610
 
                             eaptls_status_t status, EAP_HANDLER *handler)
611
 
{
612
 
        tls_session_t *tls_session;
613
 
 
614
 
        tls_session = (tls_session_t *)handler->opaque;
615
 
 
616
 
        if ((status == EAPTLS_MORE_FRAGMENTS) ||
617
 
            (status == EAPTLS_MORE_FRAGMENTS_WITH_LENGTH) ||
618
 
            (status == EAPTLS_FIRST_FRAGMENT)) {
619
 
                /*
620
 
                 * Send the ACK.
621
 
                 */
622
 
                eaptls_send_ack(handler->eap_ds, tls_session->peap_flag);
623
 
        } else {
624
 
                /*
625
 
                 *      We have the complete TLS-data or TLS-message.
626
 
                 *
627
 
                 *      Clean the dirty message.
628
 
                 *
629
 
                 *      Authenticate the user and send
630
 
                 *      Success/Failure.
631
 
                 *
632
 
                 *      If more info
633
 
                 *      is required then send another request.  */
634
 
                if (tls_handshake_recv(tls_session)) {
635
 
                        /*
636
 
                         *      FIXME: return success/fail.
637
 
                         *
638
 
                         *      TLS proper can decide what to do, then.
639
 
                         */
640
 
                        eaptls_request(handler->eap_ds, tls_session);
641
 
                } else {
642
 
                        eaptls_fail(handler->eap_ds, tls_session->peap_flag);
643
 
                }
644
 
        }
645
 
        return;
646
 
}
647
 
 
648
 
 
649
 
/*
650
 
 * In the actual authentication first verify the packet and then create the data structure
651
 
 */
652
 
/*
653
 
 * To process the TLS,
654
 
 *  INCOMING DATA:
655
 
 *      1. EAP-TLS should get the compelete TLS data from the peer.
656
 
 *      2. Store that data in a data structure with any other required info
657
 
 *      3. Hand this data structure to the TLS module.
658
 
 *      4. TLS module will perform its operations on the data and hands back to EAP-TLS
659
 
 *  OUTGOING DATA:
660
 
 *      1. EAP-TLS if necessary will fragment it and send it to the destination.
661
 
 *
662
 
 *      During EAP-TLS initialization, TLS Context object will be
663
 
 *      initialized and stored.  For every new authentication
664
 
 *      requests, TLS will open a new session object and that
665
 
 *      session object SHOULD be maintained even after the session
666
 
 *      is completed, for session resumption. (Probably later as a
667
 
 *      feature, as we do not know who maintains these session
668
 
 *      objects ie, SSL_CTX (internally) or TLS module (explicitly). If
669
 
 *      TLS module, then how to let SSL API know about these
670
 
 *      sessions.)
671
 
 */
672
 
 
673
 
/*
674
 
 *      Process an EAP request
675
 
 */
676
 
eaptls_status_t eaptls_process(EAP_HANDLER *handler)
677
 
{
678
 
        tls_session_t *tls_session = (tls_session_t *) handler->opaque;
679
 
        EAPTLS_PACKET   *tlspacket;
680
 
        eaptls_status_t status;
681
 
 
682
 
        DEBUG2("  rlm_eap_tls: processing TLS");
683
 
 
684
 
        /* This case is when SSL generates Alert then we
685
 
         * send that alert to the client and then send the EAP-Failure
686
 
         */
687
 
        status = eaptls_verify(handler);
688
 
        DEBUG2("  eaptls_verify returned %d\n", status);
689
 
 
690
 
        switch (status) {
691
 
        default:
692
 
        case EAPTLS_INVALID:
693
 
        case EAPTLS_FAIL:
694
 
 
695
 
                /*
696
 
                 *      Success means that we're done the initial
697
 
                 *      handshake.  For TTLS, this means send stuff
698
 
                 *      back to the client, and the client sends us
699
 
                 *      more tunneled data.
700
 
                 */
701
 
        case EAPTLS_SUCCESS:
702
 
                return status;
703
 
                break;
704
 
 
705
 
                /*
706
 
                 *      Normal TLS request, continue with the "get rest
707
 
                 *      of fragments" phase.
708
 
                 */
709
 
        case EAPTLS_REQUEST:
710
 
                eaptls_request(handler->eap_ds, tls_session);
711
 
                return EAPTLS_HANDLED;
712
 
                break;
713
 
 
714
 
                /*
715
 
                 *      The handshake is done, and we're in the "tunnel
716
 
                 *      data" phase.
717
 
                 */
718
 
        case EAPTLS_OK:
719
 
                DEBUG2("  rlm_eap_tls: Done initial handshake");
720
 
 
721
 
                /*
722
 
                 *      Get the rest of the fragments.
723
 
                 */
724
 
        case EAPTLS_FIRST_FRAGMENT:
725
 
        case EAPTLS_MORE_FRAGMENTS:
726
 
        case EAPTLS_LENGTH_INCLUDED:
727
 
        case EAPTLS_MORE_FRAGMENTS_WITH_LENGTH:
728
 
                break;
729
 
        }
730
 
 
731
 
        /*
732
 
         *      Extract the TLS packet from the buffer.
733
 
         */
734
 
        if ((tlspacket = eaptls_extract(handler->eap_ds, status)) == NULL)
735
 
                return EAPTLS_FAIL;
736
 
 
737
 
        /*
738
 
         *      Get the session struct from the handler
739
 
         *
740
 
         *      update the dirty_in buffer
741
 
         *
742
 
         *      NOTE: This buffer will contain partial data when M bit is set.
743
 
         *
744
 
         *      CAUTION while reinitializing this buffer, it should be
745
 
         *      reinitialized only when this M bit is NOT set.
746
 
         */
747
 
        if (tlspacket->dlen !=
748
 
            record_plus(&tls_session->dirty_in, tlspacket->data, tlspacket->dlen)) {
749
 
                eaptls_free(&tlspacket);
750
 
                radlog(L_ERR, "rlm_eap_tls: Exceeded maximum record size");
751
 
                return EAPTLS_FAIL;
752
 
        }
753
 
 
754
 
        /*
755
 
         *      SSL initalization is done.  Return.
756
 
         *
757
 
         *      The TLS data will be in the tls_session structure.
758
 
         */
759
 
        if (SSL_is_init_finished(tls_session->ssl)) {
760
 
                eaptls_free(&tlspacket);
761
 
                return EAPTLS_OK;
762
 
        }
763
 
 
764
 
        /*
765
 
         *      Continue the handshake.
766
 
         */
767
 
        eaptls_operation(tlspacket, status, handler);
768
 
 
769
 
        eaptls_free(&tlspacket);
770
 
        return EAPTLS_HANDLED;
771
 
}
772
 
 
773
 
 
774
 
/*
775
 
 *      compose the TLS reply packet in the EAP reply typedata
776
 
 */
777
 
int eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply)
778
 
{
779
 
        uint8_t *ptr;
780
 
 
781
 
        /*
782
 
         *      Don't set eap_ds->request->type.type, as the main EAP
783
 
         *      handler will do that for us.  This allows the TLS
784
 
         *      module to be called from TTLS & PEAP.
785
 
         */
786
 
 
787
 
        /*
788
 
         *      When the EAP server receives an EAP-Response with the
789
 
         *      M bit set, it MUST respond with an EAP-Request with
790
 
         *      EAP-Type=EAP-TLS and no data. This serves as a
791
 
         *      fragment ACK. The EAP peer MUST wait until it receives
792
 
         *      the EAP-Request before sending another fragment.
793
 
         *
794
 
         *      In order to prevent errors in the processing of
795
 
         *      fragments, the EAP server MUST use increment the
796
 
         *      Identifier value for each fragment ACK contained
797
 
         *      within an EAP-Request, and the peer MUST include this
798
 
         *      Identifier value in the subsequent fragment contained
799
 
         *      within an EAP- Reponse.
800
 
         */
801
 
        eap_ds->request->type.data = malloc(reply->length - TLS_HEADER_LEN + 1);
802
 
        if (eap_ds->request->type.data == NULL) {
803
 
                radlog(L_ERR, "rlm_eap_tls: out of memory");
804
 
                return 0;
805
 
        }
806
 
 
807
 
        /* EAPTLS Header length is excluded while computing EAP typelen */
808
 
        eap_ds->request->type.length = reply->length - TLS_HEADER_LEN;
809
 
 
810
 
        ptr = eap_ds->request->type.data;
811
 
        *ptr++ = (uint8_t)(reply->flags & 0xFF);
812
 
 
813
 
        if (reply->dlen) memcpy(ptr, reply->data, reply->dlen);
814
 
 
815
 
        switch (reply->code) {
816
 
        case EAPTLS_ACK:
817
 
        case EAPTLS_START:
818
 
        case EAPTLS_REQUEST:
819
 
                eap_ds->request->code = PW_EAP_REQUEST;
820
 
                break;
821
 
        case EAPTLS_SUCCESS:
822
 
                eap_ds->request->code = PW_EAP_SUCCESS;
823
 
                break;
824
 
        case EAPTLS_FAIL:
825
 
                eap_ds->request->code = PW_EAP_FAILURE;
826
 
                break;
827
 
        default:
828
 
                /* Should never enter here */
829
 
                eap_ds->request->code = PW_EAP_FAILURE;
830
 
                break;
831
 
        }
832
 
 
833
 
        return 1;
834
 
}