~ubuntu-branches/ubuntu/natty/freeradius/natty-updates

« back to all changes in this revision

Viewing changes to src/lib/radius.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hampson
  • Date: 2006-01-15 13:34:13 UTC
  • mto: (3.1.3 dapper) (4.1.3 sid) (1.1.14 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20060115133413-zo1dslttvdoalqym
Tags: upstream-1.1.0
ImportĀ upstreamĀ versionĀ 1.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * radius.c     Functions to send/receive radius packets.
3
3
 *
4
 
 * Version:     $Id: radius.c,v 1.125.2.5 2005/08/19 19:43:46 aland Exp $
 
4
 * Version:     $Id: radius.c,v 1.125.2.5.2.3 2005/12/19 19:42:38 aland Exp $
5
5
 *
6
6
 *   This library is free software; you can redistribute it and/or
7
7
 *   modify it under the terms of the GNU Lesser General Public
20
20
 * Copyright 2000-2003  The FreeRADIUS server project
21
21
 */
22
22
 
23
 
static const char rcsid[] = "$Id: radius.c,v 1.125.2.5 2005/08/19 19:43:46 aland Exp $";
 
23
static const char rcsid[] = "$Id: radius.c,v 1.125.2.5.2.3 2005/12/19 19:42:38 aland Exp $";
24
24
 
25
25
#include        "autoconf.h"
26
26
#include        "md5.h"
85
85
} radius_packet_t;
86
86
 
87
87
static lrad_randctx lrad_rand_pool;     /* across multiple calls */
88
 
static int lrad_pool_initialized = 0;
 
88
static volatile int lrad_rand_index = -1;
 
89
static unsigned int salt_offset = 0;
89
90
 
90
91
static const char *packet_codes[] = {
91
92
  "",
142
143
  "IP-Address-Release"
143
144
};
144
145
 
145
 
/*
146
 
 *  Internal prototypes
147
 
 */
148
 
static void make_secret(unsigned char *digest, uint8_t *vector,
149
 
                        const char *secret, char *value);
 
146
 
 
147
#define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
 
148
/*************************************************************************
 
149
 *
 
150
 *      Function: make_secret
 
151
 *
 
152
 *      Purpose: Build an encrypted secret value to return in a reply
 
153
 *               packet.  The secret is hidden by xoring with a MD5 digest
 
154
 *               created from the shared secret and the authentication
 
155
 *               vector.  We put them into MD5 in the reverse order from
 
156
 *               that used when encrypting passwords to RADIUS.
 
157
 *
 
158
 *************************************************************************/
 
159
static void make_secret(uint8_t *digest, const uint8_t *vector,
 
160
                        const char *secret, const uint8_t *value)
 
161
{
 
162
        MD5_CTX context;
 
163
        int             i;
 
164
 
 
165
        MD5Init(&context);
 
166
        MD5Update(&context, vector, AUTH_VECTOR_LEN);
 
167
        MD5Update(&context, secret, strlen(secret));
 
168
        MD5Final(digest, &context);
 
169
 
 
170
        for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
 
171
                digest[i] ^= value[i];
 
172
        }
 
173
}
 
174
 
 
175
#define MAX_PASS_LEN (128)
 
176
static void make_passwd(uint8_t *output, int *outlen,
 
177
                        const uint8_t *input, int inlen,
 
178
                        const char *secret, const uint8_t *vector)
 
179
{
 
180
        MD5_CTX context, old;
 
181
        uint8_t digest[AUTH_VECTOR_LEN];
 
182
        uint8_t passwd[MAX_PASS_LEN];
 
183
        int     i, n;
 
184
        int     len;
 
185
 
 
186
        /*
 
187
         *      If the length is zero, round it up.
 
188
         */
 
189
        len = inlen;
 
190
        if (len == 0) {
 
191
                len = AUTH_PASS_LEN;
 
192
        }
 
193
        else if (len > MAX_PASS_LEN) len = MAX_PASS_LEN;
 
194
 
 
195
        else if ((len & 0x0f) != 0) {
 
196
                len += 0x0f;
 
197
                len &= ~0x0f;
 
198
        }
 
199
        *outlen = len;
 
200
 
 
201
        memcpy(passwd, input, len);
 
202
        memset(passwd + len, 0, sizeof(passwd) - len);
 
203
 
 
204
        MD5Init(&context);
 
205
        MD5Update(&context, secret, strlen(secret));
 
206
        old = context;
 
207
 
 
208
        /*
 
209
         *      Do first pass.
 
210
         */
 
211
        MD5Update(&context, vector, AUTH_PASS_LEN);
 
212
 
 
213
        for (n = 0; n < len; n += AUTH_PASS_LEN) {
 
214
                if (n > 0) {
 
215
                        context = old;
 
216
                        MD5Update(&context,
 
217
                                       passwd + n - AUTH_PASS_LEN,
 
218
                                       AUTH_PASS_LEN);
 
219
                }
 
220
 
 
221
                MD5Final(digest, &context);
 
222
                for (i = 0; i < AUTH_PASS_LEN; i++) {
 
223
                        passwd[i + n] ^= digest[i];
 
224
                }
 
225
        }
 
226
 
 
227
        memcpy(output, passwd, len);
 
228
}
 
229
 
 
230
static void make_tunnel_passwd(uint8_t *output, int *outlen,
 
231
                               const uint8_t *input, int inlen, int room,
 
232
                               const char *secret, const uint8_t *vector)
 
233
{
 
234
        MD5_CTX context, old;
 
235
        uint8_t digest[AUTH_VECTOR_LEN];
 
236
        uint8_t passwd[MAX_STRING_LEN + AUTH_VECTOR_LEN];
 
237
        int     i, n;
 
238
        int     len;
 
239
 
 
240
        /*
 
241
         *      Account for 2 bytes of the salt, and round the room
 
242
         *      available down to the nearest multiple of 16.  Then,
 
243
         *      subtract one from that to account for the length byte,
 
244
         *      and the resulting number is the upper bound on the data
 
245
         *      to copy.
 
246
         *
 
247
         *      We could short-cut this calculation just be forcing
 
248
         *      inlen to be no more than 239.  It would work for all
 
249
         *      VSA's, as we don't pack multiple VSA's into one
 
250
         *      attribute.
 
251
         *
 
252
         *      However, this calculation is more general, if a little
 
253
         *      complex.  And it will work in the future for all possible
 
254
         *      kinds of weird attribute packing.
 
255
         */
 
256
        room -= 2;
 
257
        room -= (room & 0x0f);
 
258
        room--;
 
259
 
 
260
        if (inlen > room) inlen = room;
 
261
 
 
262
        /*
 
263
         *      Length of the encrypted data is password length plus
 
264
         *      one byte for the length of the password.
 
265
         */
 
266
        len = inlen + 1;
 
267
        if ((len & 0x0f) != 0) {
 
268
                len += 0x0f;
 
269
                len &= ~0x0f;
 
270
        }
 
271
        *outlen = len + 2;      /* account for the salt */
 
272
 
 
273
        /*
 
274
         *      Copy the password over.
 
275
         */
 
276
        memcpy(passwd + 3, input, inlen);
 
277
        memset(passwd + 3 + inlen, 0, sizeof(passwd) - 3 - inlen);
 
278
 
 
279
        /*
 
280
         *      Generate salt.  The RFC's say:
 
281
         *
 
282
         *      The high bit of salt[0] must be set, each salt in a
 
283
         *      packet should be unique, and they should be random
 
284
         *
 
285
         *      So, we set the high bit, add in a counter, and then
 
286
         *      add in some CSPRNG data.  should be OK..
 
287
         */
 
288
        passwd[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
 
289
                     (lrad_rand() & 0x07));
 
290
        passwd[1] = lrad_rand();
 
291
        passwd[2] = inlen;      /* length of the password string */
 
292
 
 
293
        MD5Init(&context);
 
294
        MD5Update(&context, secret, strlen(secret));
 
295
        old = context;
 
296
 
 
297
        MD5Update(&context, vector, AUTH_VECTOR_LEN);
 
298
        MD5Update(&context, &passwd[0], 2);
 
299
 
 
300
        for (n = 0; n < len; n += AUTH_PASS_LEN) {
 
301
                if (n > 0) {
 
302
                        context = old;
 
303
                        MD5Update(&context,
 
304
                                       passwd + 2 + n - AUTH_PASS_LEN,
 
305
                                       AUTH_PASS_LEN);
 
306
                }
 
307
 
 
308
                MD5Final(digest, &context);
 
309
                for (i = 0; i < AUTH_PASS_LEN; i++) {
 
310
                        passwd[i + 2 + n] ^= digest[i];
 
311
                }
 
312
        }
 
313
        memcpy(output, passwd, len + 2);
 
314
}
 
315
 
 
316
 
 
317
/*
 
318
 *      Parse a data structure into a RADIUS attribute.
 
319
 */
 
320
int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
321
                const char *secret, const VALUE_PAIR *vp, uint8_t *ptr)
 
