~ubuntu-branches/ubuntu/dapper/freeradius/dapper-updates

« back to all changes in this revision

Viewing changes to src/lib/radius.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hampson
  • Date: 2004-12-29 20:19:42 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041229201942-uj2e95la965uthc7
Tags: 1.0.1-2
* freeradius-dialupadmin Suggests php4-mysql | php4-pgsql
   Closes: #279419
* Added a two-second pause to restart in init.d script
   Closes: #262635
* FreeRADIUS module packages now depend on the same source
  version of the main FreeRADIUS package.
   Closes: #284353
* FreeRADIUS-dialupadmin's default paths in admin.conf are
  now correct.
   Closes: #280942
* FreeRADIUS-dialupadmin's help.php3 can now find README.
   Closes: #280941
* Fixes stolen from 1.0.2 CVS:
  - Bug fix to make udpfromto code work
  - radrelay shouldn't dump core if it can't read a VP from the
    detail file.
  - Only initialize the random pool once.
  - In rlm_sql, don't escape characters twice.
  - In rlm_ldap, only claim Auth-Type if a plain text password is present.
  - Locking fixes in threading code
  - Fix building on gcc-4.0 by not trying to access static auth_port from
    other files.

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.99.2.5 2003/11/20 17:47:09 aland Exp $
 
4
 * Version:     $Id: radius.c,v 1.125.2.1 2004/08/30 17:48:31 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
17
17
 *   License along with this library; if not, write to the Free Software
18
18
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19
19
 *
20
 
 * Copyright 2000  The FreeRADIUS server project
 
20
 * Copyright 2000-2003  The FreeRADIUS server project
21
21
 */
22
22
 
23
 
static const char rcsid[] = "$Id: radius.c,v 1.99.2.5 2003/11/20 17:47:09 aland Exp $";
 
23
static const char rcsid[] = "$Id: radius.c,v 1.125.2.1 2004/08/30 17:48:31 aland Exp $";
24
24
 
25
25
#include        "autoconf.h"
26
26
#include        "md5.h"
27
27
 
28
28
#include        <stdlib.h>
29
29
 
30
 
#if HAVE_UNISTD_H
 
30
#ifdef HAVE_UNISTD_H
31
31
#include        <unistd.h>
32
32
#endif
33
33
 
36
36
#include        <ctype.h>
37
37
 
38
38
#include        "libradius.h"
 
39
#ifdef WITH_UDPFROMTO
 
40
#include        "udpfromto.h"
 
41
#endif
39
42
 
40
 
#if HAVE_NETINET_IN_H
 
43
#ifdef HAVE_NETINET_IN_H
41
44
#include        <netinet/in.h>
42
45
#endif
43
46
 
44
47
#include        <sys/socket.h>
45
48
 
46
 
#if HAVE_ARPA_INET_H
 
49
#ifdef HAVE_ARPA_INET_H
47
50
#include        <arpa/inet.h>
48
51
#endif
49
52
 
50
 
#if HAVE_MALLOC_H
 
53
#ifdef HAVE_MALLOC_H
51
54
#include        <malloc.h>
52
55
#endif
53
56
 
158
161
        const char              *what;
159
162
        uint8_t                 ip_buffer[16];
160
163
 
 
164
        /*
 
165
         *      Maybe it's a fake packet.  Don't send it.
 
166
         */
 
167
        if (!packet || (packet->sockfd < 0)) {
 
168
                return 0;
 
169
        }
 
170
 
