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

« back to all changes in this revision

Viewing changes to src/lib/radius.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * radius.c     Functions to send/receive radius packets.
3
3
 *
4
 
 * Version:     $Id: radius.c,v 1.125.2.1 2004/08/30 17:48:31 aland Exp $
 
4
 * Version:     $Id: radius.c,v 1.125.2.5.2.8 2006/08/16 20:03:35 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
15
15
 *
16
16
 *   You should have received a copy of the GNU Lesser General Public
17
17
 *   License along with this library; if not, write to the Free Software
18
 
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
 
18
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
19
 *
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.1 2004/08/30 17:48:31 aland Exp $";
 
23
static const char rcsid[] = "$Id: radius.c,v 1.125.2.5.2.8 2006/08/16 20:03:35 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
  "",
131
132
  "Disconnect-Request",
132
133
  "Disconnect-ACK",
133
134
  "Disconnect-NAK",
134
 
  "CoF-Request",
135
 
  "CoF-ACK",
136
 
  "CoF-NAK",
 
135
  "CoA-Request",
 
136
  "CoA-ACK",
 
137
  "CoA-NAK",
137
138
  "46",
138
139
  "47",
139
140
  "48",
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
        case PW_COA_REQUEST:
 
610
                memset(packet->vector, 0, sizeof(packet->vector));
 
611
                break;
 
612
                
 
613
        default:
 
614
                break;
 
615
        }
 
616
                
 
617
        /*
 
618
         *      Use memory on the stack, until we know how
 
619
         *      large the packet will be.
 
620
         */
 
621
        hdr = (radius_packet_t *) data;
 
622
        
 
623
        /*
 
624
         *      Build standard header
 
625
         */
 
626
        hdr->code = packet->code;
 
627
        hdr->id = packet->id;
 
628
        
 
629
        memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
 
630
 
 
631
        total_length = AUTH_HDR_LEN;
 
632
        packet->verified = 0;
 
633
        
 
634
        /*
 
635
         *      Load up the configuration values for the user
 
636
         */
 
637
        ptr = hdr->data;
 
638
 
 
639
        /*
 
640
         *      FIXME: Loop twice over the reply list.  The first time,
 
641
         *      calculate the total length of data.  The second time,
 
642
         *      allocate the memory, and fill in the VP's.
 
643
         *
 
644
         *      Hmm... this may be slower than just doing a small
 
645
         *      memcpy.
 
646
         */
 
647
        
 
648
        /*
 
649
         *      Loop over the reply attributes for the packet.
 
650
         */
 
651
        for (reply = packet->vps; reply; reply = reply->next) {
 
652
                /*
 
653
                 *      Ignore non-wire attributes
 
654
                 */
 
655
                if ((VENDOR(reply->attribute) == 0) &&
 
656
                    ((reply->attribute & 0xFFFF) > 0xff)) {
 
657
                        continue;
 
658
                }
 
659
                
 
660
                /*
 
661
                 *      Check that the packet is no more than 4k in
 
662
                 *      size, AFTER over-flowing the 4k boundary.
 
663
                 *      Note that the 'data' buffer, above, is one
 
664
                 *      attribute longer than necessary, in order to
 
665
                 *      permit this overflow.
 
666
                 */
 
667
                if (total_length > MAX_PACKET_LEN) {
 
668
                        librad_log("ERROR: Too many attributes for packet, result is larger than RFC maximum of 4k");
 
669
                        return -1;
 
670
                }
 
671
                
 
672
                /*
 
673
                 *      Set the Message-Authenticator to the correct
 
674
                 *      length and initial value.
 
675
                 */
 
676
                if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
 
677
                        reply->length = AUTH_VECTOR_LEN;
 
678
                        memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
 
679
                        packet->verified = total_length; /* HACK! */
 
680
                }
 
681
                
 
682
                /*
 
683
                 *      Print out ONLY the attributes which
 
684
                 *      we're sending over the wire, and print
 
685
                 *      them out BEFORE they're encrypted.
 
686
                 */
 
687
                debug_pair(reply);
 
688
 
 
689
                len = rad_vp2attr(packet, original, secret, reply, ptr);
 
690
                if (len < 0) return -1;
 
691
                ptr += len;
 
692
                total_length += len;
 
693
        } /* done looping over all attributes */
 
694
        
 
695
        /*
 
696
         *      Fill in the rest of the fields, and copy the data over
 
697
         *      from the local stack to the newly allocated memory.
 
698
         *
 
699
         *      Yes, all this 'memcpy' is slow, but it means
 
700
         *      that we only allocate the minimum amount of
 
701
         *      memory for a request.
 
702
         */
 
703
        packet->data_len = total_length;
 
704
        packet->data = (uint8_t *) malloc(packet->data_len);
 
705
        if (!packet->data) {
 
706
                librad_log("Out of memory");
 
707
                return -1;
 
708
        }
 
709
 
 
710
        memcpy(packet->data, data, packet->data_len);
 
711
        hdr = (radius_packet_t *) packet->data;
 
712
        
 
713
        total_length = htons(total_length);
 
714
        memcpy(hdr->length, &total_length, sizeof(total_length));
 
715
 
 
716
        return 0;
 
717
}
 
718
 
 
719
 
 
720
/*
 
721
 *      Sign a previously encoded packet.
 
722
 */
 
723
int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
724
             const char *secret)
 
725
{
 
726
        radius_packet_t *hdr = (radius_packet_t *)packet->data;
 
727
 
 
728
        /*
 
729
         *      It wasn't assigned an Id, this is bad!
 
730
         */
 
731
        if (packet->id < 0) {
 
732
                librad_log("ERROR: RADIUS packets must be assigned an Id.");
 
733
                return -1;
 
734
        }
 
735
 
 
736
        if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
 
737
            (packet->verified < 0)) {
 
738
                librad_log("ERROR: You must call rad_encode() before rad_sign()");
 
739
                return -1;
 
740
        }
 
741
 
 
742
        /*
 
743
         *      If there's a Message-Authenticator, update it
 
744
         *      now, BEFORE updating the authentication vector.
 
745
         *
 
746
         *      This is a hack...
 
747
         */
 
748
        if (packet->verified > 0) {
 
749
                uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
 
750
                
 
751
                switch (packet->code) {
 
752
                case PW_ACCOUNTING_REQUEST:
 
753
                case PW_ACCOUNTING_RESPONSE:
 
754
                case PW_DISCONNECT_REQUEST:
 
755
                case PW_DISCONNECT_ACK:
 
756
                case PW_DISCONNECT_NAK:
 
757
                case PW_COA_REQUEST:
 
758
                case PW_COA_ACK:
 
759
                case PW_COA_NAK:
 
760
                        memset(hdr->vector, 0, AUTH_VECTOR_LEN);
 
761
                        break;
 
762
 
 
763
                case PW_AUTHENTICATION_ACK:
 
764
                case PW_AUTHENTICATION_REJECT:
 
765
                case PW_ACCESS_CHALLENGE:
 
766
                        if (!original) {
 
767
                                librad_log("ERROR: Cannot sign response packet without a request packet.");
 
768
                                return -1;
 
769
                        }
 
770
                        memcpy(hdr->vector, original->vector,
 
771
                               AUTH_VECTOR_LEN);
 
772
                        break;
 
773
 
 
774
                default:        /* others have vector already set to zero */
 
775
                        break;
 
776
                        
 
777
                }
 
778
                
 
779
                /*
 
780
                 *      Set the authentication vector to zero,
 
781
                 *      calculate the signature, and put it
 
782
                 *      into the Message-Authenticator
 
783
                 *      attribute.
 
784
                 */
 
785
                lrad_hmac_md5(packet->data, packet->data_len,
 
786
                              secret, strlen(secret),
 
787
                              calc_auth_vector);
 
788
                memcpy(packet->data + packet->verified + 2,
 
789
                       calc_auth_vector, AUTH_VECTOR_LEN);
 
790
                
 
791
                /*
 
792
                 *      Copy the original request vector back
 
793
                 *      to the raw packet.
 
794
                 */
 
795
                memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
 
796
        }
 