322
{
 
323
        int             vendorcode;
 
324
        int             offset, len, total_length;
 
325
        uint32_t        lvalue;
 
326
        uint8_t         *length_ptr, *vsa_length_ptr;
 
327
        const uint8_t   *data = NULL;
 
328
        uint8_t         array[4];
 
329
 
 
330
        vendorcode = total_length = 0;
 
331
        length_ptr = vsa_length_ptr = NULL;
 
332
        
 
333
        /*
 
334
         *      For interoperability, always put vendor attributes
 
335
         *      into their own VSA.
 
336
         */
 
337
        if ((vendorcode = VENDOR(vp->attribute)) != 0) {
 
338
                /*
 
339
                 *      Build a VSA header.
 
340
                 */
 
341
                *ptr++ = PW_VENDOR_SPECIFIC;
 
342
                vsa_length_ptr = ptr;
 
343
                *ptr++ = 6;
 
344
                lvalue = htonl(vendorcode);
 
345
                memcpy(ptr, &lvalue, 4);
 
346
                ptr += 4;
 
347
                total_length += 6;
 
348
                
 
349
                if (vendorcode == VENDORPEC_USR) {
 
350
                        lvalue = htonl(vp->attribute & 0xFFFF);
 
351
                        memcpy(ptr, &lvalue, 4);
 
352
                        
 
353
                        length_ptr = vsa_length_ptr;
 
354
                        
 
355
                        total_length += 4;
 
356
                        *length_ptr  += 4;
 
357
                        ptr          += 4;
 
358
                        
 
359
                        /*
 
360
                         *      We don't have two different lengths.
 
361
                         */
 
362
                        vsa_length_ptr = NULL;
 
363
                        
 
364
                } else if (vendorcode == VENDORPEC_LUCENT) {
 
365
                        /*
 
366
                         *      16-bit attribute, 8-bit length
 
367
                         */
 
368
                        *ptr++ = ((vp->attribute >> 8) & 0xFF);
 
369
                        *ptr++ = (vp->attribute & 0xFF);
 
370
                        length_ptr = ptr;
 
371
                        *vsa_length_ptr += 3;
 
372
                        *ptr++ = 3;
 
373
                        total_length += 3;
 
374
 
 
375
                } else if (vendorcode == VENDORPEC_STARENT) {
 
376
                        /*
 
377
                         *      16-bit attribute, 16-bit length
 
378
                         *      with the upper 8 bits of the length
 
379
                         *      always zero!
 
380
                         */
 
381
                        *ptr++ = ((vp->attribute >> 8) & 0xFF);
 
382
                        *ptr++ = (vp->attribute & 0xFF);
 
383
                        *ptr++ = 0;
 
384
                        length_ptr = ptr;
 
385
                        *vsa_length_ptr += 4;
 
386
                        *ptr++ = 4;
 
387
                        total_length += 4;
 
388
                } else {
 
389
                        /*
 
390
                         *      All other VSA's are encoded the same
 
391
                         *      as RFC attributes.
 
392
                         */
 
393
                        *vsa_length_ptr += 2;
 
394
                        goto rfc;
 
395
                }
 
396
        } else {
 
397
        rfc:
 
398
                /*
 
399
                 *      All other attributes are encoded as
 
400
                 *      per the RFC.
 
401
                 */
 
402
                *ptr++ = (vp->attribute & 0xFF);
 
403
                length_ptr = ptr;
 
404
                *ptr++ = 2;
 
405
                total_length += 2;
 
406
        }
 
407
 
 
408
        offset = 0;
 
409
        if (vp->flags.has_tag) {
 
410
                if (TAG_VALID(vp->flags.tag)) {
 
411
                        ptr[0] = vp->flags.tag & 0xff;
 
412
                        offset = 1;
 
413
            
 
414
                } else if (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
 
415
                        /*
 
416
                         *      Tunnel passwords REQUIRE a tag, even
 
417
                         *      if don't have a valid tag.
 
418
                         */
 
419
                        ptr[0] = 0;
 
420
                        offset = 1;
 
421
                } /* else don't write a tag */
 
422
        } /* else the attribute doesn't have a tag */
 
423
        
 
424
        /*
 
425
         *      Set up the default sources for the data.
 
426
         */
 
427
        data = vp->strvalue;
 
428
        len = vp->length;
 
429
 
 
430
        /*
 
431
         *      Encrypted passwords can't be very long.
 
432
         *      This check also ensures that the hashed version
 
433
         *      of the password + attribute header fits into one
 
434
         *      attribute.
 
435
         *
 
436
         *      FIXME: Print a warning message if it's too long?
 
437
         */
 
438
        if (vp->flags.encrypt && (len > MAX_PASS_LEN)) {
 
439
                len = MAX_PASS_LEN;
 
440
        }
 
441
 
 
442
        switch(vp->type) {
 
443
        case PW_TYPE_STRING:
 
444
        case PW_TYPE_OCTETS:
 
445
        case PW_TYPE_IFID:
 
446
        case PW_TYPE_IPV6ADDR:
 
447
        case PW_TYPE_IPV6PREFIX:
 
448
        case PW_TYPE_ABINARY:
 
449
                /* nothing more to do */
 
450
                break;
 
451
                        
 
452
        case PW_TYPE_INTEGER:
 
453
                len = 4;        /* just in case */
 
454
                lvalue = htonl(vp->lvalue);
 
455
                memcpy(array, &lvalue, sizeof(lvalue));
 
456
 
 
457
                /*
 
458
                 *      Perhaps discard the first octet.
 
459
                 */
 
460
                data = &array[offset];
 
461
                len -= offset;
 
462
                break;
 
463
                        
 
464
        case PW_TYPE_IPADDR:
 
465
                data = (const uint8_t *) &vp->lvalue;
 
466
                len = 4;        /* just in case */
 
467
                break;
 
468
 
 
469
                /*
 
470
                 *  There are no tagged date attributes.
 
471
                 */
 
472
        case PW_TYPE_DATE:
 
473
                lvalue = htonl(vp->lvalue);
 
474
                data = (const uint8_t *) &lvalue;
 
475
                len = 4;        /* just in case */
 
476
                break;
 
477
 
 
478
        default:                /* unknown type: ignore it */
 
479
                librad_log("ERROR: Unknown attribute type %d", vp->type);
 
480
                return -1;
 
481
        }
 
482
 
 
483
        /*
 
484
         *      Bound the data to 255 bytes.
 
485
         */
 
486
        if (len + offset + total_length > 255) {
 
487
                len = 255 - offset - total_length;
 
488
        }       
 
489
 
 
490
        /*
 
491
         *      Encrypt the various password styles
 
492
         *
 
493
         *      Attributes with encrypted values MUST be less than
 
494
         *      128 bytes long.
 
495
         */
 
496
        switch (vp->flags.encrypt) {
 
497
        case FLAG_ENCRYPT_USER_PASSWORD:
 
498
                make_passwd(ptr + offset, &len,
 
499
                            data, len,
 
500
                            secret, packet->vector);
 
501
                break;
 
502
                
 
503
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
 
504
                if (!original) {
 
505
                        librad_log("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
 
506
                        return -1;
 
507
                }
 
508
 
 
509
                /*
 
510
                 *      Check if 255 - offset - total_length is less
 
511
                 *      than 18.  If so, we can't fit the data into
 
512
                 *      the available space, and we discard the
 
513
                 *      attribute.
 
514
                 *
 
515
                 *      This is ONLY a problem if we have multiple VSA's
 
516
                 *      in one Vendor-Specific, though.
 
517
                 */
 
518
                if ((255 - offset - total_length) < 18) return 0;
 
519
 
 
520
                /*
 
521
                 *      Can't make the password, suppress it.
 
522
                 */
 
523
                make_tunnel_passwd(ptr + offset, &len,
 
524
                                   data, len, 255 - offset - total_length,
 
525
                                   secret, original->vector);
 
526
                break;
 
527
 
 
528
                /*
 
529
                 *      The code above ensures that this attribute
 
530
                 *      always fits.
 
531
                 */
 
532
        case FLAG_ENCRYPT_ASCEND_SECRET:
 
533
                make_secret(ptr + offset, packet->vector,
 
534
                            secret, data);
 
535
                len = AUTH_VECTOR_LEN;
 
536
                break;
 
537
 
 
538
                
 
539
        default:
 
540
                /*
 
541
                 *      Just copy the data over
 
542
                 */
 
543
                memcpy(ptr + offset, data, len);
 
544
                break;
 
545
        } /* switch over encryption flags */
 
546
 
 
547
        /*
 
548
         *      Account for the tag (if any).
 
549
         */
 
550
        len += offset;
 
551
 
 
552
        /*
 
553
         *      RFC 2865 section 5 says that zero-length attributes
 
554
         *      MUST NOT be sent.
 
555
         */
 
556
        if (len == 0) return 0;
 
557
 
 
558
        /*
 
559
         *      Update the various lengths.
 
560
         */
 
561
        *length_ptr += len;
 
562
        if (vsa_length_ptr) *vsa_length_ptr += len;
 
563
        ptr += len;
 
564
        total_length += len;
 
565
 
 
566
        return total_length;    /* of attribute */
 
567
}
 
568
 
 
569
 
 
570
/*
 
571
 *      Encode a packet.
 
572
 */
 
573
int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
574
               const char *secret)
 
575
{
 
576
        radius_packet_t *hdr;
 
577
        uint8_t         *ptr;
 
578
        uint16_t        total_length;
 
579
        int             len;
 
580
        VALUE_PAIR      *reply;
 
581
        
 
582
        /*
 
583
         *      For simplicity in the following logic, we allow
 
584
         *      the attributes to "overflow" the 4k maximum
 
585
         *      RADIUS packet size, by one attribute.
 
586
         *
 
587
         *      It's uint32_t, for alignment purposes.
 
588
         */
 
589
        uint32_t        data[(MAX_PACKET_LEN + 256) / 4];
 
590
 
 
591
        /*
 
592
         *      Double-check some things based on packet code.
 
593
         */
 
594
        switch (packet->code) {
 
595
        case PW_AUTHENTICATION_ACK:
 
596
        case PW_AUTHENTICATION_REJECT:
 
597
        case PW_ACCESS_CHALLENGE:
 
598
                if (!original) {
 
599
                        librad_log("ERROR: Cannot sign response packet without a request packet.");
 
600
                        return -1;
 
601
                }
 
602
                break;
 
603
                
 
604
                /*
 
605
                 *      These packet vectors start off as all zero.
 
606
                 */
 
607
        case PW_ACCOUNTING_REQUEST:
 
608
        case PW_DISCONNECT_REQUEST:
 
609
                memset(packet->vector, 0, sizeof(packet->vector));
 
610
                break;
 
611
                
 
612
        default:
 
613
                break;
 
614
        }
 
615
                
 
616
        /*
 
617
         *      Use memory on the stack, until we know how
 
618
         *      large the packet will be.
 
619
         */
 
620
        hdr = (radius_packet_t *) data;
 
621
        
 
622
        /*
 
623
         *      Build standard header
 
624
         */
 
625
        hdr->code = packet->code;
 
626
        hdr->id = packet->id;
 
627
        
 
628
        memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
 
629
 
 
630
        total_length = AUTH_HDR_LEN;
 
631
        packet->verified = 0;
 
632
        
 
633
        /*
 
634
         *      Load up the configuration values for the user
 
635
         */
 
636
        ptr = hdr->data;
 
637
 
 
638
        /*
 
639
         *      FIXME: Loop twice over the reply list.  The first time,
 
640
         *      calculate the total length of data.  The second time,
 
641
         *      allocate the memory, and fill in the VP's.
 
642
         *
 
643
         *      Hmm... this may be slower than just doing a small
 
644
         *      memcpy.
 
645
         */
 
646
        
 
647
        /*
 
648
         *      Loop over the reply attributes for the packet.
 
649
         */
 
650
        for (reply = packet->vps; reply; reply = reply->next) {
 
651
                /*
 
652
                 *      Ignore non-wire attributes
 
653
                 */
 
654
                if ((VENDOR(reply->attribute) == 0) &&
 
655
                    ((reply->attribute & 0xFFFF) > 0xff)) {
 
656
                        continue;
 
657
                }
 
658
                
 
659
                /*
 
660
                 *      Check that the packet is no more than 4k in
 
661
                 *      size, AFTER over-flowing the 4k boundary.
 
662
                 *      Note that the 'data' buffer, above, is one
 
663
                 *      attribute longer than necessary, in order to
 
664
                 *      permit this overflow.
 
665
                 */
 
666
                if (total_length > MAX_PACKET_LEN) {
 
667
                        librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
 
668
                        return -1;
 
669
                }
 
670
                
 
671
                /*
 
672
                 *      Set the Message-Authenticator to the correct
 
673
                 *      length and initial value.
 
674
                 */
 
675
                if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
 
676
                        reply->length = AUTH_VECTOR_LEN;
 
677
                        memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
 
678
                        packet->verified = total_length; /* HACK! */
 
679
                }
 
680
                
 
681
                /*
 
682
                 *      Print out ONLY the attributes which
 
683
                 *      we're sending over the wire, and print
 
684
                 *      them out BEFORE they're encrypted.
 
685
                 */
 
686
                debug_pair(reply);
 
687
 
 
688
                len = rad_vp2attr(packet, original, secret, reply, ptr);
 
689
                if (len < 0) return -1;
 
690
                ptr += len;
 
691
                total_length += len;
 
692
        } /* done looping over all attributes */
 
693
        
 
694
        /*
 
695
         *      Fill in the rest of the fields, and copy the data over
 
696
         *      from the local stack to the newly allocated memory.
 
697
         *
 
698
         *      Yes, all this 'memcpy' is slow, but it means
 
699
         *      that we only allocate the minimum amount of
 
700
         *      memory for a request.
 
701
         */
 
702
        packet->data_len = total_length;
 
703
        packet->data = (uint8_t *) malloc(packet->data_len);
 
704
        if (!packet->data) {
 
705
                librad_log("Out of memory");
 
706
                return -1;
 
707
        }
 
708
 
 
709
        memcpy(packet->data, data, packet->data_len);
 
710
        hdr = (radius_packet_t *) packet->data;
 
711
        
 
712
        total_length = htons(total_length);
 
713
        memcpy(hdr->length, &total_length, sizeof(total_length));
 
714
 
 
715
        return 0;
 
716
}
 
717
 
 
718
 
 
719
/*
 
720
 *      Sign a previously encoded packet.
 
721
 */
 
722
int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
723
             const char *secret)
 
724
{
 
725
        radius_packet_t *hdr = (radius_packet_t *)packet->data;
 
726
 
 
727
        /*
 
728
         *      It wasn't assigned an Id, this is bad!
 
729
         */
 
730
        if (packet->id < 0) {
 
731
                librad_log("ERROR: RADIUS packets must be assigned an Id.");
 
732
                return -1;
 
733
        }
 
734
 
 
735
        if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
 
736
            (packet->verified < 0)) {
 
737
                librad_log("ERROR: You must call rad_encode() before rad_sign()");
 
738
                return -1;
 
739
        }
 