161
171
        if ((packet->code > 0) && (packet->code < 52)) {
162
172
                what = packet_codes[packet->code];
163
173
        } else {
184
194
                   *    RADIUS packet size, by one attribute.
185
195
                   */
186
196
                  uint8_t               data[MAX_PACKET_LEN + 256];
187
 
                  
 
197
 
188
198
                  /*
189
199
                   *    Use memory on the stack, until we know how
190
200
                   *    large the packet will be.
196
206
                   */
197
207
                  hdr->code = packet->code;
198
208
                  hdr->id = packet->id;
199
 
                  if ((packet->code == PW_ACCOUNTING_REQUEST) ||
200
 
                      (packet->code == PW_DISCONNECT_REQUEST)) {
201
 
                          memset(hdr->vector, 0, AUTH_VECTOR_LEN);
202
 
                  } else {
203
 
                          memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
 
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
 
204
234
                  }
 
235
                  memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
205
236
 
206
237
                  DEBUG("Sending %s of id %d to %s:%d\n",
207
238
                        what, packet->id,
208
239
                        ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
209
240
                        packet->dst_port);
210
 
                  
 
241
 
211
242
                  total_length = AUTH_HDR_LEN;
212
 
                  
 
243
 
213
244
                  /*
214
245
                   *    Load up the configuration values for the user
215
246
                   */
218
249
                  vendorpec = 0;
219
250
                  vsa_length_ptr = NULL;
220
251
 
 
252
                  /*
 
253
                   *    Loop over the reply attributes for the packet.
 
254
                   */
221
255
                  for (reply = packet->vps; reply; reply = reply->next) {
222
256
                          /*
223
257
                           *    Ignore non-wire attributes
241
275
                          }
242
276
 
243
277
                          /*
244
 
                           *    Do stuff for Message-Authenticator
 
278
                           *    Set the Message-Authenticator to the
 
279
                           *    correct length and initial value.
245
280
                           */
246
281
                          if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
247
 
                                  /*
248
 
                                   *  Set it to zero!
249
 
                                   */
250
282
                                  reply->length = AUTH_VECTOR_LEN;
251
283
                                  memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
252
284
                                  msg_auth_offset = total_length;
296
328
                          if ((vendorcode == 0) &&
297
329
                              ((vendorcode = VENDOR(reply->attribute)) != 0)) {
298
330
                                  vendorpec  = dict_vendorpec(vendorcode);
299
 
                                  
 
331
 
300
332
                                  /*
301
333
                                   *    This is a potentially bad error...
302
334
                                   *    we can't find the vendor ID!
329
361
                                  ptr          += 4;
330
362
 
331
363
                                  /*
332
 
                                   *    Each USR attribute gets it's own
333
 
                                   *    VSA wrapper, so we re-set the
334
 
                                   *    vendor specific information.
 
364
                                   *    Each USR-style attribute gets
 
365
                                   *    it's own VSA wrapper, so we
 
366
                                   *    re-set the vendor specific
 
367
                                   *    information.
335
368
                                   */
336
369
                                  vendorcode = 0;
337
370
                                  vendorpec = 0;
342
375
                                   *    All other attributes are as
343
376
                                   *    per the RFC spec.
344
377
                                   */
345
 
 
346
378
                                  *ptr++ = (reply->attribute & 0xFF);
347
379
                                  length_ptr = ptr;
348
380
                                  if (vsa_length_ptr) *vsa_length_ptr += 2;
349
381
                                  *ptr++ = 2;
350
382
                                  total_length += 2;
351
383
                          }
352
 
                          
 
384
 
353
385
                          switch(reply->type) {
354
 
                                  
 
386
 
355
387
                                  /*
356
388
                                   *    Ascend binary attributes are
357
389
                                   *    stored internally in binary form.
358
390
                                   */
 
391
                          case PW_TYPE_IFID:
 
392
                          case PW_TYPE_IPV6ADDR:
 
393
                          case PW_TYPE_IPV6PREFIX:
359
394
                          case PW_TYPE_ABINARY:
360
395
                          case PW_TYPE_STRING:
361
396
                          case PW_TYPE_OCTETS:
362
397
                                  /*
363
 
                                   *  FIXME: HACK for non-updated dictionaries.
364
 
                                   *  REMOVE in a future release.
365
 
                                   */
366
 
                                  if ((strcmp(reply->name, "Ascend-Send-Secret") == 0) ||
367
 
                                      (strcmp(reply->name, "Ascend-Receive-Secret") == 0)) {
368
 
                                          reply->flags.encrypt = FLAG_ENCRYPT_ASCEND_SECRET;
369
 
                                  }
370
 
                                  if (reply->attribute == PW_USER_PASSWORD) {
371
 
                                          reply->flags.encrypt = FLAG_ENCRYPT_USER_PASSWORD;
372
 
                                  }
373
 
 
374
 
                                  /*
375
398
                                   *  Encrypt the various password styles
376
399
                                   */
377
400
                                  switch (reply->flags.encrypt) {
386
409
                                    break;
387
410
 
388
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
                                          }
389
416
                                          rad_tunnel_pwencode(reply->strvalue,
390
417
                                                              &(reply->length),
391
418
                                                              secret,
392
 
                                                              packet->vector);
 
419
                                                              original->vector);
393
420
                                          break;
394
421
 
395
422
 
398
425
                                                      secret, reply->strvalue);
399
426
                                          memcpy(reply->strvalue, digest, AUTH_VECTOR_LEN );
400
427
                                          reply->length = AUTH_VECTOR_LEN;
 
428
                                          break;
401
429
                                  } /* switch over encryption flags */
402
430
 
403
431
                                  len = reply->length;
426
454
                                                  *ptr++ = 0x00;
427
455
                                          } /* else don't write a tag */
428
456
                                  } /* else the attribute doesn't have a tag */
429
 
                                 
 
457
 
430
458
                                  /*
431
459
                                   *    Ensure we don't go too far.
432
460
                                   *    The 'length' of the attribute
440
468
                                  } else {
441
469
                                          allowed -= *length_ptr;
442
470
                                  }
443
 
                                  
 
471
 
444
472
                                  if (len > allowed) {
445
473
                                          len = allowed;
446
474
                                  }
447
 
                                  
 
475
 
448
476
                                  *length_ptr += len;
449
477
                                  if (vsa_length_ptr) *vsa_length_ptr += len;
450
478
                                  /*
457
485
                                  ptr += reply->length;
458
486
                                  total_length += len;
459
487
                                  break;
460
 
                                  
 
488
 
461
489
                          case PW_TYPE_INTEGER:
462
490
                          case PW_TYPE_IPADDR:
463
491
                                  *length_ptr += 4;
531
559
                   *    and put it in the vector.
532
560
                   */
533
561
                  secretlen = strlen(secret);
534
 
                  if (packet->code != PW_AUTHENTICATION_REQUEST &&
535
 
                      packet->code != PW_STATUS_SERVER) {
536
 
                    MD5_CTX     context;
537
 
                      /*
538
 
                       *        Set the Message-Authenticator attribute,
539
 
                       *        BEFORE setting the reply authentication vector
540
 
                       *        for CHALLENGE, ACCEPT and REJECT.
541
 
                       */
542
 
                      if (msg_auth_offset) {
543
 
                              uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
544
 
 
545
 
                              switch (packet->code) {
546
 
                              default:
547
 
                                break;
548
 
                                
549
 
                              case PW_AUTHENTICATION_ACK:
550
 
                              case PW_AUTHENTICATION_REJECT:
551
 
                              case PW_ACCESS_CHALLENGE:
552
 
                                if (original) {
553
 
                                  memcpy(hdr->vector, original->vector, AUTH_VECTOR_LEN);
554
 
                                }
555
 
                                break;
556
 
                              }
557
 
 
558
 
                              memset(packet->data + msg_auth_offset + 2, 0,
559
 
                                     AUTH_VECTOR_LEN);
560
 
                              lrad_hmac_md5(packet->data, packet->data_len,
561
 
                                            secret, secretlen, calc_auth_vector);
562
 
                              memcpy(packet->data + msg_auth_offset + 2,
563
 
                                     calc_auth_vector, AUTH_VECTOR_LEN);
564
 
                              memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
565
 
                      }
566
 
 
567
 
                      MD5Init(&context);
568
 
                      MD5Update(&context, packet->data, packet->data_len);
569
 
                      MD5Update(&context, secret, strlen(secret));
570
 
                      MD5Final(digest, &context);
571
 
 
572
 
                      memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
573
 
                      memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
574
 
                  }