797
        
 
798
        /*
 
799
         *      Switch over the packet code, deciding how to
 
800
         *      sign the packet.
 
801
         */
 
802
        switch (packet->code) {
 
803
                /*
 
804
                 *      Request packets are not signed, bur
 
805
                 *      have a random authentication vector.
 
806
                 */
 
807
        case PW_AUTHENTICATION_REQUEST:
 
808
        case PW_STATUS_SERVER:
 
809
                break;
 
810
                
 
811
                /*
 
812
                 *      Reply packets are signed with the
 
813
                 *      authentication vector of the request.
 
814
                 */
 
815
        default:
 
816
                {
 
817
                        uint8_t digest[16];
 
818
                        
 
819
                        MD5_CTX context;
 
820
                        MD5Init(&context);
 
821
                        MD5Update(&context, packet->data, packet->data_len);
 
822
                        MD5Update(&context, secret, strlen(secret));
 
823
                        MD5Final(digest, &context);
 
824
                        
 
825
                        memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
 
826
                        memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
 
827
                        break;
 
828
                }
 
829
        }/* switch over packet codes */
 
830
 
 
831
        return 0;
 
832
}
150
833
 
151
834
/*
152
835
 *      Reply to the request.  Also attach
156
839
             const char *secret)
157
840
{
158
841
        VALUE_PAIR              *reply;
 
842
        const char              *what;
 
843
        char                    ip_buffer[128];
159
844
        struct  sockaddr_in     saremote;
160
845
        struct  sockaddr_in     *sa;
161
 
        const char              *what;
162
 
        uint8_t                 ip_buffer[16];
163
846
 
164
847
        /*
165
848
         *      Maybe it's a fake packet.  Don't send it.
178
861
         *  First time through, allocate room for the packet
179
862
         */
180
863
        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_AUTHENTICATION_ACK:
575
 
                          case PW_AUTHENTICATION_REJECT:
576
 
                          case PW_ACCESS_CHALLENGE:
577
 
                                  /* this was checked above */
578
 
                                  memcpy(hdr->vector, original->vector,
579
 
                                         AUTH_VECTOR_LEN);
580
 
                                  break;
581
 
                          }
582
 
 
583
 
                          /*
584
 
                           *    Set the authentication vector to zero,
585
 
                           *    calculate the signature, and put it
586
 
                           *    into the Message-Authenticator
587
 
                           *    attribute.
588
 
                           */
589
 
                          memset(packet->data + msg_auth_offset + 2,
590
 
                                 0, AUTH_VECTOR_LEN);
591
 
                          lrad_hmac_md5(packet->data, packet->data_len,
592
 
                                        secret, secretlen, calc_auth_vector);
593
 
                          memcpy(packet->data + msg_auth_offset + 2,
594
 
                                 calc_auth_vector, AUTH_VECTOR_LEN);
595
 
 
596
 
                          /*
597
 
                           *    Copy the original request vector back
598
 
                           *    to the raw packet.
599
 
                           */
600
 
                          memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
601
 
                  }
602
 
 
603
 
                  /*
604
 
                   *    Switch over the packet code, deciding how to
605
 
                   *    sign the packet.
606
 
                   */
607
 
                  switch (packet->code) {
608
 
                          /*
609
 
                           *    Request packets are not signed, bur
610
 
                           *    have a random authentication vector.
611
 
                           */
612
 
                  case PW_AUTHENTICATION_REQUEST:
613
 
                  case PW_STATUS_SERVER:
614
 
                          break;
615
 
 
616
 
                          /*
617
 
                           *    Reply packets are signed with the
618
 
                           *    authentication vector of the request.
619
 
                           */
620
 
                  default:
621
 
                        {
622
 
                                MD5_CTX context;
623
 
                                MD5Init(&context);
624
 
                                MD5Update(&context, packet->data, packet->data_len);
625
 
                                MD5Update(&context, secret, strlen(secret));
626
 
                                MD5Final(digest, &context);
627
 
 
628
 
                                memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
629
 
                                memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
630
 
                                break;
631
 
                        }
632
 
                  } /* switch over packet codes */
633
 
 
634
 
 
635
 
                  /*
636
 
                   *    If packet->data points to data, then we print out
637
 
                   *    the VP list again only for debugging.
638
 
                   */
 
864
                DEBUG("Sending %s of id %d to %s port %d\n",
 
865
                      what, packet->id,
 
866
                      ip_ntoa(ip_buffer, packet->dst_ipaddr),
 
867
                      packet->dst_port);
 
868
                
 
869
                /*
 
870
                 *      Encode the packet.
 
871
                 */
 
872
                if (rad_encode(packet, original, secret) < 0) {
 
873
                        return -1;
 
874
                }
 
875
                
 
876
                /*
 
877
                 *      Re-sign it, including updating the
 
878
                 *      Message-Authenticator.
 
879
                 */
 
880
                if (rad_sign(packet, original, secret) < 0) {
 
881
                        return -1;
 
882
                }
 
883
 
 
884
                /*
 
885
                 *      If packet->data points to data, then we print out
 
886
                 *      the VP list again only for debugging.
 
887
                 */
639
888
        } else if (librad_debug) {
640
 
                DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
641
 
                      ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
 
889
                DEBUG("Re-sending %s of id %d to %s port %d\n", what, packet->id,
 
890
                      ip_ntoa(ip_buffer, packet->dst_ipaddr),
642
891
                      packet->dst_port);
643
892
 
644
893
                for (reply = packet->vps; reply; reply = reply->next) {
1012
1261
                        }
1013
1262
                        seen_eap |= PW_MESSAGE_AUTHENTICATOR;
1014
1263
                        break;
1015
 
 
1016
 
                case PW_VENDOR_SPECIFIC:
1017
 
                        if (attr[1] <= 6) {
1018
 
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
1019
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr),
1020
 
                                           attr[1] - 2);
1021
 
                                free(packet);
1022
 
                                return NULL;
1023
 
                        }
1024
 
 
1025
 
                        /*
1026
 
                         *      Don't allow VSA's with vendor zero.
1027
 
                         */
1028
 
                        if ((attr[2] == 0) && (attr[3] == 0) &&
1029
 
                            (attr[4] == 0) && (attr[5] == 0)) {
1030
 
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has vendor ID of zero",
1031
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr));
1032
 
                                free(packet);
1033
 
                                return NULL;
1034
 
                        }
1035
 
 
1036
 
                        /*
1037
 
                         *      Don't look at the contents of VSA's,
1038
 
                         *      too many vendors have non-standard
1039
 
                         *      formats.
1040
 
                         */
1041
 
                        break;
1042
1264
                }
1043
1265
 
1044
1266
                /*
1130
1352
        return packet;
1131
1353
}
1132
1354
 
 
1355
 
1133
1356
/*
1134
 
 *      Calculate/check digest, and decode radius attributes.
 
1357
 *      Verify the signature of a packet.
1135
1358
 */
1136
 
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
1359
int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1137
1360
               const char *secret)