740
 
 
741
        /*
 
742
         *      If there's a Message-Authenticator, update it
 
743
         *      now, BEFORE updating the authentication vector.
 
744
         *
 
745
         *      This is a hack...
 
746
         */
 
747
        if (packet->verified > 0) {
 
748
                uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
 
749
                
 
750
                switch (packet->code) {
 
751
                case PW_ACCOUNTING_REQUEST:
 
752
                case PW_ACCOUNTING_RESPONSE:
 
753
                case PW_DISCONNECT_REQUEST:
 
754
                case PW_DISCONNECT_ACK:
 
755
                case PW_DISCONNECT_NAK:
 
756
                case PW_COF_REQUEST:
 
757
                case PW_COF_ACK:
 
758
                case PW_COF_NAK:
 
759
                        memset(hdr->vector, 0, AUTH_VECTOR_LEN);
 
760
                        break;
 
761
 
 
762
                case PW_AUTHENTICATION_ACK:
 
763
                case PW_AUTHENTICATION_REJECT:
 
764
                case PW_ACCESS_CHALLENGE:
 
765
                        if (!original) {
 
766
                                librad_log("ERROR: Cannot sign response packet without a request packet.");
 
767
                                return -1;
 
768
                        }
 
769
                        memcpy(hdr->vector, original->vector,
 
770
                               AUTH_VECTOR_LEN);
 
771
                        break;
 
772
 
 
773
                default:        /* others have vector already set to zero */
 
774
                        break;
 
775
                        
 
776
                }
 
777
                
 
778
                /*
 
779
                 *      Set the authentication vector to zero,
 
780
                 *      calculate the signature, and put it
 
781
                 *      into the Message-Authenticator
 
782
                 *      attribute.
 
783
                 */
 
784
                lrad_hmac_md5(packet->data, packet->data_len,
 
785
                              secret, strlen(secret),
 
786
                              calc_auth_vector);
 
787
                memcpy(packet->data + packet->verified + 2,
 
788
                       calc_auth_vector, AUTH_VECTOR_LEN);
 
789
                
 
790
                /*
 
791
                 *      Copy the original request vector back
 
792
                 *      to the raw packet.
 
793
                 */
 
794
                memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
 
795
        }
 
796
        
 
797
        /*
 
798
         *      Switch over the packet code, deciding how to
 
799
         *      sign the packet.
 
800
         */
 
801
        switch (packet->code) {
 
802
                /*
 
803
                 *      Request packets are not signed, bur
 
804
                 *      have a random authentication vector.
 
805
                 */
 
806
        case PW_AUTHENTICATION_REQUEST:
 
807
        case PW_STATUS_SERVER:
 
808
                break;
 
809
                
 
810
                /*
 
811
                 *      Reply packets are signed with the
 
812
                 *      authentication vector of the request.
 
813
                 */
 
814
        default:
 
815
                {
 
816
                        uint8_t digest[16];
 
817
                        
 
818
                        MD5_CTX context;
 
819
                        MD5Init(&context);
 
820
                        MD5Update(&context, packet->data, packet->data_len);
 
821
                        MD5Update(&context, secret, strlen(secret));
 
822
                        MD5Final(digest, &context);
 
823
                        
 
824
                        memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
 
825
                        memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
 
826
                        break;
 
827
                }
 
828
        }/* switch over packet codes */
 
829
 
 
830
        return 0;
 
831
}
150
832
 
151
833
/*
152
834
 *      Reply to the request.  Also attach
156
838
             const char *secret)
157
839
{
158
840
        VALUE_PAIR              *reply;
 
841
        const char              *what;
 
842
        char                    ip_buffer[128];
159
843
        struct  sockaddr_in     saremote;
160
844
        struct  sockaddr_in     *sa;
161
 
        const char              *what;
162
 
        uint8_t                 ip_buffer[16];
163
845
 
164
846
        /*
165
847
         *      Maybe it's a fake packet.  Don't send it.
178
860
         *  First time through, allocate room for the packet
179
861
         */
180
862
        if (!packet->data) {
181
 
                  radius_packet_t       *hdr;
182
 
                  uint32_t              lvalue;
183
 
                  uint8_t               *ptr, *length_ptr, *vsa_length_ptr;
184
 
                  uint8_t               digest[16];
185
 
                  int                   secretlen;
186
 
                  int                   vendorcode, vendorpec;
187
 
                  u_short               total_length;
188
 
                  int                   len, allowed;
189
 
                  int                   msg_auth_offset = 0;
190
 
 
191
 
                  /*
192
 
                   *    For simplicity in the following logic, we allow
193
 
                   *    the attributes to "overflow" the 4k maximum
194
 
                   *    RADIUS packet size, by one attribute.
195
 
                   */
196
 
                  uint8_t               data[MAX_PACKET_LEN + 256];
197
 
 
198
 
                  /*
199
 
                   *    Use memory on the stack, until we know how
200
 
                   *    large the packet will be.
201
 
                   */
202
 
                  hdr = (radius_packet_t *) data;
203
 
 
204
 
                  /*
205
 
                   *    Build standard header
206
 
                   */
207
 
                  hdr->code = packet->code;
208
 
                  hdr->id = packet->id;
209
 
 
210
 
                  /*
211
 
                   *    Double-check some things based on packet code.
212
 
                   */
213
 
                  switch (packet->code) {
214
 
                  case PW_AUTHENTICATION_ACK:
215
 
                  case PW_AUTHENTICATION_REJECT:
216
 
                  case PW_ACCESS_CHALLENGE:
217
 
                          if (!original) {
218
 
                                  librad_log("ERROR: Cannot sign response packet without a request packet.");
219
 
                                  return -1;
220
 
                          }
221
 
                          break;
222
 
 
223
 
                          /*
224
 
                           *    These packet vectors start off as all zero.
225
 
                           */
226
 
                  case PW_ACCOUNTING_REQUEST:
227
 
                  case PW_DISCONNECT_REQUEST:
228
 
                          memset(packet->vector, 0, sizeof(packet->vector));
229
 
                          break;
230
 
 
231
 
                  default:
232
 
                          break;
233
 
 
234
 
                  }
235
 
                  memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
236
 
 
237
 
                  DEBUG("Sending %s of id %d to %s:%d\n",
238
 
                        what, packet->id,
239
 
                        ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
240
 
                        packet->dst_port);
241
 
 
242
 
                  total_length = AUTH_HDR_LEN;
243
 
 
244
 
                  /*
245
 
                   *    Load up the configuration values for the user
246
 
                   */
247
 
                  ptr = hdr->data;
248
 
                  vendorcode = 0;
249
 
                  vendorpec = 0;
250
 
                  vsa_length_ptr = NULL;
251
 
 
252
 
                  /*
253
 
                   *    Loop over the reply attributes for the packet.
254
 
                   */
255
 
                  for (reply = packet->vps; reply; reply = reply->next) {
256
 
                          /*
257
 
                           *    Ignore non-wire attributes
258
 
                           */
259
 
                          if ((VENDOR(reply->attribute) == 0) &&
260
 
                              ((reply->attribute & 0xFFFF) > 0xff)) {
261
 
                                  continue;
262
 
                          }
263
 
 
264
 
                          /*
265
 
                           *    Check that the packet is no more than
266
 
                           *    4k in size, AFTER over-flowing the 4k
267
 
                           *    boundary.  Note that the 'data'
268
 
                           *    buffer, above, is one attribute longer
269
 
                           *    than necessary, in order to permit
270
 
                           *    this overflow.
271
 
                           */
272
 
                          if (total_length > MAX_PACKET_LEN) {
273
 
                                  librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
274
 
                                  return -1;
275
 
                          }
276
 
 
277
 
                          /*
278
 
                           *    Set the Message-Authenticator to the
279
 
                           *    correct length and initial value.
280
 
                           */
281
 
                          if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
282
 
                                  reply->length = AUTH_VECTOR_LEN;
283
 
                                  memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
284
 
                                  msg_auth_offset = total_length;
285
 
                          }
286
 
 
287
 
                          /*
288
 
                           *    Print out ONLY the attributes which
289
 
                           *    we're sending over the wire, and print
290
 
                           *    them out BEFORE they're encrypted.
291
 
                           */
292
 
                          debug_pair(reply);
293
 
 
294
 
                          /*
295
 
                           *    We have a different vendor.  Re-set
296
 
                           *    the vendor codes.
297
 
                           */
298
 
                          if (vendorcode != VENDOR(reply->attribute)) {
299
 
                                  vendorcode = 0;
300
 
                                  vendorpec = 0;
301
 
                                  vsa_length_ptr = NULL;
302
 
                          }
303
 
 
304
 
                          /*
305
 
                           *    If the Vendor-Specific attribute is getting
306
 
                           *    full, then create a new VSA attribute
307
 
                           *
308
 
                           *    FIXME: Multiple VSA's per Vendor-Specific
309
 
                           *    SHOULD be configurable.  When that's done,
310
 
                           *    the (1), below, can be changed to point to
311
 
                           *    a configuration variable which is set TRUE
312
 
                           *    if the NAS cannot understand multiple VSA's
313
 
                           *    per Vendor-Specific
314
 
                           */
315
 
                          if ((1) || /* ALWAYS create a new Vendor-Specific */
316
 
                              (vsa_length_ptr &&
317
 
                               (reply->length + *vsa_length_ptr) >= MAX_STRING_LEN)) {
318
 
                                  vendorcode = 0;
319
 
                                  vendorpec = 0;
320
 
                                  vsa_length_ptr = NULL;
321
 
                          }
322
 
 
323
 
                          /*
324
 
                           *    Maybe we have the start of a set of
325
 
                           *    (possibly many) VSA attributes from
326
 
                           *    one vendor.  Set a global VSA wrapper
327
 
                           */
328
 
                          if ((vendorcode == 0) &&
329
 
                              ((vendorcode = VENDOR(reply->attribute)) != 0)) {
330
 
                                  vendorpec  = dict_vendorpec(vendorcode);
331
 
 
332
 
                                  /*
333
 
                                   *    This is a potentially bad error...
334
 
                                   *    we can't find the vendor ID!
335
 
                                   */
336
 
                                  if (vendorpec == 0) {
337
 
                                          /* FIXME: log an error */
338
 
                                          continue;
339
 
                                  }
340
 
 
341
 
                                  /*
342
 
                                   *    Build a VSA header.
343
 
                                   */
344
 
                                  *ptr++ = PW_VENDOR_SPECIFIC;
345
 
                                  vsa_length_ptr = ptr;
346
 
                                  *ptr++ = 6;
347
 
                                  lvalue = htonl(vendorpec);
348
 
                                  memcpy(ptr, &lvalue, 4);
349
 
                                  ptr += 4;
350
 
                                  total_length += 6;
351
 
                          }
352
 
 
353
 
                          if (vendorpec == VENDORPEC_USR) {
354
 
                                  lvalue = htonl(reply->attribute & 0xFFFF);
355
 
                                  memcpy(ptr, &lvalue, 4);
356
 
 
357
 
                                  length_ptr = vsa_length_ptr;
358
 
 
359
 
                                  total_length += 4;
360
 
                                  *length_ptr  += 4;
361
 
                                  ptr          += 4;
362
 
 
363
 
                                  /*
364
 
                                   *    Each USR-style attribute gets
365
 
                                   *    it's own VSA wrapper, so we
366
 
                                   *    re-set the vendor specific
367
 
                                   *    information.
368
 
                                   */
369
 
                                  vendorcode = 0;
370
 
                                  vendorpec = 0;
371
 
                                  vsa_length_ptr = NULL;
372
 
 
373
 
                          } else {
374
 
                                  /*
375
 
                                   *    All other attributes are as
376
 
                                   *    per the RFC spec.
377
 
                                   */
378
 
                                  *ptr++ = (reply->attribute & 0xFF);
379
 
                                  length_ptr = ptr;
380
 
                                  if (vsa_length_ptr) *vsa_length_ptr += 2;
381
 
                                  *ptr++ = 2;
382
 
                                  total_length += 2;
383
 
                          }
384
 
 
385
 
                          switch(reply->type) {
386
 
 
387
 
                                  /*
388
 
                                   *    Ascend binary attributes are
389
 
                                   *    stored internally in binary form.
390
 
                                   */
391
 
                          case PW_TYPE_IFID:
392
 
                          case PW_TYPE_IPV6ADDR:
393
 
                          case PW_TYPE_IPV6PREFIX:
394
 
                          case PW_TYPE_ABINARY:
395
 
                          case PW_TYPE_STRING:
396
 
                          case PW_TYPE_OCTETS:
397
 
                                  /*
398
 
                                   *  Encrypt the various password styles
399
 
                                   */
400
 
                                  switch (reply->flags.encrypt) {
401
 
                                  default:
402
 
                                          break;
403
 
 
404
 
                                  case FLAG_ENCRYPT_USER_PASSWORD:
405
 
                                    rad_pwencode((char *)reply->strvalue,
406
 
                                                 &(reply->length),
407
 
                                                 (const char *)secret,
408
 
                                                 (const char *)packet->vector);
409
 
                                    break;
410
 
 
411
 
                                  case FLAG_ENCRYPT_TUNNEL_PASSWORD:
412
 
                                          if (!original) {
413
 
                                                  librad_log("ERROR: No request packet, cannot encrypt Tunnel-Password attribute in the reply.");
414
 
                                                  return -1;
415
 
                                          }
416
 
                                          rad_tunnel_pwencode(reply->strvalue,
417
 
                                                              &(reply->length),
418
 
                                                              secret,
419
 
                                                              original->vector);
420
 
                                          break;
421
 
 
422
 
 
423
 
                                  case FLAG_ENCRYPT_ASCEND_SECRET:
424
 
                                          make_secret(digest, packet->vector,
425
 
                                                      secret, reply->strvalue);
426
 
                                          memcpy(reply->strvalue, digest, AUTH_VECTOR_LEN );
427
 
                                          reply->length = AUTH_VECTOR_LEN;
428
 
                                          break;
429
 
                                  } /* switch over encryption flags */
430
 
 
431
 
                                  len = reply->length;
432
 
 
433
 
                                  /*
434
 
                                   *    Set the TAG at the beginning
435
 
                                   *    of the string if tagged.  If
436
 
                                   *    tag value is not valid for
437
 
                                   *    tagged attribute, make it 0x00
438
 
                                   *    per RFC 2868.  -cparker
439
 
                                   */
440
 
                                  if (reply->flags.has_tag) {
441
 
                                          if (TAG_VALID(reply->flags.tag)) {
442
 
                                                  len++;
443
 
                                                  *ptr++ = reply->flags.tag;
444
 
 
445
 
                                          } else if (reply->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
446
 
                                                  /*
447
 
                                                   *  Tunnel passwords
448
 
                                                   *  REQUIRE a tag,
449
 
                                                   *  even if we don't
450
 
                                                   *  have a valid
451
 
                                                   *  tag.
452
 
                                                   */
453
 
                                                  len++;
454
 
                                                  *ptr++ = 0x00;
455
 
                                          } /* else don't write a tag */
456
 
                                  } /* else the attribute doesn't have a tag */
457
 
 
458
 
                                  /*
459
 
                                   *    Ensure we don't go too far.
460
 
                                   *    The 'length' of the attribute
461
 
                                   *    may be 0..255, minus whatever
462
 
                                   *    octets are used in the attribute
463
 
                                   *    header.
464
 
                                   */
465
 
                                  allowed = 255;
466
 
                                  if (vsa_length_ptr) {
467
 
                                          allowed -= *vsa_length_ptr;
468
 
                                  } else {
469
 
                                          allowed -= *length_ptr;
470
 
                                  }
471
 
 
472
 
                                  if (len > allowed) {
473
 
                                          len = allowed;
474
 
                                  }
475
 
 
476
 
                                  *length_ptr += len;
477
 
                                  if (vsa_length_ptr) *vsa_length_ptr += len;
478
 
                                  /*
479
 
                                   *  If we have tagged attributes we can't assume that
480
 
                                   *  len == reply->length.  Use reply->length for copying
481
 
                                   *  the string data into the packet.  Use len for the
482
 
                                   *  true length of the string+tags.
483
 
                                   */
484
 
                                  memcpy(ptr, reply->strvalue, reply->length);
485
 
                                  ptr += reply->length;
486
 
                                  total_length += len;
487
 
                                  break;
488
 
 
489
 
                          case PW_TYPE_INTEGER:
490
 
                          case PW_TYPE_IPADDR:
491
 
                                  *length_ptr += 4;
492
 
                                  if (vsa_length_ptr) *vsa_length_ptr += 4;
493
 
 
494
 
                                  if (reply->type == PW_TYPE_INTEGER ) {
495
 
                                          /*  If tagged, the tag becomes the MSB of the value */
496
 
                                          if(reply->flags.has_tag) {
497
 
                                                 /*  Tag must be ( 0x01 -> 0x1F ) OR 0x00  */
498
 
                                                 if(!TAG_VALID(reply->flags.tag)) {
499
 
                                                       reply->flags.tag = 0x00;
500
 
                                                 }
501
 
                                                 lvalue = htonl((reply->lvalue & 0xffffff) |
502
 
                                                                ((reply->flags.tag & 0xff) << 24));
503
 
                                          } else {
504
 
                                                 lvalue = htonl(reply->lvalue);
505
 
                                          }
506
 
                                  } else {
507
 
                                          /*
508
 
                                           *  IP address is already in
509
 
                                           *  network byte order.
510
 
                                           */
511
 
                                          lvalue = reply->lvalue;
512
 
                                  }
513
 
                                  memcpy(ptr, &lvalue, 4);
514
 
                                  ptr += 4;
515
 
                                  total_length += 4;
516
 
                                  break;
517
 
 
518
 
                                  /*
519
 
                                   *  There are no tagged date attributes.
520
 
                                   */
521
 
                          case PW_TYPE_DATE:
522
 
                                  *length_ptr += 4;
523
 
                                  if (vsa_length_ptr) *vsa_length_ptr += 4;
524
 
 
525
 
                                  lvalue = htonl(reply->lvalue);
526
 
                                  memcpy(ptr, &lvalue, 4);
527
 
                                  ptr += 4;
528
 
                                  total_length += 4;
529
 
                                  break;
530
 
                          default:
531
 
                                  break;
532
 
                          }
533
 
                  } /* done looping over all attributes */