575
562
 
576
563
                  /*
577
 
                   *    Set the Message-Authenticator attribute,
578
 
                   *    AFTER setting the authentication vector
579
 
                   *    only for ACCESS-REQUESTS
 
564
                   *    If there's a Message-Authenticator, update it
 
565
                   *    now, BEFORE updating the authentication vector.
580
566
                   */
581
 
                  else if (msg_auth_offset) {
 
567
                  if (msg_auth_offset) {
582
568
                          uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
583
569
 
584
570
                          switch (packet->code) {
585
571
                          default:
586
 
                            break;
587
 
                            
 
572
                                  break;
 
573
 
588
574
                          case PW_AUTHENTICATION_ACK:
589
575
                          case PW_AUTHENTICATION_REJECT:
590
576
                          case PW_ACCESS_CHALLENGE:
591
 
                            if (original) {
592
 
                                    memcpy(hdr->vector, original->vector,
593
 
                                           AUTH_VECTOR_LEN);
594
 
                            }
595
 
                            break;
 
577
                                  /* this was checked above */
 
578
                                  memcpy(hdr->vector, original->vector,
 
579
                                         AUTH_VECTOR_LEN);
 
580
                                  break;
596
581
                          }
597
582
 
 
583
                          /*
 
584
                           *    Set the authentication vector to zero,
 
585
                           *    calculate the signature, and put it
 
586
                           *    into the Message-Authenticator
 
587
                           *    attribute.
 
588
                           */
598
589
                          memset(packet->data + msg_auth_offset + 2,
599
590
                                 0, AUTH_VECTOR_LEN);
600
591
                          lrad_hmac_md5(packet->data, packet->data_len,
601
592
                                        secret, secretlen, calc_auth_vector);
602
593
                          memcpy(packet->data + msg_auth_offset + 2,
603
 
                                  calc_auth_vector, AUTH_VECTOR_LEN);
 
594
                                 calc_auth_vector, AUTH_VECTOR_LEN);
 
595
 
 
596
                          /*
 
597
                           *    Copy the original request vector back
 
598
                           *    to the raw packet.
 
599
                           */
604
600
                          memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
605
601
                  }
606
602
 
607
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
                  /*
608
636
                   *    If packet->data points to data, then we print out
609
637
                   *    the VP list again only for debugging.
610
638
                   */
612
640
                DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
613
641
                      ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
614
642
                      packet->dst_port);
615
 
                
 
643
 
616
644
                for (reply = packet->vps; reply; reply = reply->next) {
617
645
                        /* FIXME: ignore attributes > 0xff */
618
646
                        debug_pair(reply);
619
647
                }
620
648
        }
621
 
        
 
649
 
622
650
        /*
623
651
         *      And send it on it's way.
624
652
         */
627
655
        sa->sin_family = AF_INET;
628
656
        sa->sin_addr.s_addr = packet->dst_ipaddr;
629
657
        sa->sin_port = htons(packet->dst_port);
630
 
 
 
658
#ifndef WITH_UDPFROMTO
631
659
        return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
632
660
                      (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
 
661
#else
 
662
        {
 
663
                struct sockaddr_in salocal;
 
664
                memset ((char *) &salocal, '\0', sizeof (salocal));
 
665
                salocal.sin_family = AF_INET;
 
666
                salocal.sin_addr.s_addr = packet->src_ipaddr;
 
667
                
 
668
                return sendfromto(packet->sockfd, packet->data, (int)packet->data_len, 0,
 
669
                                  (struct sockaddr *)&salocal,  sizeof(struct sockaddr_in),
 
670
                                  (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
 
671
        }
 
672
#endif
633
673
}
634
674
 
635
675
 
659
699
         *      as the original MD5 sum (packet->vector).
660
700
         */
661
701
        memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
662
 
        
 
702
 
663
703
        /*
664
704
         *  MD5(packet + secret);
665
705
         */
730
770
        struct sockaddr_in      saremote;
731
771
        int                     totallen;
732
772
        socklen_t               salen;
733
 
        u_short                 len;
734
773
        uint8_t                 *attr;
735
 
        uint8_t                 *vendorattr;
736
774
        int                     count;
737
775
        radius_packet_t         *hdr;
738
776
        char                    host_ipaddr[16];
739
777
        int                     seen_eap;
740
778
        uint8_t                 data[MAX_PACKET_LEN];
741
779
        int                     num_attributes;
742
 
        uint32_t                vendorcode;
743
 
        int                     vendorlen;
744
 
        
 
780
 
745
781
        /*
746
782
         *      Allocate the new request data structure
747
783
         */
748
784
        if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
749
785
                librad_log("out of memory");
750
 
                errno = ENOMEM;
751
786
                return NULL;
752
787
        }
753
788
        memset(packet, 0, sizeof(RADIUS_PACKET));
757
792
         */
758
793
        salen = sizeof(saremote);
759
794
        memset(&saremote, 0, sizeof(saremote));
 
795
#ifndef WITH_UDPFROMTO
760
796
        packet->data_len = recvfrom(fd, data, sizeof(data),
761
 
                0, (struct sockaddr *)&saremote, &salen);
 
797
                                    0, (struct sockaddr *)&saremote, &salen);
 
798
        packet->dst_ipaddr = htonl(INADDR_ANY); /* i.e. unknown */
 
799
#else
 
800
        {
 
801
                socklen_t               salen_local;
 
802
                struct sockaddr_in      salocal;
 
803
                salen_local = sizeof(salocal);
 
804
                memset(&salocal, 0, sizeof(salocal));
 
805
                packet->data_len = recvfromto(fd, data, sizeof(data), 0,
 
806
                                              (struct sockaddr *)&saremote, &salen,
 
807
                                              (struct sockaddr *)&salocal, &salen_local);
 
808
                packet->dst_ipaddr = salocal.sin_addr.s_addr;
 
809
        }
 
810
#endif
762
811
 