1138
1361
{
1139
 
        uint32_t                lvalue;
1140
 
        uint32_t                vendorcode;
1141
 
        VALUE_PAIR              **tail;
1142
 
        VALUE_PAIR              *pair;
1143
1362
        uint8_t                 *ptr;
1144
1363
        int                     length;
1145
 
        int                     attribute;
1146
1364
        int                     attrlen;
1147
 
        int                     vendorlen;
1148
 
        radius_packet_t         *hdr;
1149
1365
 
1150
 
        hdr = (radius_packet_t *)packet->data;
 
1366
        if (!packet || !packet->data) return -1;
1151
1367
 
1152
1368
        /*
1153
1369
         *      Before we allocate memory for the attributes, do more
1154
1370
         *      sanity checking.
1155
1371
         */
1156
 
        ptr = hdr->data;
 
1372
        ptr = packet->data + AUTH_HDR_LEN;
1157
1373
        length = packet->data_len - AUTH_HDR_LEN;
1158
1374
        while (length > 0) {
1159
1375
                uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
1175
1391
 
1176
1392
                        switch (packet->code) {
1177
1393
                        default:
1178
 
                          break;
 
1394
                                break;
 
1395
 
 
1396
                        case PW_ACCOUNTING_REQUEST:
 
1397
                        case PW_ACCOUNTING_RESPONSE:
 
1398
                        case PW_DISCONNECT_REQUEST:
 
1399
                        case PW_DISCONNECT_ACK:
 
1400
                        case PW_DISCONNECT_NAK:
 
1401
                        case PW_COA_REQUEST:
 
1402
                        case PW_COA_ACK:
 
1403
                        case PW_COA_NAK:
 
1404
                                memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
 
1405
                                break;
1179
1406
 
1180
1407
                        case PW_AUTHENTICATION_ACK:
1181
1408
                        case PW_AUTHENTICATION_REJECT:
1182
1409
                        case PW_ACCESS_CHALLENGE:
1183
 
                          if (!original) {
1184
 
                                  librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
1185
 
                                  return -1;
1186
 
                          }
1187
 
                          memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1188
 
                          break;
 
1410
                                if (!original) {
 
1411
                                        librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
 
1412
                                        return -1;
 
1413
                                }
 
1414
                                memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
 
1415
                                break;
1189
1416
                        }
1190
1417
 
1191
1418
                        lrad_hmac_md5(packet->data, packet->data_len,
1192
1419
                                      secret, strlen(secret), calc_auth_vector);
1193
1420
                        if (memcmp(calc_auth_vector, msg_auth_vector,
1194
 
                                    sizeof(calc_auth_vector)) != 0) {
 
1421
                                   sizeof(calc_auth_vector)) != 0) {
1195
1422
                                char buffer[32];
1196
1423
                                librad_log("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
1197
1424
                                           ip_ntoa(buffer, packet->src_ipaddr));
1198
 
                                return -1;
 
1425
                                /* Silently drop packet, according to RFC 3579 */
 
1426
                                return -2;
1199
1427
                        } /* else the message authenticator was good */
1200
1428
 
1201
1429
                        /*
1229
1457
                        if (calc_acctdigest(packet, secret) > 1) {
1230
1458
                                char buffer[32];
1231
1459
                                librad_log("Received Accounting-Request packet "
1232
 
                                    "from %s with invalid signature!  (Shared secret is incorrect.)",
1233
 
                                    ip_ntoa(buffer, packet->src_ipaddr));
 
1460
                                           "from %s with invalid signature!  (Shared secret is incorrect.)",
 
1461
                                           ip_ntoa(buffer, packet->src_ipaddr));
1234
1462
                                return -1;
1235
1463
                        }
1236
1464
                        break;
1238
1466
                        /* Verify the reply digest */
1239
1467
                case PW_AUTHENTICATION_ACK:
1240
1468
                case PW_AUTHENTICATION_REJECT:
 
1469
                case PW_ACCESS_CHALLENGE:
1241
1470
                case PW_ACCOUNTING_RESPONSE:
1242
1471
                        rcode = calc_replydigest(packet, original, secret);
1243
1472
                        if (rcode > 1) {
1244
1473
                                char buffer[32];
1245
1474
                                librad_log("Received %s packet "
1246
 
                                           "from %s:%d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
 
1475
                                           "from client %s port %d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
1247
1476
                                           packet_codes[packet->code],
1248
1477
                                           ip_ntoa(buffer, packet->src_ipaddr),
1249
1478
                                           packet->src_port,
1253
1482
                  break;
1254
1483
        }
1255
1484
 
 
1485
        return 0;
 
1486
}
 
1487
 
 
1488
 
 
1489
/*
 
1490
 *      Parse a RADIUS attribute into a data structure.
 
1491
 */
 
1492
static VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
1493
                        const char *secret, int attribute, int length,
 
1494
                        const uint8_t *data)
 
1495
{
 
1496
        int offset = 0;
 
1497
        VALUE_PAIR *vp;
 
1498
 
 
1499
        if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
 
1500
                return NULL;
 
1501
        }
 
1502
        
 
1503
        /*
 
1504
         *      If length is greater than 253, something is SERIOUSLY
 
1505
         *      wrong.
 
1506
         */
 
1507
        if (length > 253) length = 253; /* paranoia (pair-anoia?) */
 
1508
 
 
1509
        vp->length = length;
 
1510
        vp->operator = T_OP_EQ;
 
1511
        vp->next = NULL;
 
1512
 
 
1513
        /*
 
1514
         *      Handle tags.
 
1515
         */
 
1516
        if (vp->flags.has_tag) {
 
1517
                if (TAG_VALID(data[0]) ||
 
1518
                    (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD)) {
 
1519
                        /*
 
1520
                         *      Tunnel passwords REQUIRE a tag, even
 
1521
                         *      if don't have a valid tag.
 
1522
                         */
 
1523
                        vp->flags.tag = data[0];
 
1524
 
 
1525
                        if ((vp->type == PW_TYPE_STRING) ||
 
1526
                            (vp->type == PW_TYPE_OCTETS)) offset = 1;
 
1527
                }
 
1528
        }
 
1529
 
 
1530
        /*
 
1531
         *      Copy the data to be decrypted
 
1532
         */
 
1533
        memcpy(&vp->strvalue[0], data + offset, length - offset);
 
1534
        vp->length -= offset;
 
1535
 
 
1536
        /*
 
1537
         *      Decrypt the attribute.
 
1538
         */
 
1539
        switch (vp->flags.encrypt) {
 
1540
                /*
 
1541
                 *  User-Password
 
1542
                 */
 
1543
        case FLAG_ENCRYPT_USER_PASSWORD:
 
1544
                if (original) {
 
1545
                        rad_pwdecode((char *)vp->strvalue,
 
1546
                                     vp->length, secret,
 
1547
                                     original->vector);
 
1548
                } else {
 
1549
                        rad_pwdecode((char *)vp->strvalue,
 
1550
                                     vp->length, secret,
 
1551
                                     packet->vector);
 
1552
                }
 
1553
                if (vp->attribute == PW_USER_PASSWORD) {
 
1554
                        vp->length = strlen(vp->strvalue);
 
1555
                }
 
1556
                break;
 
1557
                
 
1558
                /*
 
1559
                 *      Tunnel-Password's may go ONLY
 
1560
                 *      in response packets.
 
1561
                 */
 
1562
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
 
1563
                if (!original) goto raw;
 
1564
                
 
1565
                if (rad_tunnel_pwdecode(vp->strvalue, &vp->length,
 
1566
                                        secret, original->vector) < 0) {
 
1567
                        goto raw;
 
1568
                }
 
1569
                break;
 
1570
                
 
1571
                /*
 
1572
                 *  Ascend-Send-Secret
 
1573
                 *  Ascend-Receive-Secret
 
1574
                 */
 
1575
        case FLAG_ENCRYPT_ASCEND_SECRET:
 
1576
                if (!original) {
 
1577
                        goto raw;
 
1578
                } else {
 
1579
                        uint8_t my_digest[AUTH_VECTOR_LEN];
 
1580
                        make_secret(my_digest,
 
1581
                                    original->vector,
 
1582
                                    secret, data);
 
1583
                        memcpy(vp->strvalue, my_digest,
 
1584
                               AUTH_VECTOR_LEN );
 
1585
                        vp->strvalue[AUTH_VECTOR_LEN] = '\0';
 
1586
                        vp->length = strlen(vp->strvalue);
 
1587
                }
 
1588
                break;
 
1589
 
 
1590
        default:
 
1591
                break;
 
1592
        } /* switch over encryption flags */
 