534
 
 
535
 
                  /*
536
 
                   *    Fill in the rest of the fields, and copy
537
 
                   *    the data over from the local stack to
538
 
                   *    the newly allocated memory.
539
 
                   *
540
 
                   *    Yes, all this 'memcpy' is slow, but it means
541
 
                   *    that we only allocate the minimum amount of
542
 
                   *    memory for a request.
543
 
                   */
544
 
                  packet->data_len = total_length;
545
 
                  packet->data = (uint8_t *) malloc(packet->data_len);
546
 
                  if (!packet->data) {
547
 
                          librad_log("Out of memory");
548
 
                          return -1;
549
 
                  }
550
 
                  memcpy(packet->data, data, packet->data_len);
551
 
                  hdr = (radius_packet_t *) packet->data;
552
 
 
553
 
                  total_length = htons(total_length);
554
 
                  memcpy(hdr->length, &total_length, sizeof(u_short));
555
 
 
556
 
                  /*
557
 
                   *    If this is not an authentication request, we
558
 
                   *    need to calculate the md5 hash over the entire packet
559
 
                   *    and put it in the vector.
560
 
                   */
561
 
                  secretlen = strlen(secret);
562
 
 
563
 
                  /*
564
 
                   *    If there's a Message-Authenticator, update it
565
 
                   *    now, BEFORE updating the authentication vector.
566
 
                   */
567
 
                  if (msg_auth_offset) {
568
 
                          uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
569
 
 
570
 
                          switch (packet->code) {
571
 
                          default:
572
 
                                  break;
573
 
 
574
 
                          case PW_ACCOUNTING_REQUEST:
575
 
                          case PW_ACCOUNTING_RESPONSE:
576
 
                                  memset(hdr->vector, 0, AUTH_VECTOR_LEN);
577
 
                                  break;
578
 
 
579
 
                          case PW_AUTHENTICATION_ACK:
580
 
                          case PW_AUTHENTICATION_REJECT:
581
 
                          case PW_ACCESS_CHALLENGE:
582
 
                                  /* this was checked above */
583
 
                                  memcpy(hdr->vector, original->vector,
584
 
                                         AUTH_VECTOR_LEN);
585
 
                                  break;
586
 
                          }
587
 
 
588
 
                          /*
589
 
                           *    Set the authentication vector to zero,
590
 
                           *    calculate the signature, and put it
591
 
                           *    into the Message-Authenticator
592
 
                           *    attribute.
593
 
                           */
594
 
                          memset(packet->data + msg_auth_offset + 2,
595
 
                                 0, AUTH_VECTOR_LEN);
596
 
                          lrad_hmac_md5(packet->data, packet->data_len,
597
 
                                        secret, secretlen, calc_auth_vector);
598
 
                          memcpy(packet->data + msg_auth_offset + 2,
599
 
                                 calc_auth_vector, AUTH_VECTOR_LEN);
600
 
 
601
 
                          /*
602
 
                           *    Copy the original request vector back
603
 
                           *    to the raw packet.
604
 
                           */
605
 
                          memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
606
 
                  }
607
 
 
608
 
                  /*
609
 
                   *    Switch over the packet code, deciding how to
610
 
                   *    sign the packet.
611
 
                   */
612
 
                  switch (packet->code) {
613
 
                          /*
614
 
                           *    Request packets are not signed, bur
615
 
                           *    have a random authentication vector.
616
 
                           */
617
 
                  case PW_AUTHENTICATION_REQUEST:
618
 
                  case PW_STATUS_SERVER:
619
 
                          break;
620
 
 
621
 
                          /*
622
 
                           *    Reply packets are signed with the
623
 
                           *    authentication vector of the request.
624
 
                           */
625
 
                  default:
626
 
                        {
627
 
                                MD5_CTX context;
628
 
                                MD5Init(&context);
629
 
                                MD5Update(&context, packet->data, packet->data_len);
630
 
                                MD5Update(&context, secret, strlen(secret));
631
 
                                MD5Final(digest, &context);
632
 
 
633
 
                                memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
634
 
                                memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
635
 
                                break;
636
 
                        }
637
 
                  } /* switch over packet codes */
638
 
 
639
 
 
640
 
                  /*
641
 
                   *    If packet->data points to data, then we print out
642
 
                   *    the VP list again only for debugging.
643
 
                   */
 
863
                DEBUG("Sending %s of id %d to %s port %d\n",
 
864
                      what, packet->id,
 
865
                      ip_ntoa(ip_buffer, packet->dst_ipaddr),
 
866
                      packet->dst_port);
 
867
                
 
868
                /*
 
869
                 *      Encode the packet.
 
870
                 */
 
871
                if (rad_encode(packet, original, secret) < 0) {
 
872
                        return -1;
 
873
                }
 
874
                
 
875
                /*
 
876
                 *      Re-sign it, including updating the
 
877
                 *      Message-Authenticator.
 
878
                 */
 
879
                if (rad_sign(packet, original, secret) < 0) {
 
880
                        return -1;
 
881
                }
 
882
 
 
883
                /*
 
884
                 *      If packet->data points to data, then we print out
 
885
                 *      the VP list again only for debugging.
 
886
                 */
644
887
        } else if (librad_debug) {
645
 
                DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
646
 
                      ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
 
888
                DEBUG("Re-sending %s of id %d to %s port %d\n", what, packet->id,
 
889
                      ip_ntoa(ip_buffer, packet->dst_ipaddr),
647
890
                      packet->dst_port);
648
891
 
649
892
                for (reply = packet->vps; reply; reply = reply->next) {
1017
1260
                        }
1018
1261
                        seen_eap |= PW_MESSAGE_AUTHENTICATOR;
1019
1262
                        break;
1020
 
 
1021
 
                case PW_VENDOR_SPECIFIC:
1022
 
                        if (attr[1] <= 6) {
1023
 
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
1024
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr),
1025
 
                                           attr[1] - 2);