763
812
        /*
764
813
         *      Check for socket errors.
821
870
         *      i.e. We've received 128 bytes, and the packet header
822
871
         *      says it's 256 bytes long.
823
872
         */
 
873
        totallen = (data[2] << 8) | data[3];
824
874
        hdr = (radius_packet_t *)data;
825
 
        memcpy(&len, hdr->length, sizeof(u_short));
826
 
        totallen = ntohs(len);
827
875
 
828
876
        /*
829
877
         *      Code of 0 is not understood.
930
978
                        free(packet);
931
979
                        return NULL;
932
980
                }
933
 
                
 
981
 
934
982
                /*
935
983
                 *      Attributes are at LEAST as long as the ID & length
936
984
                 *      fields.  Anything shorter is an invalid attribute.
964
1012
                        }
965
1013
                        seen_eap |= PW_MESSAGE_AUTHENTICATOR;
966
1014
                        break;
967
 
                        
 
1015
 
968
1016
                case PW_VENDOR_SPECIFIC:
969
 
                        if (attr[1] < 6) {
 
1017
                        if (attr[1] <= 6) {
970
1018
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
971
1019
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr),
972
1020
                                           attr[1] - 2);
973
1021
                                free(packet);
974
1022
                                return NULL;
975
1023
                        }
976
 
                        memcpy(&vendorcode, attr + 2, 4);
977
 
                        vendorcode = ntohl(vendorcode);
978
 
                        if (vendorcode == VENDORPEC_USR) {
979
 
                                if (attr[1] < 8){
980
 
                                        librad_log("WARNING: Malformed RADIUS packet from host %s: USR attribute has invalid length %d",
981
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr),
982
 
                                           attr[1] - 2);
983
 
                                        free(packet);
984
 
                                        return NULL;
985
 
                                }
986
 
                                break;
987
 
                        }
988
 
                        vendorlen = attr[1] - 6;
989
 
                        vendorattr = attr + 6;
990
 
                        while (vendorlen >= 2) {
991
 
                                if (vendorattr[1] < 2){
992
 
                                        librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor specific attribute has invalid length %d",
993
 
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr),
994
 
                                           vendorattr[1] - 2);
995
 
                                        free(packet);
996
 
                                        return NULL;
997
 
                                }
998
 
                                vendorlen -= vendorattr[1];
999
 
                                vendorattr += vendorattr[1];
1000
 
                        }
1001
 
                        if (vendorlen != 0){
1002
 
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor specific attributes do not exactly fill Vendor-Specific",
 
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",
1003
1031
                                           ip_ntoa(host_ipaddr, packet->src_ipaddr));
1004
1032
                                free(packet);
1005
1033
                                return NULL;
1006
1034
                        }
 
1035
 
 
1036
                        /*
 
1037
                         *      Don't look at the contents of VSA's,
 
1038
                         *      too many vendors have non-standard
 
1039
                         *      formats.
 
1040
                         */
1007
1041
                        break;
1008
1042
                }
1009
1043
 
1044
1078
                return NULL;
1045
1079
        }
1046
1080
 
 
1081
        /*
 
1082
         *      http://www.freeradius.org/rfc/rfc2869.html#EAP-Message
 
1083
         *
 
1084
         *      A packet with an EAP-Message attribute MUST also have
 
1085
         *      a Message-Authenticator attribute.
 
1086
         *
 
1087
         *      A Message-Authenticator all by itself is OK, though.
 
1088
         */
 
1089
        if (seen_eap &&
 
1090
            (seen_eap != PW_MESSAGE_AUTHENTICATOR) &&
 
1091
            (seen_eap != (PW_EAP_MESSAGE | PW_MESSAGE_AUTHENTICATOR))) {
 
1092
                librad_log("WARNING: Insecure packet from host %s:  Received EAP-Message with no Message-Authenticator.",
 
1093
                           ip_ntoa(host_ipaddr, packet->src_ipaddr));
 
1094
                free(packet);
 
1095
                return NULL;
 
1096
        }
 
1097
 