1593
 
 
1594
 
 
1595
        switch (vp->type) {
 
1596
        case PW_TYPE_STRING:
 
1597
        case PW_TYPE_OCTETS:
 
1598
        case PW_TYPE_ABINARY:
 
1599
                /* nothing more to do */
 
1600
                break;
 
1601
 
 
1602
        case PW_TYPE_INTEGER:
 
1603
                if (vp->length != 4) goto raw;
 
1604
 
 
1605
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1606
                vp->lvalue = ntohl(vp->lvalue);
 
1607
 
 
1608
                if (vp->flags.has_tag) vp->lvalue &= 0x00ffffff;
 
1609
 
 
1610
                /*
 
1611
                 *      Try to get named VALUEs
 
1612
                 */
 
1613
                {
 
1614
                        DICT_VALUE *dval;
 
1615
                        dval = dict_valbyattr(vp->attribute,
 
1616
                                              vp->lvalue);
 
1617
                        if (dval) {
 
1618
                                strNcpy(vp->strvalue,
 
1619
                                        dval->name,
 
1620
                                        sizeof(vp->strvalue));
 
1621
                        }
 
1622
                }
 
1623
                break;
 
1624
 
 
1625
        case PW_TYPE_DATE:
 
1626
                if (vp->length != 4) goto raw;
 
1627
 
 
1628
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1629
                vp->lvalue = ntohl(vp->lvalue);
 
1630
                break;
 
1631
 
 
1632
                /*
 
1633
                 *      IPv4 address. Keep it in network byte order in
 
1634
                 *      vp->lvalue and put ASCII IP address in standard
 
1635
                 *      dot notation into vp->strvalue.
 
1636
                 */
 
1637
        case PW_TYPE_IPADDR:
 
1638
                if (vp->length != 4) goto raw;
 
1639
 
 
1640
                memcpy(&vp->lvalue, vp->strvalue, 4);
 
1641
                ip_ntoa(vp->strvalue, vp->lvalue);
 
1642
                break;
 
1643
 
 
1644
                /*
 
1645
                 *      IPv6 interface ID is 8 octets long.
 
1646
                 */
 
1647
        case PW_TYPE_IFID:
 
1648
                if (vp->length != 8) goto raw;
 
1649
                /* vp->vp_ifid == vp->strvalue */
 
1650
                break;
 
1651
                
 
1652
                /*
 
1653
                 *      IPv6 addresses are 16 octets long
 
1654
                 */
 
1655
        case PW_TYPE_IPV6ADDR:
 
1656
                if (vp->length != 16) goto raw;
 
1657
                /* vp->vp_ipv6addr == vp->strvalue */
 
1658
                break;
 
1659
                
 
1660
                /*
 
1661
                 *      IPv6 prefixes are 2 to 18 octets long.
 
1662
                 *
 
1663
                 *      RFC 3162: The first octet is unused.
 
1664
                 *      The second is the length of the prefix
 
1665
                 *      the rest are the prefix data.
 
1666
                 *
 
1667
                 *      The prefix length can have value 0 to 128.
 
1668
                 */
 
1669
        case PW_TYPE_IPV6PREFIX:
 
1670
                if (vp->length < 2 || vp->length > 18) goto raw;
 
1671
                if (vp->strvalue[1] > 128) goto raw;
 
1672
 
 
1673
                /*
 
1674
                 *      FIXME: double-check that
 
1675
                 *      (vp->strvalue[1] >> 3) matches vp->length + 2
 
1676
                 */
 
1677
                if (vp->length < 18) {
 
1678
                        memset(vp->strvalue + vp->length, 0,
 
1679
                               18 - vp->length);
 
1680
                }
 
1681
                break;
 
1682
 
 
1683
        default:
 
1684
        raw:
 
1685
                vp->type = PW_TYPE_OCTETS;
 
1686
                vp->length = length;
 
1687
                memcpy(vp->strvalue, data, length);
 
1688
                
 
1689
 
 
1690
                /*
 
1691
                 *      Ensure there's no encryption or tag stuff,
 
1692
                 *      we just pass the attribute as-is.
 
1693
                 */
 
1694
                memset(&vp->flags, 0, sizeof(vp->flags));
 
1695
        }
 
1696
 
 
1697
        return vp;
 
1698
}
 
1699
 
 
1700
 
 
1701
/*
 
1702
 *      Calculate/check digest, and decode radius attributes.
 
1703
 */
 
1704
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
1705
               const char *secret)
 