1026
 
                                free(packet);
1027
 
                                return NULL;
1028
 
                        }
1029
 
 
1030
 
                        /*
1031
 
                         *      Don't allow VSA's with vendor zero.
1032
 
                         */
1033
 
                        if ((attr[2] == 0) && (attr[3] == 0) &&
1034
 
                            (attr[4] == 0) && (attr[5] == 0)) {
1035
 
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has vendor ID of zero",
1036
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr));
1037
 
                                free(packet);
1038
 
                                return NULL;
1039
 
                        }
1040
 
 
1041
 
                        /*
1042
 
                         *      Don't look at the contents of VSA's,
1043
 
                         *      too many vendors have non-standard
1044
 
                         *      formats.
1045
 
                         */
1046
 
                        break;
1047
1263
                }
1048
1264
 
1049
1265
                /*
1135
1351
        return packet;
1136
1352
}
1137
1353
 
 
1354
 
1138
1355
/*
1139
 
 *      Calculate/check digest, and decode radius attributes.
 
1356
 *      Verify the signature of a packet.
1140
1357
 */
1141
 
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
1358
static int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1142
1359
               const char *secret)
1143
1360
{
1144
 
        uint32_t                lvalue;
1145
 
        uint32_t                vendorcode;
1146
 
        VALUE_PAIR              **tail;
1147
 
        VALUE_PAIR              *pair;
1148
1361
        uint8_t                 *ptr;
1149
1362
        int                     length;
1150
 
        int                     attribute;
1151
1363
        int                     attrlen;
1152
 
        int                     vendorlen;
1153
 
        radius_packet_t         *hdr;
1154
1364
 
1155
 
        hdr = (radius_packet_t *)packet->data;
 
1365
        if (!packet || !packet->data) return -1;
1156
1366
 
1157
1367
        /*
1158
1368
         *      Before we allocate memory for the attributes, do more
1159
1369
         *      sanity checking.
1160
1370
         */
1161
 
        ptr = hdr->data;
 
1371
        ptr = packet->data + AUTH_HDR_LEN;
1162
1372
        length = packet->data_len - AUTH_HDR_LEN;
1163
1373
        while (length > 0) {
1164
1374
                uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
1180
1390
 
1181
1391
                        switch (packet->code) {
1182
1392
                        default:
1183
 
                          break;
 
1393
                                break;
1184
1394
 
1185
1395
                        case PW_ACCOUNTING_REQUEST:
1186
1396
                        case PW_ACCOUNTING_RESPONSE:
1187
 
                          memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
1188
 
                          break;
 
1397
                        case PW_DISCONNECT_REQUEST:
 
1398
                        case PW_DISCONNECT_ACK:
 
1399
                        case PW_DISCONNECT_NAK:
 
1400
                        case PW_COF_REQUEST:
 
1401
                        case PW_COF_ACK:
 
1402
                        case PW_COF_NAK:
 
1403
                                memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
 
1404
                                break;
1189
1405
 
1190
1406
                        case PW_AUTHENTICATION_ACK:
1191
1407
                        case PW_AUTHENTICATION_REJECT:
1192
1408
                        case PW_ACCESS_CHALLENGE:
1193
 
                          if (!original) {
1194
 
                                  librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
1195
 
                                  return -1;
1196
 
                          }
1197
 
                          memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1198
 
                          break;
 
1409
                                if (!original) {
 
1410
                                        librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
 
1411
                                        return -1;
 
1412
                                }
 
1413
                                memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
 
1414
                                break;
1199
1415
                        }
1200
1416
 
1201
1417
                        lrad_hmac_md5(packet->data, packet->data_len,
1202
1418
                                      secret, strlen(secret), calc_auth_vector);
1203
1419
                        if (memcmp(calc_auth_vector, msg_auth_vector,
1204
 
                                    sizeof(calc_auth_vector)) != 0) {
 
1420
                                   sizeof(calc_auth_vector)) != 0) {
1205
1421
                                char buffer[32];
1206
1422
                                librad_log("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
1207
1423
                                           ip_ntoa(buffer, packet->src_ipaddr));
1208
 
                                return -1;
 
1424
                                /* Silently drop packet, according to RFC 3579 */
 
1425
                                return -2;
1209
1426
                        } /* else the message authenticator was good */
1210
1427
 
1211
1428
                        /*
1239
1456
                        if (calc_acctdigest(packet, secret) > 1) {
1240
1457
                                char buffer[32];
1241
1458
                                librad_log("Received Accounting-Request packet "
1242
 
                                    "from %s with invalid signature!  (Shared secret is incorrect.)",
1243
 
                                    ip_ntoa(buffer, packet->src_ipaddr));
 
1459
                                           "from %s with invalid signature!  (Shared secret is incorrect.)",
 
1460
                                           ip_ntoa(buffer, packet->src_ipaddr));
1244
1461
                                return -1;
1245
1462
                        }
1246
1463
                        break;
1253
1470
                        if (rcode > 1) {
1254
1471
                                char buffer[32];
1255
1472
                                librad_log("Received %s packet "
1256
 
                                           "from %s:%d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
 
1473
                                           "from client %s port %d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
1257
1474
                                           packet_codes[packet->code],
1258
1475
                                           ip_ntoa(buffer, packet->src_ipaddr),
1259
1476
                                           packet->src_port,
1263
1480
                  break;
1264
1481
        }
1265
1482
 
 
1483
        return 0;
 
1484
}
 
1485
 
 
1486
 
 
1487
/*
 
1488
 *      Parse a RADIUS attribute into a data structure.
 
1489
 */
 
1490
static VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
1491
                        const char *secret, int attribute, int length,
 
1492
                        const uint8_t *data)
 
1493
{
 
1494
        int offset = 0;
 
1495
        VALUE_PAIR *vp;
 
1496
 
 
1497
        if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
 
1498
                return NULL;
 
1499
        }
 
1500
        
 
1501
        /*
 
1502
         *      If length is greater than 253, something is SERIOUSLY
 
1503
         *      wrong.
 
1504
         */
 
1505
        if (length > 253) length = 253; /* paranoia (pair-anoia?) */
 
1506
 
 
1507
        vp->length = length;
 
1508
        vp->operator = T_OP_EQ;
 
1509
        vp->next = NULL;
 
1510
 
 
1511
        /*
 
1512
         *      Handle tags.
 
1513
         */
 
1514
        if (vp->flags.has_tag) {
 
1515
                if (TAG_VALID(data[0]) ||
 
1516
                    (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
 
1517
                        /*
 
1518
                         *      Tunnel passwords REQUIRE a tag, even
 
1519
                         *      if don't have a valid tag.
 
1520
                         */
 
1521
                        vp->flags.tag = data[0];
 
1522
 
 
1523
                        if ((vp->type == PW_TYPE_STRING) ||
 
1524
                            (vp->type == PW_TYPE_OCTETS)) offset = 1;
 
1525
                }
 
1526
        }
 
1527
 
 
1528
        /*
 
1529
         *      Copy the data to be decrypted
 
1530
         */
 
1531
        memcpy(&vp->strvalue[0], data + offset, length - offset);
 
1532
        vp->length -= offset;
 
1533
 
 
1534
        /*
 
1535
         *      Decrypt the attribute.
 
1536
         */
 
1537
        switch (vp->flags.encrypt) {
 
1538
                /*
 
1539
                 *  User-Password
 
1540
                 */
 
1541
        case FLAG_ENCRYPT_USER_PASSWORD:
 
1542
                if (original) {
 
1543
                        rad_pwdecode((char *)vp->strvalue,
 
1544
                                     vp->length, secret,
 
1545
                                     original->vector);
 
1546
                } else {
 
1547
                        rad_pwdecode((char *)vp->strvalue,
 
1548
                                     vp->length, secret,
 
1549
                                     packet->vector);
 
1550
                }
 
1551
                if (vp->attribute == PW_USER_PASSWORD) {
 
1552
                        vp->length = strlen(vp->strvalue);
 
1553
                }
 
1554
                break;
 
1555
                
 
1556
                /*
 
1557
                 *      Tunnel-Password's may go ONLY
 
1558
                 *      in response packets.
 
1559
                 */
 
1560
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
 
1561
                if (!original) goto raw;
 
1562
                
 
1563
                if (rad_tunnel_pwdecode(vp->strvalue, &vp->length,
 
1564
                                        secret, original->vector) < 0) {
 
1565
                        goto raw;
 
1566
                }
 
1567
                break;
 
1568
                
 
1569
                /*
 
1570
                 *  Ascend-Send-Secret
 
1571
                 *  Ascend-Receive-Secret
 
1572
                 */
 
1573
        case FLAG_ENCRYPT_ASCEND_SECRET:
 
1574
                if (!original) {
 
1575
                        goto raw;
 
1576
                } else {
 
1577
                        uint8_t my_digest[AUTH_VECTOR_LEN];
 
1578
                        make_secret(my_digest,
 
1579
                                    original->vector,
 
1580
                                    secret, data);
 
1581
                        memcpy(vp->strvalue, my_digest,
 
1582
                               AUTH_VECTOR_LEN );
 
1583
                        vp->strvalue[AUTH_VECTOR_LEN] = '\0';
 
1584
                        vp->length = strlen(vp->strvalue);
 
1585
                }
 
1586
                break;
 
1587
 
 
1588
        default:
 
1589
                break;
 
1590
        } /* switch over encryption flags */
 
1591
 
 
1592
 
 
1593
        switch (vp->type) {
 
1594
        case PW_TYPE_STRING:
 
1595
        case PW_TYPE_OCTETS:
 
1596
                /* nothing more to do */
 
1597
                break;
 
1598
 
 
1599
        case PW_TYPE_INTEGER:
 
1600
                if (vp->length != 4) goto raw;
 
1601
 
 
1602
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1603
                vp->lvalue = ntohl(vp->lvalue);
 
1604
 
 
1605
                if (vp->flags.has_tag) vp->lvalue &= 0x00ffffff;
 
1606
 
 
1607
                /*
 
1608
                 *      Try to get named VALUEs
 
1609
                 */
 
1610
                {
 
1611
                        DICT_VALUE *dval;
 
1612
                        dval = dict_valbyattr(vp->attribute,
 
1613
                                              vp->lvalue);
 
1614
                        if (dval) {
 
1615
                                strNcpy(vp->strvalue,
 
1616
                                        dval->name,
 
1617
                                        sizeof(vp->strvalue));
 
1618
                        }
 
1619
                }
 
1620
                break;
 
1621
 
 
1622
        case PW_TYPE_DATE:
 
1623
                if (vp->length != 4) goto raw;
 
1624
 
 
1625
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1626
                vp->lvalue = ntohl(vp->lvalue);
 
1627
                break;
 
1628
 
 
1629
                /*
 
1630
                 *      IPv4 address. Keep it in network byte order in
 
1631
                 *      vp->lvalue and put ASCII IP address in standard
 
1632
                 *      dot notation into vp->strvalue.
 
1633
                 */
 
1634
        case PW_TYPE_IPADDR:
 
1635
                if (vp->length != 4) goto raw;
 
1636
 
 
1637
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1638
                ip_ntoa(vp->strvalue, vp->lvalue);
 
1639
                break;
 
1640
 
 
1641
                /*
 
1642
                 *      IPv6 interface ID is 8 octets long.
 
1643
                 */
 
1644
        case PW_TYPE_IFID:
 
1645
                if (vp->length != 8) goto raw;
 
1646
                /* vp->vp_ifid == vp->strvalue */
 
1647
                break;
 
1648
                
 
1649
                /*
 
1650
                 *      IPv6 addresses are 16 octets long
 
1651
                 */
 
1652
        case PW_TYPE_IPV6ADDR:
 
1653
                if (vp->length != 16) goto raw;
 
1654
                /* vp->vp_ipv6addr == vp->strvalue */
 
1655
                break;
 
1656
                
 
1657
                /*
 
1658
                 *      IPv6 prefixes are 2 to 18 octets long.
 
1659
                 *
 
1660
                 *      RFC 3162: The first octet is unused.
 
1661
                 *      The second is the length of the prefix
 
1662
                 *      the rest are the prefix data.
 
1663
                 *
 
1664
                 *      The prefix length can have value 0 to 128.
 
1665
                 */
 
1666
        case PW_TYPE_IPV6PREFIX:
 
1667
                if (vp->length < 2 || vp->length > 18) goto raw;
 
1668
                if (vp->strvalue[1] > 128) goto raw;
 
1669
 
 
1670
                /*
 
1671
                 *      FIXME: double-check that
 
1672
                 *      (vp->strvalue[1] >> 3) matches vp->length + 2
 
1673
                 */
 
1674
                if (vp->length < 18) {
 
1675
                        memset(vp->strvalue + vp->length, 0,
 
1676
                               18 - vp->length);
 
1677
                }
 
1678
                break;
 
1679
 
 
1680
        default:
 
1681
        raw:
 
1682
                vp->type = PW_TYPE_OCTETS;
 
1683
                vp->length = length;
 
1684
                memcpy(vp->strvalue, data, length);
 
1685
                
 
1686
 
 
1687
                /*
 
1688
                 *      Ensure there's no encryption or tag stuff,
 
1689
                 *      we just pass the attribute as-is.
 
1690
                 */
 
1691
                memset(&vp->flags, 0, sizeof(vp->flags));
 
1692
        }
 
1693
 
 
1694
        return vp;
 
1695
}
 