1047
1098
        if (librad_debug) {
1048
1099
                if ((hdr->code > 0) && (hdr->code < 52)) {
1049
1100
                        printf("rad_recv: %s packet from host %s:%d",
1050
1101
                               packet_codes[hdr->code],
1051
1102
                               ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
1052
1103
                } else {
1053
 
                        printf("rad_recv: Packet from host %s:%d code=%d",      
 
1104
                        printf("rad_recv: Packet from host %s:%d code=%d",
1054
1105
                               ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
1055
1106
                               hdr->code);
1056
1107
                }
1085
1136
int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
1086
1137
               const char *secret)
1087
1138
{
1088
 
        DICT_ATTR               *attr;
1089
1139
        uint32_t                lvalue;
1090
1140
        uint32_t                vendorcode;
1091
1141
        VALUE_PAIR              **tail;
1130
1180
                        case PW_AUTHENTICATION_ACK:
1131
1181
                        case PW_AUTHENTICATION_REJECT:
1132
1182
                        case PW_ACCESS_CHALLENGE:
1133
 
                          if (original) {
1134
 
                                  memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
 
1183
                          if (!original) {
 
1184
                                  librad_log("ERROR: Cannot validate Message-Authenticator in response packet without a request packet.");
 
1185
                                  return -1;
1135
1186
                          }
 
1187
                          memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
1136
1188
                          break;
1137
1189
                        }
1138
1190
 
1143
1195
                                char buffer[32];
1144
1196
                                librad_log("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
1145
1197
                                           ip_ntoa(buffer, packet->src_ipaddr));
1146
 
                                return 1;
 
1198
                                return -1;
1147
1199
                        } /* else the message authenticator was good */
1148
1200
 
1149
1201
                        /*
1179
1231
                                librad_log("Received Accounting-Request packet "
1180
1232
                                    "from %s with invalid signature!  (Shared secret is incorrect.)",
1181
1233
                                    ip_ntoa(buffer, packet->src_ipaddr));
1182
 
                                return 1;
 
1234
                                return -1;
1183
1235
                        }
1184
1236
                        break;
1185
1237
 
1191
1243
                        if (rcode > 1) {
1192
1244
                                char buffer[32];
1193
1245
                                librad_log("Received %s packet "
1194
 
                                           "from %s with invalid signature (err=%d)!  (Shared secret is incorrect.)",
 
1246
                                           "from %s:%d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
1195
1247
                                           packet_codes[packet->code],
1196
1248
                                           ip_ntoa(buffer, packet->src_ipaddr),
 
1249
                                           packet->src_port,
1197
1250
                                           rcode);
1198
 
                                return 1;
 
1251
                                return -1;
1199
1252
                        }
1200
1253
                  break;
1201
1254
        }
1205
1258
         */
1206
1259
        ptr = hdr->data;
1207
1260
        length = packet->data_len - AUTH_HDR_LEN;
1208
 
        packet->vps = NULL;
1209
 
        tail = &packet->vps;
 
1261
 
 
1262
        /*
 
1263
         *      There may be VP's already in the packet.  Don't
 
1264
         *      destroy them.
 
1265
         */
 
1266
        for (tail = &packet->vps; *tail != NULL; tail = &((*tail)->next)) {
 
1267
                /* nothing */
 
1268
        }
1210
1269
 
1211
1270
        vendorcode = 0;
1212
1271
        vendorlen  = 0;
1213
1272
 
1214
 
        while(length > 0) {
 
1273
        while (length > 0) {
1215
1274
                if (vendorlen > 0) {
1216
1275
                        attribute = *ptr++ | (vendorcode << 16);
1217
1276
                        attrlen   = *ptr++;
1225
1284
 
1226
1285
                /*
1227
1286
                 *      This could be a Vendor-Specific attribute.
1228
 
                 *
1229
1287
                 */
1230
1288
                if ((vendorlen <= 0) &&
1231
 
                    (attribute == PW_VENDOR_SPECIFIC) && 
1232
 
                    (attrlen > 6)) {
 
1289
                    (attribute == PW_VENDOR_SPECIFIC)) {
 
1290
                        int     sublen;
 
1291
                        uint8_t *subptr;
 
1292
 
 
1293
                        /*
 
1294
                         *      attrlen was checked to be >= 6, in rad_recv
 
1295
                         */
1233
1296
                        memcpy(&lvalue, ptr, 4);
1234
1297
                        vendorcode = ntohl(lvalue);
1235
 
                        if (vendorcode != 0) {
1236
 
 
1237
 
                                if (vendorcode == VENDORPEC_USR) {
1238
 
                                        ptr += 4;
1239
 
                                        memcpy(&lvalue, ptr, 4);
1240
 
                                        /*printf("received USR %04x\n", ntohl(lvalue));*/
1241
 
                                        attribute = (ntohl(lvalue) & 0xFFFF) |
1242
 
                                                        (vendorcode << 16);
1243
 
                                        ptr += 4;
 
1298
 
 
1299
                        /*
 
1300
                         *      This is an implementation issue.
 
1301
                         *      We currently pack vendor into the upper
 
1302
                         *      16 bits of a 32-bit attribute number,
 
1303
                         *      so we can't handle vendor numbers larger
 
1304
                         *      than 16 bits.
 
1305
                         */
 
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
 
1321
                         */
 
1322
                        subptr = ptr + 4;
 
1323
                        sublen = attrlen - 4;
 
1324
 
 
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
                        /*
 
1339
                         *      If the attribute is RFC compatible,
 
1340
                         *      then allow it as an RFC style VSA.
 
1341
                         */
 
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;
1244
1390
                                        attrlen -= 8;
1245
1391
                                        length -= 8;
1246
 
 
1247
 
                                } else {
1248
 
                                        ptr += 4;
1249
 
                                        vendorlen = attrlen - 4;
1250
 
                                        attribute = *ptr++ | (vendorcode << 16);
1251
 
                                        attrlen   = *ptr++;
1252
 
                                        attrlen -= 2;
1253
 
                                        length -= 6;
1254
 
                                }
1255
 
                        }
1256
 
                        /*
1257
 
                         *  Else the vendor wasn't found...
1258
 
                         */
1259
 
                }
 
1392
                                } /* else it's not in the dictionary */
 
1393
                        } /* else it was a stupid vendor format */
 
1394
                } /* else it wasn't a VSA */
1260
1395
 
1261
1396
                /*
1262
 
                 *      FIXME: should we us paircreate() ?
 
1397
                 *      Create the attribute, setting the default type
 
1398
                 *      to 'octects'.  If the type in the dictionary
 
1399
                 *      is different, then the dictionary type will
 
1400
                 *      over-ride this one.
1263
1401
                 */
1264
 
                if ((pair = malloc(sizeof(VALUE_PAIR))) == NULL) {
 
1402
        create_pair:
 
1403
                if ((pair = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
1265
1404
                        pairfree(&packet->vps);
1266
1405
                        librad_log("out of memory");
1267
 
                        errno = ENOMEM;
1268
1406
                        return -1;
1269
1407
                }
1270
 
                
1271
 
                memset(pair, 0, sizeof(VALUE_PAIR));
1272
 
                if ((attr = dict_attrbyvalue(attribute)) == NULL) {
1273
 
                        snprintf(pair->name, sizeof(pair->name), "Attr-%d", attribute);
1274
 
                        pair->type = PW_TYPE_OCTETS;
1275
 
                } else {
1276
 
                        strcpy(pair->name, attr->name);
1277
 
                        pair->type = attr->type;
1278
 
                        pair->flags = attr->flags;
1279
 
                }
1280
 
                pair->attribute = attribute;
 
1408
 
1281
1409
                pair->length = attrlen;
1282
1410
                pair->operator = T_OP_EQ;
1283
1411
                pair->next = NULL;
1284
 
                
 
1412
 
1285
1413
                switch (pair->type) {
1286
 
                        
1287
 
                case PW_TYPE_OCTETS:
1288
 
                case PW_TYPE_ABINARY:
 
1414
 
 
1415
                        /*
 
1416
                         *      The attribute may be zero length,
 
1417
                         *      or it may have a tag, and then no data...
 
1418
                         */
1289
1419
                case PW_TYPE_STRING:
1290
 
                        if (pair->flags.has_tag &&
1291
 
                            pair->type == PW_TYPE_STRING) {
 
1420
                        if (pair->flags.has_tag) {
1292
1421
                                int offset = 0;
1293
1422
 
1294
 
                                if ((pair->length > 0) && TAG_VALID(*ptr)) {
 
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)) {
1295
1430
                                        pair->flags.tag = *ptr;
1296
1431
                                        pair->length--;
1297
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
                                         */
1298
1440
                                } else if (pair->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
1299
1441
                                        /*
1300
1442
                                         * from RFC2868 - 3.5.  Tunnel-Password
1312
1454
                                }
1313
1455
 
1314
1456
                                /*
1315
 
                                 *      pair->length may be zero here...
 
1457
                                 *      pair->length MAY be zero here.
1316
1458
                                 */
1317
1459
                                memcpy(pair->strvalue, ptr + offset,
1318
1460
                                       pair->length);
1319
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:
1320
1468
                                /* attrlen always < MAX_STRING_LEN */
1321
1469
                                memcpy(pair->strvalue, ptr, attrlen);
1322
1470
                                pair->flags.tag = 0;
1323
1471
                        }
1324
1472
 
1325
1473
                        /*
1326
 
                         *  FIXME: HACK for non-updated dictionaries.
1327
 
                         *  REMOVE in a future release.
1328
 
                         */
1329
 
                        if ((strcmp(pair->name, "Ascend-Send-Secret") == 0) ||
1330
 
                            (strcmp(pair->name, "Ascend-Receive-Secret") == 0)) {
1331
 
                                pair->flags.encrypt = FLAG_ENCRYPT_ASCEND_SECRET;
1332
 
                        }
1333
 
                        if (pair->attribute == PW_USER_PASSWORD) {
1334
 
                                pair->flags.encrypt = FLAG_ENCRYPT_USER_PASSWORD;
1335
 
                        }
1336
 
 
1337
 
                        /*
1338
1474
                         *      Decrypt passwords here.
1339
1475
                         */
1340
1476
                        switch (pair->flags.encrypt) {
1360
1496
                                break;
1361
1497
 
1362
1498
                                /*
1363
 
                                 *  Tunnel-Password
 
1499
                                 *      Tunnel-Password's may go ONLY
 
1500
                                 *      in response packets.
1364
1501
                                 */
1365
1502
                        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
1366
1503
                                if (!original) {
1367
1504
                                        librad_log("ERROR: Tunnel-Password attribute in request: Cannot decrypt it.");
1368
 
                                        return -1;
1369
 
                                }
1370
 
                                rad_tunnel_pwdecode((char *)pair->strvalue,
1371
 
                                                    &pair->length, 
1372
 
                                                    secret,
1373
 
                                                    (char *)original->vector);
 
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
                                }
1374
1515
                                break;
1375
1516
 
1376
1517
                                /*
1378
1519
                                 *  Ascend-Receive-Secret
1379
1520
                                 */
1380
1521
                        case FLAG_ENCRYPT_ASCEND_SECRET:
1381
 
                                {
 
1522
                                if (!original) {
 
1523
                                        librad_log("ERROR: Ascend-Send-Secret attribute in request: Cannot decrypt it.");
 
1524
                                        free(pair);
 
1525
                                        return -1;
 
1526
                                } else {
1382
1527
                                        uint8_t my_digest[AUTH_VECTOR_LEN];
1383
1528
                                        make_secret(my_digest,
1384
1529
                                                    original->vector,
1391
1536
                                break;
1392
1537
                        } /* switch over encryption flags */
1393
1538
                        break;  /* from octets/string/abinary */
1394
 
                        
 
1539
 
1395
1540
                case PW_TYPE_INTEGER:
1396
1541
                case PW_TYPE_DATE:
1397
1542
                case PW_TYPE_IPADDR:
1412
1557
 
1413
1558
                        memcpy(&lvalue, ptr, 4);
1414
1559
 
1415
 
                        if (attr->type != PW_TYPE_IPADDR) {
 
1560
                        if (pair->type != PW_TYPE_IPADDR) {
1416
1561
                                pair->lvalue = ntohl(lvalue);
1417
1562
                        } else {
1418
1563
                                 /*
1426
1571
                        }
1427
1572
 
1428
1573
                        /*
1429
 
                         *  Only PW_TYPE_INTEGER should have tags.
 
1574
                         *      Tagged attributes of type integer have
 
1575
                         *      special treatment.
1430
1576
                         */
1431
1577
                        if (pair->flags.has_tag &&
1432
1578
                            pair->type == PW_TYPE_INTEGER) {
1434
1580
                                pair->lvalue &= 0x00ffffff;
1435
1581
                        }
1436
1582
 
1437
 
                        if (attr->type == PW_TYPE_INTEGER) {
 
1583
                        /*
 
1584
                         *      Try to get the name for integer
 
1585
                         *      attributes.
 
1586
                         */
 
1587
                        if (pair->type == PW_TYPE_INTEGER) {
1438
1588
                                DICT_VALUE *dval;
1439
1589
                                dval = dict_valbyattr(pair->attribute,
1440
1590
                                                      pair->lvalue);
1445
1595
                                }
1446
1596
                        }
1447
1597
                        break;
1448
 
                        
 
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
 
1449
1641
                default:
1450
1642
                        DEBUG("    %s (Unknown Type %d)\n",
1451
 
                              attr->name,attr->type);
 
1643
                              pair->name, pair->type);
1452
1644
                        free(pair);
1453
1645
                        pair = NULL;
1454
1646
                        break;
1455
1647
                }
1456
 
                
 
1648
 
1457
1649
                if (pair) {
1458
1650
                        debug_pair(pair);
1459
1651
                        *tail = pair;
1510
1702
                for (i = len; n > 0; n--, i++)
1511
1703
                        passwd[i] = 0;
1512
1704
                len = *pwlen = i;
 
1705
 
 
1706
        } else if (len == 0) {
 
1707
                memset(passwd, 0, AUTH_PASS_LEN);
 
1708
                *pwlen = len = AUTH_PASS_LEN;
1513
1709
        }
1514
1710
 
1515
1711
        /*
1532
1728
         *      Length > AUTH_PASS_LEN, so we need to use the extended
1533
1729
         *      algorithm.
1534
1730
         */
1535
 
        for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) { 
 
1731
        for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
1536
1732
                memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
1537
1733
                librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1538
1734
                for (i = 0; i < AUTH_PASS_LEN; i++)
1581
1777
         */
1582
1778
        rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
1583
1779
 
1584
 
        for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) { 
 
1780
        for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
1585
1781
                s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
1586
1782
                memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
1587
1783
                librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1604
1800
 *      This is per RFC-2868 which adds a two char SALT to the initial intermediate
1605
1801
 *      value MD5 hash.
1606
1802
 */
1607
 
int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret, const char *vector)
 
1803
int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
 
1804
                        const char *vector)
1608
1805
{
1609
1806
        uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
1610
1807
        unsigned char   digest[AUTH_VECTOR_LEN];
1611
1808
        char*   salt;
1612
1809
        int     i, n, secretlen;
1613
 
        unsigned len;
1614
 
        
 
1810
        unsigned len, n2;
1615
1811
 
1616
 
        
1617
1812
        len = *pwlen;
1618
1813
 
1619
1814
        if (len > 127) len = 127;
1634
1829
        /*
1635
1830
         *      Generate salt.  The RFC's say:
1636
1831
         *
1637
 
         *      high bit of salt[0] must be set.
1638
 
         *      each salt in a packet should be unique.
1639
 
         *      they should be random
 
1832
         *      The high bit of salt[0] must be set, each salt in a
 
1833
         *      packet should be unique, and they should be random
1640
1834
         *
1641
 
         *      So, we set the high bit,
1642
 
         *      add in a counter,
1643
 
         *      and then add in some CSPRNG data.
1644
 
         *      should be OK..
 
1835
         *      So, we set the high bit, add in a counter, and then
 
1836
         *      add in some CSPRNG data.  should be OK..
1645
1837
         */
1646
1838
        salt[0] = (0x80 | ( ((salt_offset++) & 0x0f) << 3) |
1647
1839
                   (lrad_rand() & 0x07));
1648
1840
        salt[1] = lrad_rand();
1649
 
        
 
1841
 
1650
1842
        /*
1651
1843
         *      Padd password to multiple of AUTH_PASS_LEN bytes.
1652
1844
         */
1658
1850
        }
1659
1851
        /* set new password length */
1660
1852
        *pwlen = len + 2;
1661
 
        
 
1853
 
1662
1854
        /*
1663
1855
         *      Use the secret to setup the decryption digest
1664
1856
         */
1665
1857
        secretlen = strlen(secret);
1666
1858
        memcpy(buffer, secret, secretlen);
1667
 
        
1668
 
        for (n = 0; n < len; n+=AUTH_PASS_LEN) {
1669
 
                if (!n) {
 
1859
 
 
1860
        for (n2 = 0; n2 < len; n2+=AUTH_PASS_LEN) {
 
1861
                if (!n2) {
1670
1862
                        memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1671
1863
                        memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
1672
1864
                        librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
1673
 
                }
1674
 
                else {
1675
 
                        memcpy(buffer + secretlen, passwd + n - AUTH_PASS_LEN, AUTH_PASS_LEN);
 
1865
                } else {
 
1866
                        memcpy(buffer + secretlen, passwd + n2 - AUTH_PASS_LEN, AUTH_PASS_LEN);
1676
1867
                        librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
1677
1868
                }
1678
 
                
1679
 
                for (i = 0; i < AUTH_PASS_LEN; i++)
1680
 
                        passwd[i + n] ^= digest[i];
 
1869
 
 
1870
                for (i = 0; i < AUTH_PASS_LEN; i++) {
 
1871
                        passwd[i + n2] ^= digest[i];
 
1872
                }
1681
1873
        }
1682
 
        passwd[n] = 0;
 
1874
        passwd[n2] = 0;
1683
1875
        return 0;
1684
1876
}
1685
1877
 
1686
1878
/*
1687
1879
 *      Decode Tunnel-Password encrypted attributes.
1688
1880
 *
1689
 
 *      Defined in RFC-2868, this adds a two char SALT to the initial intermediate
1690
 
 *      value, to differentiate it from the above.
 
1881
 *      Defined in RFC-2868, this uses a two char SALT along with the
 
1882
 *      initial intermediate value, to differentiate it from the
 
1883
 *      above.
1691
1884
 */
1692
 
 
1693
 
int rad_tunnel_pwdecode(char *passwd, int * pwlen, const char *secret, const char *vector)
 
1885
int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
 
1886
                        const char *vector)
1694
1887
{
1695
 
        uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
1696
 
        unsigned char   digest[AUTH_VECTOR_LEN];
1697
 
        char    salt[2];
1698
 
        int     i, n, ntimes, secretlen;
1699
 
        unsigned len;
1700
 
        
 
1888
        uint8_t         buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
 
1889
        uint8_t         digest[AUTH_VECTOR_LEN];
 
1890
        uint8_t         decrypted[MAX_STRING_LEN + 1];
 
1891
        int             secretlen;
 
1892
        unsigned        i, n, len;
 
1893
 
1701
1894
        len = *pwlen;
1702
1895
 
1703
 
        if(len < 3) {
1704
 
          return len;
1705
 
        }
1706
 
        salt[0] = passwd[0];
1707
 
        salt[1] = passwd[1];
1708
 
 
1709
 
        passwd += 2;
1710
 
        len -= 2;
1711
 
        
 
1896
        /*
 
1897
         *      We need at least a salt.
 
1898
         */
 
1899
        if (len < 2) {
 
1900
                librad_log("tunnel password is too short");
 
1901
                return -1;
 
1902
        }
 
1903
 
 
1904
        /*
 
1905
         *      There's a salt, but no password.  Or, there's a salt
 
1906
         *      and a 'data_len' octet.  It's wrong, but at least we
 
1907
         *      can figure out what it means: the password is empty.
 
1908
         *
 
1909
         *      Note that this means we ignore the 'data_len' field,
 
1910
         *      if the attribute length tells us that there's no
 
1911
         *      more data.  So the 'data_len' field may be wrong,
 
1912
         *      but that's ok...
 
1913
         */
 
1914
        if (len <= 3) {
 
1915
                passwd[0] = 0;
 
1916
                *pwlen = 0;
 
1917
                return 0;
 
1918
        }
 
1919
 
 
1920
        len -= 2;               /* discount the salt */
 
1921
 
1712
1922
        /*
1713
1923
         *      Use the secret to setup the decryption digest
1714
1924
         */
1715
1925
        secretlen = strlen(secret);
 
1926
 
 
1927
        /*
 
1928
         *      Set up the initial key:
 
1929
         *
 
1930
         *       b(1) = MD5(secret + vector + salt)
 
1931
         */
1716
1932
        memcpy(buffer, secret, secretlen);
1717
 
 
1718
 
        ntimes = (len-1)/AUTH_PASS_LEN;
1719
 
        do {
1720
 
                if(!ntimes){
1721
 
                        memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1722
 
                        memcpy(buffer + secretlen + AUTH_VECTOR_LEN, salt, 2);
1723
 
                        librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
1724
 
                }
1725
 
                else {
1726
 
                        memcpy(buffer + secretlen, passwd + AUTH_PASS_LEN * (ntimes - 1), AUTH_PASS_LEN);
1727
 
                        librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
1728
 
                }
1729
 
                for ( i = 0, n = ntimes * AUTH_PASS_LEN; i < AUTH_PASS_LEN && (i + n) < len; i++)
1730
 
                        passwd[i + n] ^= digest[i];
1731
 
        } while(ntimes--);
1732
 
        passwd[len] = '\0';
1733
 
 
1734
 
        if (*(unsigned char*)passwd >= len) {
1735
 
                /* Pasword is broken, original password should be longer */
1736
 
                *pwlen = 2;
1737
 
                passwd[0]=passwd[1]=0;
1738
 
                return 0;
1739
 
        }
1740
 
        len = *pwlen = *passwd; /* restore original length */
1741
 
        for (n=0; n<len; n++) passwd[n-2]=passwd[n+1];
1742
 
        passwd[len-2] = 0;
1743
 
        return len;
 
1933
        memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
 
1934
        memcpy(buffer + secretlen + AUTH_VECTOR_LEN, passwd, 2);
 
1935
        librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
 
1936
 
 
1937
        /*
 
1938
         *      A quick check: decrypt the first octet of the password,
 
1939
         *      which is the 'data_len' field.  Ensure it's sane.
 
1940
         *
 
1941
         *      'n' doesn't include the 'data_len' octet
 
1942
         *      'len' does.
 
1943
         */
 
1944
        n = passwd[2] ^ digest[0];
 
1945
        if (n >= len) {
 
1946
                librad_log("tunnel password is too long for the attribute");
 
1947
                return -1;
 
1948
        }
 
1949
 
 
1950
        /*
 
1951
         *      Loop over the data, decrypting it, and generating
 
1952
         *      the key for the next round of decryption.
 
1953
         */
 
1954
        for (n = 0; n < len; n += AUTH_PASS_LEN) {
 
1955
                for (i = 0; i < AUTH_PASS_LEN; i++) {
 
1956
                        decrypted[n + i] = passwd[n + i + 2] ^ digest[i];
 
1957
 
 
1958
                        /*
 
1959
                         *      Encrypted password may not be aligned
 
1960
                         *      on 16 octets, so we catch that here...
 
1961
                         */
 
1962
                        if ((n + i) == len) break;
 
1963
                }
 
1964
 
 
1965
                /*
 
1966
                 *      Update the digest, based on
 
1967
                 *
 
1968
                 *      b(n) = MD5(secret + cleartext(n-1)
 
1969
                 *
 
1970
                 *      but only if there's more data...
 
1971
                 */
 
1972
                memcpy(buffer + secretlen, passwd + n + 2, AUTH_PASS_LEN);
 
1973
                librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
 
1974
        }
 
1975
 
 
1976
        /*
 
1977
         *      We've already validated the length of the decrypted
 
1978
         *      password.  Copy it back to the caller.
 
1979
         */
 
1980
        memcpy(passwd, decrypted + 1, decrypted[0]);
 
1981
        passwd[decrypted[0]] = 0;
 
1982
        *pwlen = decrypted[0];
 
1983
 
 
1984
        return decrypted[0];
1744
1985
}
1745
1986
 
1746
1987
/*
1791
2032
                i += challenge->length;
1792
2033
        } else {
1793
2034
                memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
1794
 
                i += AUTH_VECTOR_LEN; 
 
2035
                i += AUTH_VECTOR_LEN;
1795
2036
        }
1796
2037
 
1797
2038
        *output = id;
1820
2061
                lrad_rand_pool.randrsl[2] = (uint32_t) vector;
1821
2062
 
1822
2063
                lrad_randinit(&lrad_rand_pool, 1);
 
2064
                lrad_pool_initialized = 1;
1823
2065
        }
1824
2066
 
1825
2067
        lrad_isaac(&lrad_rand_pool);
1884
2126
        memset(rp, 0, sizeof(RADIUS_PACKET));
1885
2127
        if (newvector)
1886
2128
                random_vector(rp->vector);
 
2129
        lrad_rand();
1887
2130
 
1888
2131
        return rp;
1889
2132
}