1706
{
 
1707
        uint32_t                lvalue;
 
1708
        uint32_t                vendorcode;
 
1709
        VALUE_PAIR              **tail;
 
1710
        VALUE_PAIR              *pair;
 
1711
        uint8_t                 *ptr;
 
1712
        int                     packet_length;
 
1713
        int                     attribute;
 
1714
        int                     attrlen;
 
1715
        int                     vendorlen;
 
1716
        radius_packet_t         *hdr;
 
1717
        int                     vsa_tlen, vsa_llen;
 
1718
        DICT_VENDOR             *dv = NULL;
 
1719
 
1256
1720
        /*
1257
1721
         *      Extract attribute-value pairs
1258
1722
         */
 
1723
        hdr = (radius_packet_t *)packet->data;
1259
1724
        ptr = hdr->data;
1260
 
        length = packet->data_len - AUTH_HDR_LEN;
 
1725
        packet_length = packet->data_len - AUTH_HDR_LEN;
1261
1726
 
1262
1727
        /*
1263
1728
         *      There may be VP's already in the packet.  Don't
1269
1734
 
1270
1735
        vendorcode = 0;
1271
1736
        vendorlen  = 0;
1272
 
 
1273
 
        while (length > 0) {
1274
 
                if (vendorlen > 0) {
1275
 
                        attribute = *ptr++ | (vendorcode << 16);
1276
 
                        attrlen   = *ptr++;
1277
 
                } else {
 
1737
        vsa_tlen = vsa_llen = 1;
 
1738
 
 
1739
        /*
 
1740
         *      We have to read at least two bytes.
 
1741
         *
 
1742
         *      rad_recv() above ensures that this is OK.
 
1743
         */
 
1744
        while (packet_length > 0) {
 
1745
                attribute = -1;
 
1746
                attrlen = -1;
 
1747
 
 
1748
                /*
 
1749
                 *      Normal attribute, handle it like normal.
 
1750
                 */
 
1751
                if (vendorcode == 0) {
 
1752
                        /*
 
1753
                         *      No room to read attr/length,
 
1754
                         *      or bad attribute, or attribute is
 
1755
                         *      too short, or attribute is too long,
 
1756
                         *      stop processing the packet.
 
1757
                         */
 
1758
                        if ((packet_length < 2) ||
 
1759
                            (ptr[0] == 0) ||  (ptr[1] < 2) ||
 
1760
                            (ptr[1] > packet_length)) break;
 
1761
 
1278
1762
                        attribute = *ptr++;
1279
1763
                        attrlen   = *ptr++;
 
1764
 
 
1765
                        attrlen -= 2;
 
1766
                        packet_length  -= 2;
 
1767
 
 
1768
                        if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
 
1769
                        
 
1770
                        /*
 
1771
                         *      No vendor code, or ONLY vendor code.
 
1772
                         */
 
1773
                        if (attrlen <= 4) goto create_pair;
 
1774
 
 
1775
                        vendorlen = 0;
1280
1776
                }
1281
 
 
1282
 
                attrlen -= 2;
1283
 
                length  -= 2;
1284
 
 
 
1777
                
1285
1778
                /*
1286
 
                 *      This could be a Vendor-Specific attribute.
 
1779
                 *      Handle Vendor-Specific
1287
1780
                 */
1288
 
                if ((vendorlen <= 0) &&
1289
 
                    (attribute == PW_VENDOR_SPECIFIC)) {
1290
 
                        int     sublen;
1291
 
                        uint8_t *subptr;
1292
 
 
 
1781
                if (vendorlen == 0) {
 
1782
                        uint8_t *subptr;
 
1783
                        int sublen;
 
1784
                        int myvendor;
 
1785
                        
1293
1786
                        /*
1294
 
                         *      attrlen was checked to be >= 6, in rad_recv
 
1787
                         *      attrlen was checked above.
1295
1788
                         */
1296
1789
                        memcpy(&lvalue, ptr, 4);
1297
 
                        vendorcode = ntohl(lvalue);
 
1790
                        myvendor = ntohl(lvalue);
1298
1791
 
1299
1792
                        /*
 
1793
                         *      Zero isn't allowed.
 
1794
                         */
 
1795
                        if (myvendor == 0) goto create_pair;
 
1796
                        
 
1797
                        /*
1300
1798
                         *      This is an implementation issue.
1301
1799
                         *      We currently pack vendor into the upper
1302
1800
                         *      16 bits of a 32-bit attribute number,
1303
1801
                         *      so we can't handle vendor numbers larger
1304
1802
                         *      than 16 bits.
1305
1803
                         */
1306
 
                        if (vendorcode > 65535) goto create_pair;
1307
 
 
1308
 
                        /*
1309
 
                         *      vendorcode was checked to be non-zero
1310
 
                         *      above, in rad_recv.
1311
 
                         */
1312
 
 
1313
 
                        /*
1314
 
                         *      First, check to see if the
1315
 
                         *      sub-attributes fill the VSA, as
1316
 
                         *      defined by the RFC.  If not, then it
1317
 
                         *      may be a USR-style VSA, or it may be a
1318
 
                         *      vendor who packs all of the
1319
 
                         *      information into one nonsense
1320
 
                         *      attribute
 
1804
                        if (myvendor > 65535) goto create_pair;
 
1805
                        
 
1806
                        vsa_tlen = vsa_llen = 1;
 
1807
                        dv = dict_vendorbyvalue(myvendor);
 
1808
                        if (dv) {
 
1809
                                vsa_tlen = dv->type;
 
1810
                                vsa_llen = dv->length;
 
1811
                        }
 
1812
                        
 
1813
                        /*
 
1814
                         *      Sweep through the list of VSA's,
 
1815
                         *      seeing if they exactly fill the
 
1816
                         *      outer Vendor-Specific attribute.
 
1817
                         *
 
1818
                         *      If not, create a raw Vendor-Specific.
1321
1819
                         */
1322
1820
                        subptr = ptr + 4;
1323
1821
                        sublen = attrlen - 4;
1324
1822
 
1325
 
                        while (sublen > 0) {
1326
 
                                if (subptr[1] < 2) { /* too short */
1327
 
                                        break;
1328
 
                                }
1329
 
 
1330
 
                                if (subptr[1] > sublen) { /* too long */
1331
 
                                        break;
1332
 
                                }
1333
 
 
1334
 
                                sublen -= subptr[1]; /* just right */
1335
 
                                subptr += subptr[1];
1336
 
                        }
1337
 
 
1338
1823
                        /*
1339
 
                         *      If the attribute is RFC compatible,
1340
 
                         *      then allow it as an RFC style VSA.
 
1824
                         *      See if we can parse it.
1341
1825
                         */
1342
 
                        if (sublen == 0) {
1343
 
                                ptr += 4;
1344
 
                                vendorlen = attrlen - 4;
1345
 
                                attribute = *ptr++ | (vendorcode << 16);
1346
 
                                attrlen   = *ptr++;
1347
 
                                attrlen -= 2;
1348
 
                                length -= 6;
1349
 
 
1350
 
                                /*
1351
 
                                 *      USR-style attributes are 4 octets,
1352
 
                                 *      with the upper 2 octets being zero.
1353
 
                                 *
1354
 
                                 *      The upper octets may not be zero,
1355
 
                                 *      but that then means we won't be
1356
 
                                 *      able to pack the vendor & attribute
1357
 
                                 *      into a 32-bit number, so we can't
1358
 
                                 *      handle it.
1359
 
                                 *
1360
 
                                 *
1361
 
                                 *      FIXME: Update the dictionaries so
1362
 
                                 *      that we key off of per-attribute
1363
 
                                 *      flags "4-octet", instead of hard
1364
 
                                 *      coding USR here.  This will also
1365
 
                                 *      let us send packets with other
1366
 
                                 *      vendors having 4-octet attributes.
1367
 
                                 */
1368
 
                        } else if ((vendorcode == VENDORPEC_USR) &&
1369
 
                                   ((ptr[4] == 0) && (ptr[5] == 0)) &&
1370
 
                                   (attrlen >= 8)) {
1371
 
                                DICT_ATTR *da;
1372
 
 
1373
 
                                da = dict_attrbyvalue((vendorcode << 16) |
1374
 
                                                      (ptr[6] << 8) |
1375
 
                                                      ptr[7]);
1376
 
 
1377
 
                                /*
1378
 
                                 *      See if it's in the dictionary.
1379
 
                                 *      If so, it's a valid USR style
1380
 
                                 *      attribute.  If not, it's not...
1381
 
                                 *
1382
 
                                 *      Don't touch 'attribute' until
1383
 
                                 *      we know what to do!
1384
 
                                 */
1385
 
                                if (da != NULL) {
1386
 
                                        attribute = ((vendorcode << 16) |
1387
 
                                                     (ptr[6] << 8) |
1388
 
                                                     ptr[7]);
1389
 
                                        ptr += 8;
1390
 
                                        attrlen -= 8;
1391
 
                                        length -= 8;
1392
 
                                } /* else it's not in the dictionary */
1393
 
                        } /* else it was a stupid vendor format */
1394
 
                } /* else it wasn't a VSA */
 
1826
                        do {
 
1827
                                int myattr = 0;
 
1828
 
 
1829
                                /*
 
1830
                                 *      Don't have a type, it's bad.
 
1831
                                 */
 
1832
                                if (sublen < vsa_tlen) goto create_pair;
 
1833
                                
 
1834
                                /*
 
1835
                                 *      Ensure that the attribute number
 
1836
                                 *      is OK.
 
1837
                                 */
 
1838
                                switch (vsa_tlen) {
 
1839
                                case 1:
 
1840
                                        myattr = subptr[0];
 
1841
                                        break;
 
1842
                                        
 
1843
                                case 2:
 
1844
                                        myattr = (subptr[0] << 8) | subptr[1];
 
1845
                                        break;
 
1846
                                        
 
1847
                                case 4:
 
1848
                                        if ((subptr[0] != 0) ||
 
1849
                                            (subptr[1] != 0)) goto create_pair;
 
1850
                                        
 
1851
                                        myattr = (subptr[2] << 8) | subptr[3];
 
1852
                                        break;
 
1853
                                        
 
1854
                                        /*
 
1855
                                         *      Our dictionary is broken.
 
1856
                                         */
 
1857
                                default:
 
1858
                                        goto create_pair;
 
1859
                                }
 
1860
                                
 
1861
                                /*
 
1862
                                 *      Not enough room for one more
 
1863
                                 *      attribute.  Die!
 
1864
                                 */
 
1865
                                if (sublen < vsa_tlen + vsa_llen) goto create_pair;
 
1866
                                switch (vsa_llen) {
 
1867
                                case 0:
 
1868
                                        attribute = (myvendor << 16) | myattr;
 
1869
                                        ptr += 4 + vsa_tlen;
 
1870
                                        attrlen -= (4 + vsa_tlen);
 
1871
                                        packet_length -= 4 + vsa_tlen;
 
1872
                                        goto create_pair;
 
1873
 
 
1874
                                case 1:
 
1875
                                        if (subptr[vsa_tlen] < (vsa_tlen + vsa_llen))
 
1876
                                                goto create_pair;
 
1877
 
 
1878
                                        if (subptr[vsa_tlen] > sublen)
 
1879
                                                goto create_pair;
 
1880
                                        sublen -= subptr[vsa_tlen];
 
1881
                                        subptr += subptr[vsa_tlen];
 
1882
                                        break;
 
1883
 
 
1884
                                case 2:
 
1885
                                        if (subptr[vsa_tlen] != 0) goto create_pair;
 
1886
                                        if (subptr[vsa_tlen + 1] < (vsa_tlen + vsa_llen))
 
1887
                                                goto create_pair;
 
1888
                                        if (subptr[vsa_tlen + 1] > sublen)
 
1889
                                                goto create_pair;
 
1890
                                        sublen -= subptr[vsa_tlen + 1];
 
1891
                                        subptr += subptr[vsa_tlen + 1];
 
1892
                                        break;
 
1893
 
 
1894
                                        /*
 
1895
                                         *      Our dictionaries are
 
1896
                                         *      broken.
 
1897
                                         */
 
1898
                                default:
 
1899
                                        goto create_pair;
 
1900
                                }
 
1901
                        } while (sublen > 0);
 
1902
 
 
1903
                        vendorcode = myvendor;
 
1904
                        vendorlen = attrlen - 4;
 
1905
                        packet_length -= 4;
 
1906
 
 
1907
                        ptr += 4;
 
1908
                }
 
1909
 
 
1910
                /*
 
1911
                 *      attrlen is the length of this attribute.
 
1912
                 *      total_len is the length of the encompassing
 
1913
                 *      attribute.
 
1914
                 */
 
1915
                switch (vsa_tlen) {
 
1916
                case 1:
 
1917
                        attribute = ptr[0];
 
1918
                        break;
 
1919
                        
 
1920
                case 2:
 
1921
                        attribute = (ptr[0] << 8) | ptr[1];
 
1922
                        break;
 
1923
 
 
1924
                default:        /* can't hit this. */
 
1925
                        return -1;
 
1926
                }
 
1927
                attribute |= (vendorcode << 16);
 
1928
                ptr += vsa_tlen;
 
1929
 
 
1930
                switch (vsa_llen) {
 
1931
                case 1:
 
1932
                        attrlen = ptr[0] - (vsa_tlen + vsa_llen);
 
1933
                        break;
 
1934
                        
 
1935
                case 2:
 
1936
                        attrlen = ptr[1] - (vsa_tlen + vsa_llen);
 
1937
                        break;
 
1938
 
 
1939
                default:        /* can't hit this. */
 
1940
                        return -1;
 
1941
                }
 
1942
                ptr += vsa_llen;
 
1943
                vendorlen -= vsa_tlen + vsa_llen + attrlen;
 
1944
                if (vendorlen == 0) vendorcode = 0;
 
1945
                packet_length -= (vsa_tlen + vsa_llen);
1395
1946
 
1396
1947
                /*
1397
1948
                 *      Create the attribute, setting the default type
1400
1951
                 *      over-ride this one.
1401
1952
                 */
1402
1953
        create_pair:
1403
 
                if ((pair = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
 
1954
                pair = rad_attr2vp(packet, original, secret,
 
1955
                                 attribute, attrlen, ptr);
 
1956
                if (!pair) {
1404
1957
                        pairfree(&packet->vps);
1405
1958
                        librad_log("out of memory");
1406
1959
                        return -1;
1407
1960
                }
1408
1961
 
1409
 
                pair->length = attrlen;
1410
 
                pair->operator = T_OP_EQ;
1411
 
                pair->next = NULL;
1412
 
 
1413
 
                switch (pair->type) {
1414
 
 
1415
 
                        /*
1416
 
                         *      The attribute may be zero length,
1417
 
                         *      or it may have a tag, and then no data...
1418
 
                         */
1419
 
                case PW_TYPE_STRING:
1420
 
                        if (pair->flags.has_tag) {
1421
 
                                int offset = 0;
1422
 
 
1423
 
                                /*
1424
 
                                 *      If there's sufficient room for
1425
 
                                 *      a tag, and the tag looks valid,
1426
 
                                 *      then use it.
1427
 
                                 */
1428
 
                                if ((pair->length > 0) &&
1429
 
                                    TAG_VALID_ZERO(*ptr)) {
1430
 
                                        pair->flags.tag = *ptr;
1431
 
                                        pair->length--;
1432
 
                                        offset = 1;
1433
 
 
1434
 
                                        /*
1435
 
                                         *      If the leading tag
1436
 
                                         *      isn't valid, then it's
1437
 
                                         *      ignored for the tunnel
1438
 
                                         *      password attribute.
1439
 
                                         */
1440
 
                                } else if (pair->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
1441
 
                                        /*
1442
 
                                         * from RFC2868 - 3.5.  Tunnel-Password
1443
 
                                         * If the value of the Tag field is greater than
1444
 
                                         * 0x00 and less than or equal to 0x1F, it SHOULD
1445
 
                                         * be interpreted as indicating which tunnel
1446
 
                                         * (of several alternatives) this attribute pertains;
1447
 
                                         * otherwise, the Tag field SHOULD be ignored.
1448
 
                                         */
1449
 
                                        pair->flags.tag = 0x00;
1450
 
                                        if (pair->length > 0) pair->length--;
1451
 
                                        offset = 1;
1452
 
                                } else {
1453
 
                                       pair->flags.tag = 0x00;
1454
 
                                }
1455
 
 
1456
 
                                /*
1457
 
                                 *      pair->length MAY be zero here.
1458
 
                                 */
1459
 
                                memcpy(pair->strvalue, ptr + offset,
1460
 
                                       pair->length);
1461
 
                        } else {
1462
 
                          /*
1463
 
                           *    Ascend binary attributes never have a
1464
 
                           *    tag, and neither do the 'octets' type.
1465
 
                           */
1466
 
                        case PW_TYPE_ABINARY:
1467
 
                        case PW_TYPE_OCTETS:
1468
 
                                /* attrlen always < MAX_STRING_LEN */
1469
 
                                memcpy(pair->strvalue, ptr, attrlen);
1470
 
                                pair->flags.tag = 0;
1471
 
                        }
1472
 
 
1473
 
                        /*
1474
 
                         *      Decrypt passwords here.
1475
 
                         */
1476
 
                        switch (pair->flags.encrypt) {
1477
 
                        default:
1478
 
                                break;
1479
 
 
1480
 
                                /*
1481
 
                                 *  User-Password
1482
 
                                 */
1483
 
                        case FLAG_ENCRYPT_USER_PASSWORD:
1484
 
                                if (original) {
1485
 
                                        rad_pwdecode((char *)pair->strvalue,
1486
 
                                                     pair->length, secret,
1487
 
                                                     (char *)original->vector);
1488
 
                                } else {
1489
 
                                        rad_pwdecode((char *)pair->strvalue,
1490
 
                                                     pair->length, secret,
1491
 
                                                     (char *)packet->vector);
1492
 
                                }
1493
 
                                if (pair->attribute == PW_USER_PASSWORD) {
1494
 
                                        pair->length = strlen(pair->strvalue);
1495
 
                                }
1496
 
                                break;
1497
 
 
1498
 
                                /*
1499
 
                                 *      Tunnel-Password's may go ONLY
1500
 
                                 *      in response packets.
1501
 
                                 */
1502
 
                        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
1503
 
                                if (!original) {
1504
 
                                        librad_log("ERROR: Tunnel-Password attribute in request: Cannot decrypt it.");
1505
 
                                        free(pair);
1506
 
                                        return -1;
1507
 
                                }
1508
 
                                if (rad_tunnel_pwdecode(pair->strvalue,
1509
 
                                                        &pair->length,
1510
 
                                                        secret,
1511
 
                                                        (char *)original->vector) < 0) {
1512
 
                                        free(pair);
1513
 
                                        return -1;
1514
 
                                }
1515
 
                                break;
1516
 
 
1517
 
                                /*
1518
 
                                 *  Ascend-Send-Secret
1519
 
                                 *  Ascend-Receive-Secret
1520
 
                                 */
1521
 
                        case FLAG_ENCRYPT_ASCEND_SECRET:
1522
 
                                if (!original) {
1523
 
                                        librad_log("ERROR: Ascend-Send-Secret attribute in request: Cannot decrypt it.");
1524
 
                                        free(pair);
1525
 
                                        return -1;
1526
 
                                } else {
1527
 
                                        uint8_t my_digest[AUTH_VECTOR_LEN];
1528
 
                                        make_secret(my_digest,
1529
 
                                                    original->vector,
1530
 
                                                    secret, ptr);
1531
 
                                        memcpy(pair->strvalue, my_digest,
1532
 
                                               AUTH_VECTOR_LEN );
1533
 
                                        pair->strvalue[AUTH_VECTOR_LEN] = '\0';
1534
 
                                        pair->length = strlen(pair->strvalue);
1535
 
                                }
1536
 
                                break;
1537
 
                        } /* switch over encryption flags */
1538
 
                        break;  /* from octets/string/abinary */
1539
 
 
1540
 
                case PW_TYPE_INTEGER:
1541
 
                case PW_TYPE_DATE:
1542
 
                case PW_TYPE_IPADDR:
1543
 
                        /*
1544
 
                         *      Check for RFC compliance.  If the
1545
 
                         *      attribute isn't compliant, turn it
1546
 
                         *      into a string of raw octets.
1547
 
                         *
1548
 
                         *      Also set the lvalue to something
1549
 
                         *      which should never match anything.
1550
 
                         */
1551
 
                        if (attrlen != 4) {
1552
 
                                pair->type = PW_TYPE_OCTETS;
1553
 
                                memcpy(pair->strvalue, ptr, attrlen);
1554
 
                                pair->lvalue = 0xbad1bad1;
1555
 
                                break;
1556
 
                        }
1557
 
 
1558
 
                        memcpy(&lvalue, ptr, 4);
1559
 
 
1560
 
                        if (pair->type != PW_TYPE_IPADDR) {
1561
 
                                pair->lvalue = ntohl(lvalue);
1562
 
                        } else {
1563
 
                                 /*
1564
 
                                  *  It's an IP address, keep it in network
1565
 
                                  *  byte order, and put the ASCII IP
1566
 
                                  *  address or host name into the string
1567
 
                                  *  value.
1568
 
                                  */
1569
 
                                pair->lvalue = lvalue;
1570
 
                                ip_ntoa(pair->strvalue, pair->lvalue);
1571
 
                        }
1572
 
 
1573
 
                        /*
1574
 
                         *      Tagged attributes of type integer have
1575
 
                         *      special treatment.
1576
 
                         */
1577
 
                        if (pair->flags.has_tag &&
1578
 
                            pair->type == PW_TYPE_INTEGER) {
1579
 
                                pair->flags.tag = (pair->lvalue >> 24) & 0xff;
1580
 
                                pair->lvalue &= 0x00ffffff;
1581
 
                        }
1582
 
 
1583
 
                        /*
1584
 
                         *      Try to get the name for integer
1585
 
                         *      attributes.
1586
 
                         */
1587
 
                        if (pair->type == PW_TYPE_INTEGER) {
1588
 
                                DICT_VALUE *dval;
1589
 
                                dval = dict_valbyattr(pair->attribute,
1590
 
                                                      pair->lvalue);
1591
 
                                if (dval) {
1592
 
                                        strNcpy(pair->strvalue,
1593
 
                                                dval->name,
1594
 
                                                sizeof(pair->strvalue));
1595
 
                                }
1596
 
                        }
1597
 
                        break;
1598
 
 
1599
 
                        /*
1600
 
                         *      IPv6 interface ID is 8 octets long.
1601
 
                         */
1602
 
                case PW_TYPE_IFID:
1603
 
                        if (attrlen != 8)
1604
 
                                pair->type = PW_TYPE_OCTETS;
1605
 
                        memcpy(pair->strvalue, ptr, attrlen);
1606
 
                        break;
1607
 
 
1608
 
                        /*
1609
 
                         *      IPv6 addresses are 16 octets long
1610
 
                         */
1611
 
                case PW_TYPE_IPV6ADDR:
1612
 
                        if (attrlen != 16)
1613
 
                                pair->type = PW_TYPE_OCTETS;
1614
 
                        memcpy(pair->strvalue, ptr, attrlen);
1615
 
                        break;
1616
 
 
1617
 
                        /*
1618
 
                         *      IPv6 prefixes are 2 to 18 octets long.
1619
 
                         *
1620
 
                         *      RFC 3162: The first octet is unused.
1621
 
                         *      The second is the length of the prefix
1622
 
                         *      the rest are the prefix data.
1623
 
                         *
1624
 
                         *      The prefix length can have value 0 to 128.
1625
 
                         */
1626
 
                case PW_TYPE_IPV6PREFIX:
1627
 
                        if (attrlen < 2 || attrlen > 18)
1628
 
                                pair->type = PW_TYPE_OCTETS;
1629
 
                        if (attrlen >= 2) {
1630
 
                                if (ptr[1] > 128) {
1631
 
                                        pair->type = PW_TYPE_OCTETS;
1632
 
                                }
1633
 
                                /*
1634
 
                                 *      FIXME: double-check that
1635
 
                                 *      (ptr[1] >> 3) matches attrlen + 2
1636
 
                                 */
1637
 
                        }
1638
 
                        memcpy(pair->strvalue, ptr, attrlen);
1639
 
                        break;
1640
 
 
1641
 
                default:
1642
 
                        DEBUG("    %s (Unknown Type %d)\n",
1643
 
                              pair->name, pair->type);
1644
 
                        free(pair);
1645
 
                        pair = NULL;
1646
 
                        break;
1647
 
                }
1648
 
 
1649
 
                if (pair) {
1650
 
                        debug_pair(pair);
1651
 
                        *tail = pair;
1652
 
                        tail = &pair->next;
1653
 
                }
 
1962
                debug_pair(pair);
 
1963
                *tail = pair;
 
1964
                tail = &pair->next;
1654
1965
 
1655
1966
                ptr += attrlen;
1656
 
                length -= attrlen;
1657
 
                if (vendorlen > 0) vendorlen -= (attrlen + 2);
 
1967
                packet_length -= attrlen;
1658
1968
        }
1659
1969
 
1660
1970
        /*
1661
1971
         *      Merge information from the outside world into our
1662
 
         *      random pool
 
1972
         *      random pool.
1663
1973
         */
1664
 
        for (length = 0; length < AUTH_VECTOR_LEN; length++) {
1665
 
                lrad_rand_pool.randmem[length] += packet->vector[length];
1666
 
        }
1667
 
        lrad_rand_pool.randmem[lrad_rand_pool.randmem[0] & 0xff] += packet->id;
1668
 
        lrad_rand_pool.randmem[lrad_rand_pool.randmem[1] & 0xff] += packet->data_len;
1669
 
 
 
1974
        lrad_rand_seed(packet->data, AUTH_HDR_LEN);
 
1975
          
1670
1976
        return 0;
1671
1977
}
1672
1978
 
1682
1988
 *      int *pwlen is updated to the new length of the encrypted
1683
1989
 *      password - a multiple of 16 bytes.
1684
1990
 */
1685
 
#define AUTH_PASS_LEN (16)
1686
1991
int rad_pwencode(char *passwd, int *pwlen, const char *secret,
1687
1992
                 const char *vector)
1688
1993
{
1789
2094
        return pwlen;
1790
2095
}
1791
2096
 
1792
 
static unsigned int salt_offset = 0;
1793
2097
 
1794
2098
/*
1795
2099
 *      Encode Tunnel-Password attributes when sending them out on the wire.
2041
2345
        return 0;
2042
2346
}
2043
2347
 
 
2348
 
2044
2349
/*
2045
 
 *      Create a random vector of AUTH_VECTOR_LEN bytes.
 
2350
 *      Seed the random number generator.
 
2351
 *
 
2352
 *      May be called any number of times.
2046
2353
 */
2047
 
static void random_vector(uint8_t *vector)
 
2354
void lrad_rand_seed(const void *data, size_t size)
2048
2355
{
2049
 
        int i;
 
2356
        uint32_t hash;
2050
2357
 
2051
 
        if (!lrad_pool_initialized) {
 
2358
        /*
 
2359
         *      Ensure that the pool is initialized.
 
2360
         */
 
2361
        if (lrad_rand_index < 0) {
 
2362
                int fd;
 
2363
                
2052
2364
                memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
2053
2365
 
2054
 
                /*
2055
 
                 *      Initialize the state to something, using
2056
 
                 *      numbers which aren't random, but which also
2057
 
                 *      aren't static.
2058
 
                 */
2059
 
                lrad_rand_pool.randrsl[0] = (uint32_t) &lrad_pool_initialized;
2060
 
                lrad_rand_pool.randrsl[1] = (uint32_t) &i;
2061
 
                lrad_rand_pool.randrsl[2] = (uint32_t) vector;
 
2366
                fd = open("/dev/urandom", O_RDONLY);
 
2367
                if (fd >= 0) {
 
2368
                        size_t total;
 
2369
                        ssize_t this;
 
2370
 
 
2371
                        total = this = 0;
 
2372
                        while (total < sizeof(lrad_rand_pool.randrsl)) {
 
2373
                                this = read(fd, lrad_rand_pool.randrsl,
 
2374
                                            sizeof(lrad_rand_pool.randrsl) - total);
 
2375
                                if ((this < 0) && (errno != EINTR)) break;
 
2376
                                if (this > 0) total += this;
 
2377
                        }
 
2378
                        close(fd);
 
2379
                } else {
 
2380
                        lrad_rand_pool.randrsl[0] = fd;
 
2381
                        lrad_rand_pool.randrsl[1] = time(NULL);
 
2382
                        lrad_rand_pool.randrsl[2] = errno;
 
2383
                }
2062
2384
 
2063
2385
                lrad_randinit(&lrad_rand_pool, 1);
2064
 
                lrad_pool_initialized = 1;
 
2386
                lrad_rand_index = 0;
2065
2387
        }
2066
2388
 
2067
 
        lrad_isaac(&lrad_rand_pool);
2068
 
 
2069
 
        /*
2070
 
         *      Copy the random data over.
2071
 
         */
2072
 
        for (i = 0; i < AUTH_VECTOR_LEN; i++) {
2073
 
                *(vector++) = lrad_rand_pool.randrsl[i] & 0xff;
 
2389
        if (!data) return;
 
2390
 
 
2391
        /*
 
2392
         *      Hash the user data
 
2393
         */
 
2394
        hash = lrad_hash(data, size);
 
2395
        
 
2396
        lrad_rand_pool.randrsl[lrad_rand_index & 0xff] ^= hash;
 
2397
        lrad_rand_index++;
 
2398
        lrad_rand_index &= 0xff;
 
2399
 
 
2400
        /*
 
2401
         *      Churn the pool every so often after seeding it.
 
2402
         */
 
2403
        if (((int) (hash & 0xff)) == lrad_rand_index) {
 
2404
                lrad_isaac(&lrad_rand_pool);
2074
2405
        }
2075
2406
}
2076
2407
 
 
2408
 
2077
2409
/*
2078
2410
 *      Return a 32-bit random number.
2079
2411
 */
2080
2412
uint32_t lrad_rand(void)
2081
2413
{
2082
 
        uint32_t answer;
2083
 
        static int rand_index = 0;
 
2414
        uint32_t num;
2084
2415
 
2085
2416
        /*
2086
2417
         *      Ensure that the pool is initialized.
2087
2418
         */
2088
 
        if (!lrad_pool_initialized) {
2089
 
                uint8_t vector[AUTH_VECTOR_LEN];
2090
 
 
2091
 
                random_vector(vector);
 
2419
        if (lrad_rand_index < 0) {
 
2420
                lrad_rand_seed(NULL, 0);
2092
2421
        }
2093
2422
 
2094
2423
        /*
2095
 
         *      Grab an entry from the pool.
2096
 
         */
2097
 
        answer = lrad_rand_pool.randrsl[rand_index];
2098
 
 
2099
 
        /*
2100
 
         *      Go to the next entry (wrapping around to zero).
2101
 
         */
2102
 
        rand_index++;
2103
 
        rand_index &= 0xff;
2104
 
 
2105
 
        /*
2106
 
         *      Every 256 numbers, churn the pool again.
2107
 
         */
2108
 
        if (rand_index == 0) {
 
2424
         *      We don't return data directly from the pool.
 
2425
         *      Rather, we return a summary of the data.
 
2426
         */
 
2427
        num = lrad_rand_pool.randrsl[lrad_rand_index & 0xff];
 
2428
        lrad_rand_index++;
 
2429
        lrad_rand_index &= 0xff;
 
2430
 
 
2431
        /*
 
2432
         *      Every so often, churn the pool.
 
2433
         */
 
2434
        if (((int) (num & 0xff)) == lrad_rand_index) {
2109
2435
                lrad_isaac(&lrad_rand_pool);
2110
2436
        }
2111
2437
 
2112
 
        return answer;
 
2438
        return num;
2113
2439
}
2114
2440
 
2115
2441
/*
2124
2450
                return NULL;
2125
2451
        }
2126
2452
        memset(rp, 0, sizeof(RADIUS_PACKET));
2127
 
        if (newvector)
2128
 
                random_vector(rp->vector);
 
2453
        if (newvector) {
 
2454
                int i;
 
2455
                uint32_t hash, base;
 
2456
 
 
2457
                /*
 
2458
                 *      Don't expose the actual contents of the random
 
2459
                 *      pool.
 
2460
                 */
 
2461
                base = lrad_rand();
 
2462
                for (i = 0; i < AUTH_VECTOR_LEN; i += sizeof(uint32_t)) {
 
2463
                        hash = lrad_rand() ^ base;
 
2464
                        memcpy(rp->vector + i, &hash, sizeof(hash));
 
2465
                }
 
2466
        }
2129
2467
        lrad_rand();
2130
2468
 
2131
2469
        return rp;
2148
2486
 
2149
2487
        *radius_packet_ptr = NULL;
2150
2488
}
2151
 
 
2152
 
/*************************************************************************
2153
 
 *
2154
 
 *      Function: make_secret
2155
 
 *
2156
 
 *      Purpose: Build an encrypted secret value to return in a reply
2157
 
 *               packet.  The secret is hidden by xoring with a MD5 digest
2158
 
 *               created from the shared secret and the authentication
2159
 
 *               vector.  We put them into MD5 in the reverse order from
2160
 
 *               that used when encrypting passwords to RADIUS.
2161
 
 *
2162
 
 *************************************************************************/
2163
 
static void make_secret(unsigned char *digest, uint8_t *vector,
2164
 
                        const char *secret, char *value)
2165
 
{
2166
 
        u_char  buffer[256 + AUTH_VECTOR_LEN];
2167
 
        int             secretLen = strlen(secret);
2168
 
        int             i;
2169
 
 
2170
 
        memcpy(buffer, vector, AUTH_VECTOR_LEN );
2171
 
        memcpy(buffer + AUTH_VECTOR_LEN, secret, secretLen );
2172
 
 
2173
 
        librad_md5_calc(digest, buffer, AUTH_VECTOR_LEN + secretLen );
2174
 
        memset(buffer, 0, sizeof(buffer));
2175
 
 
2176
 
        for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
2177
 
                digest[i] ^= value[i];
2178
 
        }
2179
 
}