1696
 
 
1697
 
 
1698
/*
 
1699
 *      Calculate/check digest, and decode radius attributes.
 
1700
 */
 
1701
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
1702
               const char *secret)
 
1703
{
 
1704
        uint32_t                lvalue;
 
1705
        uint32_t                vendorcode;
 
1706
        VALUE_PAIR              **tail;
 
1707
        VALUE_PAIR              *pair;
 
1708
        uint8_t                 *ptr;
 
1709
        int                     packet_length;
 
1710
        int                     attribute;
 
1711
        int                     attrlen;
 
1712
        int                     vendorlen;
 
1713
        radius_packet_t         *hdr;
 
1714
        int                     vsa_tlen, vsa_llen;
 
1715
        DICT_VENDOR             *dv = NULL;
 
1716
 
 
1717
        if (rad_verify(packet, original, secret) < 0) return -1;
 
1718
 
1266
1719
        /*
1267
1720
         *      Extract attribute-value pairs
1268
1721
         */
 
1722
        hdr = (radius_packet_t *)packet->data;
1269
1723
        ptr = hdr->data;
1270
 
        length = packet->data_len - AUTH_HDR_LEN;
 
1724
        packet_length = packet->data_len - AUTH_HDR_LEN;
1271
1725
 
1272
1726
        /*
1273
1727
         *      There may be VP's already in the packet.  Don't
1279
1733
 
1280
1734
        vendorcode = 0;
1281
1735
        vendorlen  = 0;
1282
 
 
1283
 
        while (length > 0) {
1284
 
                if (vendorlen > 0) {
1285
 
                        attribute = *ptr++ | (vendorcode << 16);
1286
 
                        attrlen   = *ptr++;
1287
 
                } else {
 
1736
        vsa_tlen = vsa_llen = 1;
 
1737
 
 
1738
        /*
 
1739
         *      We have to read at least two bytes.
 
1740
         *
 
1741
         *      rad_recv() above ensures that this is OK.
 
1742
         */
 
1743
        while (packet_length > 0) {
 
1744
                attribute = -1;
 
1745
                attrlen = -1;
 
1746
 
 
1747
                /*
 
1748
                 *      Normal attribute, handle it like normal.
 
1749
                 */
 
1750
                if (vendorcode == 0) {
 
1751
                        /*
 
1752
                         *      No room to read attr/length,
 
1753
                         *      or bad attribute, or attribute is
 
1754
                         *      too short, or attribute is too long,
 
1755
                         *      stop processing the packet.
 
1756
                         */
 
1757
                        if ((packet_length < 2) ||
 
1758
                            (ptr[0] == 0) ||  (ptr[1] < 2) ||
 
1759
                            (ptr[1] > packet_length)) break;
 
1760
 
1288
1761
                        attribute = *ptr++;
1289
1762
                        attrlen   = *ptr++;
 
1763
 
 
1764
                        attrlen -= 2;
 
1765
                        packet_length  -= 2;
 
1766
 
 
1767
                        if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
 
1768
                        
 
1769
                        /*
 
1770
                         *      No vendor code, or ONLY vendor code.
 
1771
                         */
 
1772
                        if (attrlen <= 4) goto create_pair;
 
1773
 
 
1774
                        vendorlen = 0;
1290
1775
                }
1291
 
 
1292
 
                attrlen -= 2;
1293
 
                length  -= 2;
1294
 
 
 
1776
                
1295
1777
                /*
1296
 
                 *      This could be a Vendor-Specific attribute.
 
1778
                 *      Handle Vendor-Specific
1297
1779
                 */
1298
 
                if ((vendorlen <= 0) &&
1299
 
                    (attribute == PW_VENDOR_SPECIFIC)) {
1300
 
                        int     sublen;
1301
 
                        uint8_t *subptr;
1302
 
 
 
1780
                if (vendorlen == 0) {
 
1781
                        uint8_t *subptr;
 
1782
                        int sublen;
 
1783
                        int myvendor;
 
1784
                        
1303
1785
                        /*
1304
 
                         *      attrlen was checked to be >= 6, in rad_recv
 
1786
                         *      attrlen was checked above.
1305
1787
                         */
1306
1788
                        memcpy(&lvalue, ptr, 4);
1307
 
                        vendorcode = ntohl(lvalue);
 
1789
                        myvendor = ntohl(lvalue);
1308
1790
 
1309
1791
                        /*
 
1792
                         *      Zero isn't allowed.
 
1793
                         */
 
1794
                        if (myvendor == 0) goto create_pair;
 
1795
                        
 
1796
                        /*
1310
1797
                         *      This is an implementation issue.
1311
1798
                         *      We currently pack vendor into the upper
1312
1799
                         *      16 bits of a 32-bit attribute number,
1313
1800
                         *      so we can't handle vendor numbers larger
1314
1801
                         *      than 16 bits.
1315
1802
                         */
1316
 
                        if (vendorcode > 65535) goto create_pair;
1317
 
 
1318
 
                        /*
1319
 
                         *      vendorcode was checked to be non-zero
1320
 
                         *      above, in rad_recv.
1321
 
                         */
1322
 
 
1323
 
                        /*
1324
 
                         *      First, check to see if the
1325
 
                         *      sub-attributes fill the VSA, as
1326
 
                         *      defined by the RFC.  If not, then it
1327
 
                         *      may be a USR-style VSA, or it may be a
1328
 
                         *      vendor who packs all of the
1329
 
                         *      information into one nonsense
1330
 
                         *      attribute
 
1803
                        if (myvendor > 65535) goto create_pair;
 
1804
                        
 
1805
                        vsa_tlen = vsa_llen = 1;
 
1806
                        dv = dict_vendorbyvalue(myvendor);
 
1807
                        if (dv) {
 
1808
                                vsa_tlen = dv->type;
 
1809
                                vsa_llen = dv->length;
 
1810
                        }
 
1811
                        
 
1812
                        /*
 
1813
                         *      Sweep through the list of VSA's,
 
1814
                         *      seeing if they exactly fill the
 
1815
                         *      outer Vendor-Specific attribute.
 
1816
                         *
 
1817
                         *      If not, create a raw Vendor-Specific.
1331
1818
                         */
1332
1819
                        subptr = ptr + 4;
1333
1820
                        sublen = attrlen - 4;
1334
1821
 
1335
 
                        while (sublen >= 2) {
1336
 
                                if (subptr[1] < 2) { /* too short */
1337
 
                                        break;
1338
 
                                }
1339
 
 
1340
 
                                if (subptr[1] > sublen) { /* too long */
1341
 
                                        break;
1342
 
                                }
1343
 
 
1344
 
                                sublen -= subptr[1]; /* just right */
1345
 
                                subptr += subptr[1];
1346
 
                        }
1347
 
 
1348
1822
                        /*
1349
 
                         *      If the attribute is RFC compatible,
1350
 
                         *      then allow it as an RFC style VSA.
 
1823
                         *      See if we can parse it.
1351
1824
                         */
1352
 
                        if (sublen == 0) {
1353
 
                                ptr += 4;
1354
 
                                vendorlen = attrlen - 4;
1355
 
                                attribute = *ptr++ | (vendorcode << 16);
1356
 
                                attrlen   = *ptr++;
1357
 
                                attrlen -= 2;
1358
 
                                length -= 6;
1359
 
 
1360
 
                                /*
1361
 
                                 *      USR-style attributes are 4 octets,
1362
 
                                 *      with the upper 2 octets being zero.
1363
 
                                 *
1364
 
                                 *      The upper octets may not be zero,
1365
 
                                 *      but that then means we won't be
1366
 
                                 *      able to pack the vendor & attribute
1367
 
                                 *      into a 32-bit number, so we can't
1368
 
                                 *      handle it.
1369
 
                                 *
1370
 
                                 *
1371
 
                                 *      FIXME: Update the dictionaries so
1372
 
                                 *      that we key off of per-attribute
1373
 
                                 *      flags "4-octet", instead of hard
1374
 
                                 *      coding USR here.  This will also
1375
 
                                 *      let us send packets with other
1376
 
                                 *      vendors having 4-octet attributes.
1377
 
                                 */
1378
 
                        } else if ((vendorcode == VENDORPEC_USR) &&
1379
 
                                   ((ptr[4] == 0) && (ptr[5] == 0)) &&
1380
 
                                   (attrlen >= 8)) {
1381
 
                                DICT_ATTR *da;
1382
 
 
1383
 
                                da = dict_attrbyvalue((vendorcode << 16) |
1384
 
                                                      (ptr[6] << 8) |
1385
 
                                                      ptr[7]);
1386
 
 
1387
 
                                /*
1388
 
                                 *      See if it's in the dictionary.
1389
 
                                 *      If so, it's a valid USR style
1390
 
                                 *      attribute.  If not, it's not...
1391
 
                                 *
1392
 
                                 *      Don't touch 'attribute' until
1393
 
                                 *      we know what to do!
1394
 
                                 */
1395
 
                                if (da != NULL) {
1396
 
                                        attribute = ((vendorcode << 16) |
1397
 
                                                     (ptr[6] << 8) |
1398
 
                                                     ptr[7]);
1399
 
                                        ptr += 8;
1400
 
                                        attrlen -= 8;
1401
 
                                        length -= 8;
1402
 
                                } /* else it's not in the dictionary */
1403
 
                        } /* else it was a stupid vendor format */
1404
 
                } /* else it wasn't a VSA */
 
1825
                        do {
 
1826
                                int myattr = 0;
 
1827
 
 
1828
                                /*
 
1829
                                 *      Don't have a type, it's bad.
 
1830
                                 */
 
1831
                                if (sublen < vsa_tlen) goto create_pair;
 
1832
                                
 
1833
                                /*
 
1834
                                 *      Ensure that the attribute number
 
1835
                                 *      is OK.
 
1836
                                 */
 
1837
                                switch (vsa_tlen) {
 
1838
                                case 1:
 
1839
                                        myattr = subptr[0];
 
1840
                                        break;
 
1841
                                        
 
1842
                                case 2:
 
1843
                                        myattr = (subptr[0] << 8) | subptr[1];
 
1844
                                        break;
 
1845
                                        
 
1846
                                case 4:
 
1847
                                        if ((subptr[0] != 0) ||
 
1848
                                            (subptr[1] != 0)) goto create_pair;
 
1849
                                        
 
1850
                                        myattr = (subptr[2] << 8) | subptr[3];
 
1851
                                        break;
 
1852
                                        
 
1853
                                        /*
 
1854
                                         *      Our dictionary is broken.
 
1855
                                         */
 
1856
                                default:
 
1857
                                        goto create_pair;
 
1858
                                }
 
1859
                                
 
1860
                                /*
 
1861
                                 *      Not enough room for one more
 
1862
                                 *      attribute.  Die!
 
1863
                                 */
 
1864
                                if (sublen < vsa_tlen + vsa_llen) goto create_pair;
 
1865
                                switch (vsa_llen) {
 
1866
                                case 0:
 
1867
                                        attribute = (myvendor << 16) | myattr;
 
1868
                                        ptr += 4 + vsa_tlen;
 
1869
                                        attrlen -= (4 + vsa_tlen);
 
1870
                                        packet_length -= 4 + vsa_tlen;
 
1871
                                        goto create_pair;
 
1872
 
 
1873
                                case 1:
 
1874
                                        if (subptr[vsa_tlen] < (vsa_tlen + vsa_llen))
 
1875
                                                goto create_pair;
 
1876
 
 
1877
                                        if (subptr[vsa_tlen] > sublen)
 
1878
                                                goto create_pair;
 
1879
                                        sublen -= subptr[vsa_tlen];
 
1880
                                        subptr += subptr[vsa_tlen];
 
1881
                                        break;
 
1882
 
 
1883
                                case 2:
 
1884
                                        if (subptr[vsa_tlen] != 0) goto create_pair;
 
1885
                                        if (subptr[vsa_tlen + 1] < (vsa_tlen + vsa_llen))
 
1886
                                                goto create_pair;
 
1887
                                        if (subptr[vsa_tlen + 1] > sublen)
 
1888
                                                goto create_pair;
 
1889
                                        sublen -= subptr[vsa_tlen + 1];
 
1890
                                        subptr += subptr[vsa_tlen + 1];
 
1891
                                        break;
 
1892
 
 
1893
                                        /*
 
1894
                                         *      Our dictionaries are
 
1895
                                         *      broken.
 
1896
                                         */
 
1897
                                default:
 
1898
                                        goto create_pair;
 
1899
                                }
 
1900
                        } while (sublen > 0);
 
1901
 
 
1902
                        vendorcode = myvendor;
 
1903
                        vendorlen = attrlen - 4;
 
1904
                        packet_length -= 4;
 
1905
 
 
1906
                        ptr += 4;
 
1907
                }
 
1908
 
 
1909
                /*
 
1910
                 *      attrlen is the length of this attribute.
 
1911
                 *      total_len is the length of the encompassing
 
1912
                 *      attribute.
 
1913
                 */
 
1914
                switch (vsa_tlen) {
 
1915
                case 1:
 
1916
                        attribute = ptr[0];
 
1917
                        break;
 
1918
                        
 
1919
                case 2:
 
1920
                        attribute = (ptr[0] << 8) | ptr[1];
 
1921
                        break;
 
1922
 
 
1923
                default:        /* can't hit this. */
 
1924
                        return -1;
 
1925
                }
 
1926
                attribute |= (vendorcode << 16);
 
1927
                ptr += vsa_tlen;
 
1928
 
 
1929
                switch (vsa_llen) {
 
1930
                case 1:
 
1931
                        attrlen = ptr[0] - (vsa_tlen + vsa_llen);
 
1932
                        break;
 
1933
                        
 
1934
                case 2:
 
1935
                        attrlen = ptr[1] - (vsa_tlen + vsa_llen);
 
1936
                        break;
 
1937
 
 
1938
                default:        /* can't hit this. */
 
1939
                        return -1;
 
1940
                }
 
1941
                ptr += vsa_llen;
 
1942
                vendorlen -= vsa_tlen + vsa_llen + attrlen;
 
1943
                if (vendorlen == 0) vendorcode = 0;
 
1944
                packet_length -= (vsa_tlen + vsa_llen);
1405
1945
 
1406
1946
                /*
1407
1947
                 *      Create the attribute, setting the default type
1410
1950
                 *      over-ride this one.
1411
1951
                 */
1412
1952
        create_pair:
1413
 
                if ((pair = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
 
1953
                pair = rad_attr2vp(packet, original, secret,
 
1954
                                 attribute, attrlen, ptr);
 
1955
                if (!pair) {
1414
1956
                        pairfree(&packet->vps);
1415
1957
                        librad_log("out of memory");
1416
1958
                        return -1;
1417
1959
                }
1418
1960
 
1419
 
                pair->length = attrlen;
1420
 
                pair->operator = T_OP_EQ;
1421
 
                pair->next = NULL;
1422
 
 
1423
 
                switch (pair->type) {
1424
 
 
1425
 
                        /*
1426
 
                         *      The attribute may be zero length,
1427
 
                         *      or it may have a tag, and then no data...
1428
 
                         */
1429
 
                case PW_TYPE_STRING:
1430
 
                        if (pair->flags.has_tag) {
1431
 
                                int offset = 0;
1432
 
 
1433
 
                                /*
1434
 
                                 *      If there's sufficient room for
1435
 
                                 *      a tag, and the tag looks valid,
1436
 
                                 *      then use it.
1437
 
                                 */
1438
 
                                if ((pair->length > 0) &&
1439
 
                                    TAG_VALID_ZERO(*ptr)) {
1440
 
                                        pair->flags.tag = *ptr;
1441
 
                                        pair->length--;
1442
 
                                        offset = 1;
1443
 
 
1444
 
                                        /*
1445
 
                                         *      If the leading tag
1446
 
                                         *      isn't valid, then it's
1447
 
                                         *      ignored for the tunnel
1448
 
                                         *      password attribute.
1449
 
                                         */
1450
 
                                } else if (pair->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
1451
 
                                        /*
1452
 
                                         * from RFC2868 - 3.5.  Tunnel-Password
1453
 
                                         * If the value of the Tag field is greater than
1454
 
                                         * 0x00 and less than or equal to 0x1F, it SHOULD
1455
 
                                         * be interpreted as indicating which tunnel
1456
 
                                         * (of several alternatives) this attribute pertains;
1457
 
                                         * otherwise, the Tag field SHOULD be ignored.
1458
 
                                         */
1459
 
                                        pair->flags.tag = 0x00;
1460
 
                                        if (pair->length > 0) pair->length--;
1461
 
                                        offset = 1;
1462
 
                                } else {
1463
 
                                       pair->flags.tag = 0x00;
1464
 
                                }
1465
 
 
1466
 
                                /*
1467
 
                                 *      pair->length MAY be zero here.
1468
 
                                 */
1469
 
                                memcpy(pair->strvalue, ptr + offset,
1470
 
                                       pair->length);
1471
 
                        } else {
1472
 
                          /*
1473
 
                           *    Ascend binary attributes never have a
1474
 
                           *    tag, and neither do the 'octets' type.
1475
 
                           */
1476
 
                        case PW_TYPE_ABINARY:
1477
 
                        case PW_TYPE_OCTETS:
1478
 
                                /* attrlen always < MAX_STRING_LEN */
1479
 
                                memcpy(pair->strvalue, ptr, attrlen);
1480
 
                                pair->flags.tag = 0;
1481
 
                        }
1482
 
 
1483
 
                        /*
1484
 
                         *      Decrypt passwords here.
1485
 
                         */
1486
 
                        switch (pair->flags.encrypt) {
1487
 
                        default:
1488
 
                                break;
1489
 
 
1490
 
                                /*
1491
 
                                 *  User-Password
1492
 
                                 */
1493
 
                        case FLAG_ENCRYPT_USER_PASSWORD:
1494
 
                                if (original) {
1495
 
                                        rad_pwdecode((char *)pair->strvalue,
1496
 
                                                     pair->length, secret,
1497
 
                                                     (char *)original->vector);
1498
 
                                } else {
1499
 
                                        rad_pwdecode((char *)pair->strvalue,
1500
 
                                                     pair->length, secret,
1501
 
                                                     (char *)packet->vector);
1502
 
                                }
1503
 
                                if (pair->attribute == PW_USER_PASSWORD) {
1504
 
                                        pair->length = strlen(pair->strvalue);
1505
 
                                }
1506
 
                                break;
1507
 
 
1508
 
                                /*
1509
 
                                 *      Tunnel-Password's may go ONLY
1510
 
                                 *      in response packets.
1511
 
                                 */
1512
 
                        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
1513
 
                                if (!original) {
1514
 
                                        librad_log("ERROR: Tunnel-Password attribute in request: Cannot decrypt it.");
1515
 
                                        free(pair);
1516
 
                                        return -1;
1517
 
                                }
1518
 
                                if (rad_tunnel_pwdecode(pair->strvalue,
1519
 
                                                        &pair->length,
1520
 
                                                        secret,
1521
 
                                                        (char *)original->vector) < 0) {
1522
 
                                        free(pair);
1523
 
                                        return -1;
1524
 
                                }
1525
 
                                break;
1526
 
 
1527
 
                                /*
1528
 
                                 *  Ascend-Send-Secret
1529
 
                                 *  Ascend-Receive-Secret
1530
 
                                 */
1531
 
                        case FLAG_ENCRYPT_ASCEND_SECRET:
1532
 
                                if (!original) {
1533
 
                                        librad_log("ERROR: Ascend-Send-Secret attribute in request: Cannot decrypt it.");
1534
 
                                        free(pair);
1535
 
                                        return -1;
1536
 
                                } else {
1537
 
                                        uint8_t my_digest[AUTH_VECTOR_LEN];
1538
 
                                        make_secret(my_digest,
1539
 
                                                    original->vector,
1540
 
                                                    secret, ptr);
1541
 
                                        memcpy(pair->strvalue, my_digest,
1542
 
                                               AUTH_VECTOR_LEN );
1543
 
                                        pair->strvalue[AUTH_VECTOR_LEN] = '\0';
1544
 
                                        pair->length = strlen(pair->strvalue);
1545
 
                                }
1546
 
                                break;
1547
 
                        } /* switch over encryption flags */
1548
 
                        break;  /* from octets/string/abinary */
1549
 
 
1550
 
                case PW_TYPE_INTEGER:
1551
 
                case PW_TYPE_DATE:
1552
 
                case PW_TYPE_IPADDR:
1553
 
                        /*
1554
 
                         *      Check for RFC compliance.  If the
1555
 
                         *      attribute isn't compliant, turn it
1556
 
                         *      into a string of raw octets.
1557
 
                         *
1558
 
                         *      Also set the lvalue to something
1559
 
                         *      which should never match anything.
1560
 
                         */
1561
 
                        if (attrlen != 4) {
1562
 
                                pair->type = PW_TYPE_OCTETS;
1563
 
                                memcpy(pair->strvalue, ptr, attrlen);
1564
 
                                pair->lvalue = 0xbad1bad1;
1565
 
                                break;
1566
 
                        }
1567
 
 
1568
 
                        memcpy(&lvalue, ptr, 4);
1569
 
 
1570
 
                        if (pair->type != PW_TYPE_IPADDR) {
1571
 
                                pair->lvalue = ntohl(lvalue);
1572
 
                        } else {
1573
 
                                 /*
1574
 
                                  *  It's an IP address, keep it in network
1575
 
                                  *  byte order, and put the ASCII IP
1576
 
                                  *  address or host name into the string
1577
 
                                  *  value.
1578
 
                                  */
1579
 
                                pair->lvalue = lvalue;
1580
 
                                ip_ntoa(pair->strvalue, pair->lvalue);
1581
 
                        }
1582
 
 
1583
 
                        /*
1584
 
                         *      Tagged attributes of type integer have
1585
 
                         *      special treatment.
1586
 
                         */
1587
 
                        if (pair->flags.has_tag &&
1588
 
                            pair->type == PW_TYPE_INTEGER) {
1589
 
                                pair->flags.tag = (pair->lvalue >> 24) & 0xff;
1590
 
                                pair->lvalue &= 0x00ffffff;
1591
 
                        }
1592
 
 
1593
 
                        /*
1594
 
                         *      Try to get the name for integer
1595
 
                         *      attributes.
1596
 
                         */
1597
 
                        if (pair->type == PW_TYPE_INTEGER) {
1598
 
                                DICT_VALUE *dval;
1599
 
                                dval = dict_valbyattr(pair->attribute,
1600
 
                                                      pair->lvalue);
1601
 
                                if (dval) {
1602
 
                                        strNcpy(pair->strvalue,
1603
 
                                                dval->name,
1604
 
                                                sizeof(pair->strvalue));
1605
 
                                }
1606
 
                        }
1607
 
                        break;
1608
 
 
1609
 
                        /*
1610
 
                         *      IPv6 interface ID is 8 octets long.
1611
 
                         */
1612
 
                case PW_TYPE_IFID:
1613
 
                        if (attrlen != 8)
1614
 
                                pair->type = PW_TYPE_OCTETS;
1615
 
                        memcpy(pair->strvalue, ptr, attrlen);
1616
 
                        break;
1617
 
 
1618
 
                        /*
1619
 
                         *      IPv6 addresses are 16 octets long
1620
 
                         */
1621
 
                case PW_TYPE_IPV6ADDR:
1622
 
                        if (attrlen != 16)
1623
 
                                pair->type = PW_TYPE_OCTETS;
1624
 
                        memcpy(pair->strvalue, ptr, attrlen);
1625
 
                        break;
1626
 
 
1627
 
                        /*
1628
 
                         *      IPv6 prefixes are 2 to 18 octets long.
1629
 
                         *
1630
 
                         *      RFC 3162: The first octet is unused.
1631
 
                         *      The second is the length of the prefix
1632
 
                         *      the rest are the prefix data.
1633
 
                         *
1634
 
                         *      The prefix length can have value 0 to 128.
1635
 
                         */
1636
 
                case PW_TYPE_IPV6PREFIX:
1637
 
                        if (attrlen < 2 || attrlen > 18)
1638
 
                                pair->type = PW_TYPE_OCTETS;
1639
 
                        if (attrlen >= 2) {
1640
 
                                if (ptr[1] > 128) {
1641
 
                                        pair->type = PW_TYPE_OCTETS;
1642
 
                                }
1643
 
                                /*
1644
 
                                 *      FIXME: double-check that
1645
 
                                 *      (ptr[1] >> 3) matches attrlen + 2
1646
 
                                 */
1647
 
                        }
1648
 
                        memcpy(pair->strvalue, ptr, attrlen);
1649
 
                        break;
1650
 
 
1651
 
                default:
1652
 
                        DEBUG("    %s (Unknown Type %d)\n",
1653
 
                              pair->name, pair->type);
1654
 
                        free(pair);
1655
 
                        pair = NULL;
1656
 
                        break;
1657
 
                }
1658
 
 
1659
 
                if (pair) {
1660
 
                        debug_pair(pair);
1661
 
                        *tail = pair;
1662
 
                        tail = &pair->next;
1663
 
                }
 
1961
                debug_pair(pair);
 
1962
                *tail = pair;
 
1963
                tail = &pair->next;
1664
1964
 
1665
1965
                ptr += attrlen;
1666
 
                length -= attrlen;
1667
 
                if (vendorlen > 0) vendorlen -= (attrlen + 2);
 
1966
                packet_length -= attrlen;
1668
1967
        }
1669
1968
 
1670
1969
        /*
1671
1970
         *      Merge information from the outside world into our
1672
 
         *      random pool
 
1971
         *      random pool.
1673
1972
         */
1674
 
        for (length = 0; length < AUTH_VECTOR_LEN; length++) {
1675
 
                lrad_rand_pool.randmem[length] += packet->vector[length];
1676
 
        }
1677
 
        lrad_rand_pool.randmem[lrad_rand_pool.randmem[0] & 0xff] += packet->id;
1678
 
        lrad_rand_pool.randmem[lrad_rand_pool.randmem[1] & 0xff] += packet->data_len;
1679
 
 
 
1973
        lrad_rand_seed(packet->data, AUTH_HDR_LEN);
 
1974
          
1680
1975
        return 0;
1681
1976
}
1682
1977
 
1692
1987
 *      int *pwlen is updated to the new length of the encrypted
1693
1988
 *      password - a multiple of 16 bytes.
1694
1989
 */
1695
 
#define AUTH_PASS_LEN (16)
1696
1990
int rad_pwencode(char *passwd, int *pwlen, const char *secret,
1697
1991
                 const char *vector)
1698
1992
{
1799
2093
        return pwlen;
1800
2094
}
1801
2095
 
1802
 
static unsigned int salt_offset = 0;
1803
2096
 
1804
2097
/*
1805
2098
 *      Encode Tunnel-Password attributes when sending them out on the wire.
2051
2344
        return 0;
2052
2345
}
2053
2346
 
 
2347
 
2054
2348
/*
2055
 
 *      Create a random vector of AUTH_VECTOR_LEN bytes.
 
2349
 *      Seed the random number generator.
 
2350
 *
 
2351
 *      May be called any number of times.
2056
2352
 */
2057
 
static void random_vector(uint8_t *vector)
 
2353
void lrad_rand_seed(const void *data, size_t size)
2058
2354
{
2059
 
        int i;
 
2355
        uint32_t hash;
2060
2356
 
2061
 
        if (!lrad_pool_initialized) {
 
2357
        /*
 
2358
         *      Ensure that the pool is initialized.
 
2359
         */
 
2360
        if (lrad_rand_index < 0) {
 
2361
                int fd;
 
2362
                
2062
2363
                memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
2063
2364
 
2064
 
                /*
2065
 
                 *      Initialize the state to something, using
2066
 
                 *      numbers which aren't random, but which also
2067
 
                 *      aren't static.
2068
 
                 */
2069
 
                lrad_rand_pool.randrsl[0] = (uint32_t) &lrad_pool_initialized;
2070
 
                lrad_rand_pool.randrsl[1] = (uint32_t) &i;
2071
 
                lrad_rand_pool.randrsl[2] = (uint32_t) vector;
 
2365
                fd = open("/dev/urandom", O_RDONLY);
 
2366
                if (fd >= 0) {
 
2367
                        size_t total;
 
2368
                        ssize_t this;
 
2369
 
 
2370
                        total = this = 0;
 
2371
                        while (total < sizeof(lrad_rand_pool.randrsl)) {
 
2372
                                this = read(fd, lrad_rand_pool.randrsl,
 
2373
                                            sizeof(lrad_rand_pool.randrsl) - total);
 
2374
                                if ((this < 0) && (errno != EINTR)) break;
 
2375
                                if (this > 0) total += this;
 
2376
                        }
 
2377
                        close(fd);
 
2378
                } else {
 
2379
                        lrad_rand_pool.randrsl[0] = fd;
 
2380
                        lrad_rand_pool.randrsl[1] = time(NULL);
 
2381
                        lrad_rand_pool.randrsl[2] = errno;
 
2382
                }
2072
2383
 
2073
2384
                lrad_randinit(&lrad_rand_pool, 1);
2074
 
                lrad_pool_initialized = 1;
 
2385
                lrad_rand_index = 0;
2075
2386
        }
2076
2387
 
2077
 
        lrad_isaac(&lrad_rand_pool);
2078
 
 
2079
 
        /*
2080
 
         *      Copy the random data over.
2081
 
         */
2082
 
        for (i = 0; i < AUTH_VECTOR_LEN; i++) {
2083
 
                *(vector++) = lrad_rand_pool.randrsl[i] & 0xff;
 
2388
        if (!data) return;
 
2389
 
 
2390
        /*
 
2391
         *      Hash the user data
 
2392
         */
 
2393
        hash = lrad_hash(data, size);
 
2394
        
 
2395
        lrad_rand_pool.randrsl[lrad_rand_index & 0xff] ^= hash;
 
2396
        lrad_rand_index++;
 
2397
        lrad_rand_index &= 0xff;
 
2398
 
 
2399
        /*
 
2400
         *      Churn the pool every so often after seeding it.
 
2401
         */
 
2402
        if (((int) (hash & 0xff)) == lrad_rand_index) {
 
2403
                lrad_isaac(&lrad_rand_pool);
2084
2404
        }
2085
2405
}
2086
2406
 
 
2407
 
2087
2408
/*
2088
2409
 *      Return a 32-bit random number.
2089
2410
 */
2090
2411
uint32_t lrad_rand(void)
2091
2412
{
2092
 
        uint32_t answer;
2093
 
        static int rand_index = 0;
 
2413
        uint32_t num;
2094
2414
 
2095
2415
        /*
2096
2416
         *      Ensure that the pool is initialized.
2097
2417
         */
2098
 
        if (!lrad_pool_initialized) {
2099
 
                uint8_t vector[AUTH_VECTOR_LEN];
2100
 
 
2101
 
                random_vector(vector);
 
2418
        if (lrad_rand_index < 0) {
 
2419
                lrad_rand_seed(NULL, 0);
2102
2420
        }
2103
2421
 
2104
2422
        /*
2105
 
         *      Grab an entry from the pool.
2106
 
         */
2107
 
        answer = lrad_rand_pool.randrsl[rand_index];
2108
 
 
2109
 
        /*
2110
 
         *      Go to the next entry (wrapping around to zero).
2111
 
         */
2112
 
        rand_index++;
2113
 
        rand_index &= 0xff;
2114
 
 
2115
 
        /*
2116
 
         *      Every 256 numbers, churn the pool again.
2117
 
         */
2118
 
        if (rand_index == 0) {
 
2423
         *      We don't return data directly from the pool.
 
2424
         *      Rather, we return a summary of the data.
 
2425
         */
 
2426
        num = lrad_rand_pool.randrsl[lrad_rand_index & 0xff];
 
2427
        lrad_rand_index++;
 
2428
        lrad_rand_index &= 0xff;
 
2429
 
 
2430
        /*
 
2431
         *      Every so often, churn the pool.
 
2432
         */
 
2433
        if (((int) (num & 0xff)) == lrad_rand_index) {
2119
2434
                lrad_isaac(&lrad_rand_pool);
2120
2435
        }
2121
2436
 
2122
 
        return answer;
 
2437
        return num;
2123
2438
}
2124
2439
 
2125
2440
/*
2134
2449
                return NULL;
2135
2450
        }
2136
2451
        memset(rp, 0, sizeof(RADIUS_PACKET));
2137
 
        if (newvector)
2138
 
                random_vector(rp->vector);
 
2452
        if (newvector) {
 
2453
                int i;
 
2454
                uint32_t hash, base;
 
2455
 
 
2456
                /*
 
2457
                 *      Don't expose the actual contents of the random
 
2458
                 *      pool.
 
2459
                 */
 
2460
                base = lrad_rand();
 
2461
                for (i = 0; i < AUTH_VECTOR_LEN; i += sizeof(uint32_t)) {
 
2462
                        hash = lrad_rand() ^ base;
 
2463
                        memcpy(rp->vector + i, &hash, sizeof(hash));
 
2464
                }
 
2465
        }
2139
2466
        lrad_rand();
2140
2467
 
2141
2468
        return rp;
2158
2485
 
2159
2486
        *radius_packet_ptr = NULL;
2160
2487
}
2161
 
 
2162
 
/*************************************************************************
2163
 
 *
2164
 
 *      Function: make_secret
2165
 
 *
2166
 
 *      Purpose: Build an encrypted secret value to return in a reply
2167
 
 *               packet.  The secret is hidden by xoring with a MD5 digest
2168
 
 *               created from the shared secret and the authentication
2169
 
 *               vector.  We put them into MD5 in the reverse order from
2170
 
 *               that used when encrypting passwords to RADIUS.
2171
 
 *
2172
 
 *************************************************************************/
2173
 
static void make_secret(unsigned char *digest, uint8_t *vector,
2174
 
                        const char *secret, char *value)
2175
 
{
2176
 
        u_char  buffer[256 + AUTH_VECTOR_LEN];
2177
 
        int             secretLen = strlen(secret);
2178
 
        int             i;
2179
 
 
2180
 
        memcpy(buffer, vector, AUTH_VECTOR_LEN );
2181
 
        memcpy(buffer + AUTH_VECTOR_LEN, secret, secretLen );
2182
 
 
2183
 
        librad_md5_calc(digest, buffer, AUTH_VECTOR_LEN + secretLen );
2184
 
        memset(buffer, 0, sizeof(buffer));
2185
 
 
2186
 
        for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
2187
 
                digest[i] ^= value[i];
2188
 
        }
2189
 
}