2bca33ba6654fa1317c854658cf0e59d5f711d2c
[freeradius.git] / src / lib / radius.c
1 /*
2  * radius.c     Functions to send/receive radius packets.
3  *
4  * Version:     $Id$
5  *
6  */
7
8 static const char rcsid[] = "$Id$";
9
10 #include        "autoconf.h"
11 #include        "md5.h"
12
13 #include        <stdlib.h>
14
15 #if HAVE_UNISTD_H
16 #include        <unistd.h>
17 #endif
18
19 #include        <fcntl.h>
20 #include        <string.h>
21 #include        <ctype.h>
22
23 #include        "libradius.h"
24
25 #if HAVE_NETINET_IN_H
26 #include        <netinet/in.h>
27 #endif
28
29 #include        <sys/socket.h>
30
31 #if HAVE_ARPA_INET_H
32 #include        <arpa/inet.h>
33 #endif
34
35 #if HAVE_MALLOC_H
36 #include        <malloc.h>
37 #endif
38
39 #ifdef WIN32
40 #include        <process.h>
41 #endif
42
43 /*
44  *  The RFC says 4096 octets max, and most packets are less than 256.
45  *  However, this number is just larger than the maximum MTU of just
46  *  most types of networks, except maybe for gigabit ethernet.
47  */
48 #define PACKET_DATA_LEN 1600
49
50 /*
51  *      The maximum number of attributes which we allow in an incoming
52  *      request.  If there are more attributes than this, the request
53  *      is rejected.
54  *
55  *      This helps to minimize the potential for a DoS, when an
56  *      attacker spoofs Access-Request packets, which don't have a
57  *      Message-Authenticator attribute.  This means that the packet
58  *      is unsigned, and the attacker can use resources on the server,
59  *      even if the end request is rejected.
60  */
61 int librad_max_attributes = 0;
62
63 typedef struct radius_packet_t {
64   uint8_t       code;
65   uint8_t       id;
66   uint8_t       length[2];
67   uint8_t       vector[16];
68   uint8_t       data[1];
69 } radius_packet_t;
70
71 static uint8_t random_vector_pool[AUTH_VECTOR_LEN*2];
72
73 static const char *packet_codes[] = {
74   "",
75   "Access-Request",
76   "Access-Accept",
77   "Access-Reject",
78   "Accounting-Request",
79   "Accounting-Response",
80   "Accounting-Status",
81   "Password-Request",
82   "Password-Accept",
83   "Password-Reject",
84   "Accounting-Message",
85   "Access-Challenge",
86   "Status-Server",
87   "Status-Client"
88 };
89
90 /*
91  *  Internal prototypes
92  */
93 static void make_secret(unsigned char *digest, uint8_t *vector,
94                         const char *secret, char *value);
95
96 /*
97  *      Reply to the request.  Also attach
98  *      reply attribute value pairs and any user message provided.
99  */
100 int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original, const char *secret)
101 {
102         VALUE_PAIR              *reply;
103         struct  sockaddr_in     saremote;
104         struct  sockaddr_in     *sa;
105         const char              *what;
106         uint8_t                 ip_buffer[16];
107
108         if ((packet->code > 0) && (packet->code < 14)) {
109                 what = packet_codes[packet->code];
110         } else {
111                 what = "Reply";
112         }
113
114         /*
115          *  First time through, allocate room for the packet
116          */
117         if (!packet->data) {
118                   radius_packet_t       *hdr;
119                   int32_t               lvalue;
120                   uint8_t               *ptr, *length_ptr, *vsa_length_ptr;
121                   uint8_t               digest[16];
122                   int                   secretlen;
123                   int                   vendorcode, vendorpec;
124                   u_short               total_length;
125                   int                   len, allowed;
126                   int                   msg_auth_offset = 0;
127                   uint8_t               data[4096];
128                   
129                   /*
130                    *    Use memory on the stack, until we know how
131                    *    large the packet will be.
132                    */
133                   hdr = (radius_packet_t *) data;
134
135                   /*
136                    *    Build standard header
137                    */
138                   hdr->code = packet->code;
139                   hdr->id = packet->id;
140                   if (packet->code == PW_ACCOUNTING_REQUEST) {
141                           memset(hdr->vector, 0, AUTH_VECTOR_LEN);
142                   } else {
143                           memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
144                   }
145
146                   DEBUG("Sending %s of id %d to %s:%d\n",
147                         what, packet->id,
148                         ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
149                         packet->dst_port);
150                   
151                   total_length = AUTH_HDR_LEN;
152                   
153                   /*
154                    *    Load up the configuration values for the user
155                    */
156                   ptr = hdr->data;
157                   vendorcode = 0;
158                   vendorpec = 0;
159                   vsa_length_ptr = NULL;
160
161                   for (reply = packet->vps; reply; reply = reply->next) {
162                           /*
163                            *    Ignore non-wire attributes
164                            */
165                           if ((VENDOR(reply->attribute) == 0) &&
166                               ((reply->attribute & 0xFFFF) > 0xff)) {
167                                   continue;
168                           }
169
170                           /*
171                            *    Do stuff for Message-Authenticator
172                            */
173                           if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
174                                   /*
175                                    *  Set it to zero!
176                                    */
177                                   reply->length = AUTH_VECTOR_LEN;
178                                   memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
179                                   msg_auth_offset = total_length;
180                           }
181
182                           /*
183                            *    We have a different vendor.  Re-set
184                            *    the vendor codes.
185                            */
186                           if (vendorcode != VENDOR(reply->attribute)) {
187                                   vendorcode = 0;
188                                   vendorpec = 0;
189                                   vsa_length_ptr = NULL;
190                           }
191
192                           /*
193                            *    If the Vendor-Specific attribute is getting
194                            *    full, then create a new VSA attribute
195                            *
196                            *    FIXME: Multiple VSA's per Vendor-Specific
197                            *    SHOULD be configurable.  When that's done,
198                            *    the (1), below, can be changed to point to
199                            *    a configuration variable which is set TRUE
200                            *    if the NAS cannot understand multiple VSA's
201                            *    per Vendor-Specific
202                            */
203                           if ((1) || /* ALWAYS create a new Vendor-Specific */
204                               (vsa_length_ptr &&
205                                (reply->length + *vsa_length_ptr) >= MAX_STRING_LEN)) {
206                                   vendorcode = 0;
207                                   vendorpec = 0;
208                                   vsa_length_ptr = NULL;
209                           }
210
211                           /*
212                            *    Maybe we have the start of a set of
213                            *    (possibly many) VSA attributes from
214                            *    one vendor.  Set a global VSA wrapper
215                            */
216                           if ((vendorcode == 0) &&
217                               ((vendorcode = VENDOR(reply->attribute)) != 0)) {
218                                   vendorpec  = dict_vendorpec(vendorcode);
219                                   
220                                   /*
221                                    *    This is a potentially bad error...
222                                    *    we can't find the vendor ID!
223                                    */
224                                   if (vendorpec == 0) {
225                                           /* FIXME: log an error */
226                                           continue;
227                                   }
228
229                                   /*
230                                    *    Build a VSA header.
231                                    */
232                                   *ptr++ = PW_VENDOR_SPECIFIC;
233                                   vsa_length_ptr = ptr;
234                                   *ptr++ = 6;
235                                   lvalue = htonl(vendorpec);
236                                   memcpy(ptr, &lvalue, 4);
237                                   ptr += 4;
238                                   total_length += 6;
239                           }
240
241                           if (vendorpec == VENDORPEC_USR) {
242                                   lvalue = htonl(reply->attribute & 0xFFFF);
243                                   memcpy(ptr, &lvalue, 4);
244
245                                   length_ptr = vsa_length_ptr;
246
247                                   total_length += 4;
248                                   *length_ptr  += 4;
249                                   ptr          += 4;
250
251                                   /*
252                                    *    Each USR attribute gets it's own
253                                    *    VSA wrapper, so we re-set the
254                                    *    vendor specific information.
255                                    */
256                                   vendorcode = 0;
257                                   vendorpec = 0;
258                                   vsa_length_ptr = NULL;
259
260                           } else {
261                                   /*
262                                    *    All other attributes are as
263                                    *    per the RFC spec.
264                                    */
265
266                                   *ptr++ = (reply->attribute & 0xFF);
267                                   length_ptr = ptr;
268                                   if (vsa_length_ptr) *vsa_length_ptr += 2;
269                                   *ptr++ = 2;
270                                   total_length += 2;
271                           }
272                           
273                           switch(reply->type) {
274                                   
275                                   /*
276                                    *    Ascend binary attributes are
277                                    *    stored internally in binary form.
278                                    */
279                           case PW_TYPE_ABINARY:
280                           case PW_TYPE_STRING:
281                           case PW_TYPE_OCTETS:
282                                   /*
283                                    *  Hmm... this is based on names
284                                    *  right now.  We really shouldn't do
285                                    *  this.  It should be based on the value
286                                    *  of the attribute (VSA or not).
287                                    */
288                                   if ((strcmp(reply->name, "Ascend-Send-Secret") == 0) ||
289                                       (strcmp(reply->name, "Ascend-Receive-Secret") == 0)) {
290                                           make_secret(digest, packet->vector,
291                                                       secret, reply->strvalue);
292                                           memcpy(reply->strvalue, digest, AUTH_VECTOR_LEN );
293                                           reply->length = AUTH_VECTOR_LEN;
294                                   }
295                                   len = reply->length;
296                                   
297                                   /*
298                                    *    Ensure we don't go too far.
299                                    *    The 'length' of the attribute
300                                    *    may be 0..255, minus whatever
301                                    *    octets are used in the attribute
302                                    *    header.
303                                    */
304                                   allowed = 255;
305                                   if (vsa_length_ptr) {
306                                           allowed -= *vsa_length_ptr;
307                                   } else {
308                                           allowed -= *length_ptr;
309                                   }
310                                   
311                                   if (len > allowed) {
312                                           len = allowed;
313                                   }
314                                   
315                                   *length_ptr += len;
316                                   if (vsa_length_ptr) *vsa_length_ptr += len;
317                                   memcpy(ptr, reply->strvalue,len);
318                                   ptr += len;
319                                   total_length += len;
320                                   break;
321                                   
322                           case PW_TYPE_INTEGER:
323                           case PW_TYPE_IPADDR:
324                                   *length_ptr += 4;
325                                   if (vsa_length_ptr) *vsa_length_ptr += 4;
326                                   if (reply->type != PW_TYPE_IPADDR)
327                                           lvalue = htonl(reply->lvalue);
328                                   else
329                                           lvalue = reply->lvalue;
330                                   memcpy(ptr, &lvalue, 4);
331                                   ptr += 4;
332                                   total_length += 4;
333                                   break;
334
335                           default:
336                                   break;
337                           }
338                           
339                           /*
340                            *    Print out ONLY the attributes which
341                            *    we're sending over the wire.  Also,
342                            *    pick up any hacked password
343                            *    attributes.
344                            */
345                           debug_pair(reply);
346                   } /* done looping over all attributes */
347
348                   /*
349                    *    Fill in the rest of the fields, and copy
350                    *    the data over from the local stack to
351                    *    the newly allocated memory.
352                    *
353                    *    Yes, all this 'memcpy' is slow, but it means
354                    *    that we only allocate the minimum amount of
355                    *    memory for a request.
356                    */
357                   packet->data_len = total_length;
358                   packet->data = (uint8_t *) malloc(packet->data_len);
359                   if (!packet->data) {
360                           librad_log("Out of memory");
361                           return -1;
362                   }
363                   memcpy(packet->data, data, packet->data_len);
364                   hdr = (radius_packet_t *) packet->data;
365
366                   total_length = htons(total_length);
367                   memcpy(hdr->length, &total_length, sizeof(u_short));
368
369                   /*
370                    *    If this is not an authentication request, we
371                    *    need to calculate the md5 hash over the entire packet
372                    *    and put it in the vector.
373                    */
374                   secretlen = strlen(secret);
375                   if (packet->code != PW_AUTHENTICATION_REQUEST &&
376                       packet->code != PW_STATUS_SERVER) {
377                     MD5_CTX     context;
378                       /*
379                        *        Set the Message-Authenticator attribute,
380                        *        BEFORE setting the reply authentication vector
381                        *        for CHALLENGE, ACCEPT and REJECT.
382                        */
383                       if (msg_auth_offset) {
384                               uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
385
386                               switch (packet->code) {
387                               default:
388                                 break;
389                                 
390                               case PW_AUTHENTICATION_ACK:
391                               case PW_AUTHENTICATION_REJECT:
392                               case PW_ACCESS_CHALLENGE:
393                                 if (original) {
394                                   memcpy(hdr->vector, original->vector, AUTH_VECTOR_LEN);
395                                 }
396                                 break;
397                               }
398
399                               memset(packet->data + msg_auth_offset + 2, 0,
400                                      AUTH_VECTOR_LEN);
401                               lrad_hmac_md5(packet->data, packet->data_len,
402                                             secret, secretlen, calc_auth_vector);
403                               memcpy(packet->data + msg_auth_offset + 2,
404                                      calc_auth_vector, AUTH_VECTOR_LEN);
405                               memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
406                       }
407
408                       MD5Init(&context);
409                       MD5Update(&context, packet->data, packet->data_len);
410                       MD5Update(&context, secret, strlen(secret));
411                       MD5Final(digest, &context);
412
413                       memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
414                       memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
415                   }
416
417                   /*
418                    *    Set the Message-Authenticator attribute,
419                    *    AFTER setting the authentication vector
420                    *    only for ACCESS-REQUESTS
421                    */
422                   else if (msg_auth_offset) {
423                           uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
424
425                           switch (packet->code) {
426                           default:
427                             break;
428                             
429                           case PW_AUTHENTICATION_ACK:
430                           case PW_AUTHENTICATION_REJECT:
431                           case PW_ACCESS_CHALLENGE:
432                             if (original) {
433                               memcpy(hdr->vector, original->vector, AUTH_VECTOR_LEN);
434                             }
435                             break;
436                           }
437
438                           memset(packet->data + msg_auth_offset + 2,
439                                  0, AUTH_VECTOR_LEN);
440                           lrad_hmac_md5(packet->data, packet->data_len,
441                                         secret, secretlen, calc_auth_vector);
442                           memcpy(packet->data + msg_auth_offset + 2,
443                                   calc_auth_vector, AUTH_VECTOR_LEN);
444                           memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
445                   }
446
447                   /*
448                    *    If packet->data points to data, then we print out
449                    *    the VP list again only for debugging.
450                    */
451         } else if (librad_debug) {
452                 DEBUG("Sending %s of id %d to %s\n", what, packet->id,
453                       ip_ntoa((char *)ip_buffer, packet->dst_ipaddr));
454                 
455                 for (reply = packet->vps; reply; reply = reply->next) {
456                         /* FIXME: ignore attributes > 0xff */
457                         debug_pair(reply);
458                 }
459         }
460         
461         /*
462          *      And send it on it's way.
463          */
464         sa = (struct sockaddr_in *) &saremote;
465         memset ((char *) sa, '\0', sizeof (saremote));
466         sa->sin_family = AF_INET;
467         sa->sin_addr.s_addr = packet->dst_ipaddr;
468         sa->sin_port = htons(packet->dst_port);
469
470         return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
471                       &saremote, sizeof(struct sockaddr_in));
472 }
473
474
475 /*
476  *      Validates the requesting client NAS.  Calculates the
477  *      signature based on the clients private key.
478  */
479 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
480 {
481         u_char          digest[AUTH_VECTOR_LEN];
482         MD5_CTX context;
483
484         /*
485          *      Older clients have the authentication vector set to
486          *      all zeros. Return `1' in that case.
487          */
488         memset(digest, 0, sizeof(digest));
489         if (memcmp(packet->vector, digest, AUTH_VECTOR_LEN) == 0) {
490                 packet->verified = 1;
491                 return 1;
492         }
493
494         /*
495          *      Zero out the auth_vector in the received packet.
496          *      Then append the shared secret to the received packet,
497          *      and calculate the MD5 sum. This must be the same
498          *      as the original MD5 sum (packet->vector).
499          */
500         memset(packet->data + 4, 0, AUTH_VECTOR_LEN);
501         
502         /*
503          *  MD5(packet + secret);
504          */
505         MD5Init(&context);
506         MD5Update(&context, packet->data, packet->data_len);
507         MD5Update(&context, secret, strlen(secret));
508         MD5Final(digest, &context);
509
510         /*
511          *      Return 0 if OK, 2 if not OK.
512          */
513         packet->verified =
514         memcmp(digest, packet->vector, AUTH_VECTOR_LEN) ? 2 : 0;
515
516         return packet->verified;
517 }
518
519 /*
520  *      Validates the requesting client NAS.  Calculates the
521  *      signature based on the clients private key.
522  */
523 static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret)
524 {
525         uint8_t         calc_digest[AUTH_VECTOR_LEN];
526         MD5_CTX         context;
527
528         /*
529          *  Copy the original vector in place.
530          */
531         memcpy(packet->data + 4, original->vector, sizeof(original->vector));
532
533         /*
534          *  MD5(packet + secret);
535          */
536         MD5Init(&context);
537         MD5Update(&context, packet->data, packet->data_len);
538         MD5Update(&context, secret, strlen(secret));
539         MD5Final(calc_digest, &context);
540
541         /*
542          *  Copy the packet's vector back to the packet.
543          */
544         memcpy(packet->data + 4, packet->vector, sizeof(packet->vector));
545
546         /*
547          *      Return 0 if OK, 2 if not OK.
548          */
549         packet->verified =
550                 memcmp(packet->vector, calc_digest, sizeof(packet->vector)) ? 2 : 0;
551         return packet->verified;
552 }
553
554 /*
555  *      Receive UDP client requests, and fill in
556  *      the basics of a RADIUS_PACKET structure.
557  */
558 RADIUS_PACKET *rad_recv(int fd)
559 {
560         RADIUS_PACKET           *packet;
561         struct sockaddr_in      saremote;
562         int                     totallen;
563         socklen_t               salen;
564         u_short                 len;
565         uint8_t                 *attr;
566         int                     count;
567         radius_packet_t         *hdr;
568         char                    host_ipaddr[16];
569         int                     seen_eap;
570         uint8_t                 data[4096];
571         int                     num_attributes;
572
573         /*
574          *      Allocate the new request data structure
575          */
576         if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
577                 librad_log("out of memory");
578                 errno = ENOMEM;
579                 return NULL;
580         }
581         memset(packet, 0, sizeof(RADIUS_PACKET));
582
583         /*
584          *      Receive the packet.
585          */
586         salen = sizeof(saremote);
587         memset(&saremote, 0, sizeof(saremote));
588         packet->data_len = recvfrom(fd, data, sizeof(data),
589                 0, (struct sockaddr *)&saremote, &salen);
590
591         /*
592          *      Fill IP header fields.  We need these for the error
593          *      messages which may come later.
594          */
595         packet->sockfd = fd;
596         packet->src_ipaddr = saremote.sin_addr.s_addr;
597         packet->src_port = ntohs(saremote.sin_port);
598
599         /*
600          *      Explicitely set the VP list to empty.
601          */
602         packet->vps = NULL;
603
604         /*
605          *      Check for socket errors.
606          */
607         if (packet->data_len < 0) {
608                 librad_log("Error receiving packet from host %s: %s",
609                            ip_ntoa(host_ipaddr, packet->src_ipaddr),
610                            strerror(errno));
611                 free(packet);
612                 return NULL;
613         }
614
615         /*
616          *      Check for packets smaller than the packet header.
617          */
618         if (packet->data_len < AUTH_HDR_LEN) {
619                 librad_log("WARNING: Malformed RADIUS packet from host %s: too short",
620                            ip_ntoa(host_ipaddr, packet->src_ipaddr));
621                 free(packet);
622                 return NULL;
623         }
624
625         /*
626          *      Check for packets with mismatched size.
627          *      i.e. We've received 128 bytes, and the packet header
628          *      says it's 256 bytes long.
629          */
630         hdr = (radius_packet_t *)data;
631         memcpy(&len, hdr->length, sizeof(u_short));
632         totallen = ntohs(len);
633         if (packet->data_len != totallen) {
634                 librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet size says %d",
635                            ip_ntoa(host_ipaddr, packet->src_ipaddr),
636                            packet->data_len, totallen);
637                 free(packet);
638                 return NULL;
639         }
640
641         /*
642          *      Walk through the packet's attributes, ensuring that
643          *      they add up EXACTLY to the size of the packet.
644          *
645          *      If they don't, then the attributes either under-fill
646          *      or over-fill the packet.  Any parsing of the packet
647          *      is impossible, and will result in unknown side effects.
648          *
649          *      This would ONLY happen with buggy RADIUS implementations,
650          *      or with an intentional attack.  Either way, we do NOT want
651          *      to be vulnerable to this problem.
652          */
653         attr = hdr->data;
654         count = totallen - AUTH_HDR_LEN;
655         seen_eap = 0;
656         num_attributes = 0;
657
658         while (count > 0) {
659                 /*
660                  *      Attribute number zero is NOT defined.
661                  */
662                 if (attr[0] == 0) {
663                         librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
664                                    ip_ntoa(host_ipaddr, packet->src_ipaddr));
665                         free(packet);
666                         return NULL;
667                 }
668                 
669                 /*
670                  *      Attributes are at LEAST as long as the ID & length
671                  *      fields.  Anything shorter is an invalid attribute.
672                  */
673                 if (attr[1] < 2) {
674                         librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
675                                    ip_ntoa(host_ipaddr, packet->src_ipaddr),
676                                    attr[0]);
677                         free(packet);
678                         return NULL;
679                 }
680
681                 /*
682                  *      Sanity check the attributes for length.
683                  */
684                 switch (attr[0]) {
685                 default:        /* don't do anything by default */
686                         break;
687
688                 case PW_EAP_MESSAGE:
689                         seen_eap |= PW_EAP_MESSAGE;
690                         break;
691
692                 case PW_MESSAGE_AUTHENTICATOR:
693                         if (attr[1] != 2 + AUTH_VECTOR_LEN) {
694                                 librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
695                                            ip_ntoa(host_ipaddr, packet->src_ipaddr),
696                                            attr[1] - 2);
697                                 free(packet);
698                                 return NULL;
699                         }
700                         seen_eap |= PW_MESSAGE_AUTHENTICATOR;
701                         break;
702                 }
703
704                 /*
705                  *      FIXME: Look up the base 255 attributes in the
706                  *      dictionary, and switch over their type.  For
707                  *      integer/date/ip, the attribute length SHOULD
708                  *      be 6.
709                  */
710                 count -= attr[1];       /* grab the attribute length */
711                 attr += attr[1];
712                 num_attributes++;       /* seen one more attribute */
713         }
714
715         /*
716          *      If the attributes add up to a packet, it's allowed.
717          *
718          *      If not, we complain, and throw the packet away.
719          */
720         if (count != 0) {
721                 librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
722                            ip_ntoa(host_ipaddr, packet->src_ipaddr));
723                 free(packet);
724                 return NULL;
725         }
726
727         /*
728          *      If we've seen an EAP-Message attribute without a
729          *      Message-Authenticator attribute, it's invalid.
730          */
731         if (((seen_eap & PW_EAP_MESSAGE) == PW_EAP_MESSAGE) &&
732             ((seen_eap & PW_MESSAGE_AUTHENTICATOR) != PW_MESSAGE_AUTHENTICATOR)) {
733                 librad_log("WARNING: Malformed RADIUS packet from host %s: Contains EAP-Message, but no Message-Authenticator",
734                            ip_ntoa(host_ipaddr, packet->src_ipaddr));
735                 free(packet);
736                 return NULL;
737         }
738
739         /*
740          *      If we're configured to look for a maximum number of
741          *      attributes, and we've seen more than that maximum,
742          *      then throw the packet away, as a possible DoS.
743          */
744         if ((librad_max_attributes > 0) &&
745             (num_attributes > librad_max_attributes)) {
746                 librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
747                            ip_ntoa(host_ipaddr, packet->src_ipaddr),
748                            num_attributes, librad_max_attributes);
749                 free(packet);
750                 return NULL;
751         }
752
753         if (librad_debug) {
754                 if ((hdr->code > 0) && (hdr->code < 14)) {
755                         printf("rad_recv: %s packet from host %s:%d",
756                                packet_codes[hdr->code],
757                                ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
758                 } else {
759                         printf("rad_recv: Packet from host %s:%d code=%d",      
760                                ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
761                                hdr->code);
762                 }
763                 printf(", id=%d, length=%d\n", hdr->id, totallen);
764         }
765
766         /*
767          *      Fill RADIUS header fields
768          */
769         packet->code = hdr->code;
770         packet->id = hdr->id;
771         memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
772
773         /*
774          *  Now that we've sanity checked the packet, we can allocate
775          *  memory for it, and copy the data from the local area to
776          *  the packet buffer.
777          */
778         if ((packet->data = malloc(packet->data_len)) == NULL) {
779           free(packet);
780           librad_log("out of memory");
781           return NULL;
782         }
783         memcpy(packet->data, data, packet->data_len);
784
785         return packet;
786 }
787
788 /*
789  *      Calculate/check digest, and decode radius attributes.
790  */
791 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret)
792 {
793         DICT_ATTR               *attr;
794         uint32_t                lvalue;
795         uint32_t                vendorcode;
796         uint32_t                vendorpec;
797         VALUE_PAIR              *first_pair;
798         VALUE_PAIR              *prev;
799         VALUE_PAIR              *pair;
800         uint8_t                 *ptr;
801         int                     length;
802         int                     attribute;
803         int                     attrlen;
804         int                     vendorlen;
805         radius_packet_t         *hdr;
806
807         hdr = (radius_packet_t *)packet->data;
808
809         /*
810          *      Before we allocate memory for the attributes, do more
811          *      sanity checking.
812          */
813         ptr = hdr->data;
814         length = packet->data_len - AUTH_HDR_LEN;
815         while (length > 0) {
816                 uint8_t msg_auth_vector[AUTH_VECTOR_LEN];
817                 uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
818
819                 attrlen = ptr[1];
820
821                 switch (ptr[0]) {
822                 default:        /* don't do anything. */
823                         break;
824
825                         /*
826                          *      Note that more than one Message-Authenticator
827                          *      attribute is invalid.
828                          */
829                 case PW_MESSAGE_AUTHENTICATOR:
830                         memcpy(msg_auth_vector, &ptr[2], sizeof(msg_auth_vector));
831                         memset(&ptr[2], 0, AUTH_VECTOR_LEN);
832
833                         switch (packet->code) {
834                         default:
835                           break;
836
837                         case PW_AUTHENTICATION_ACK:
838                         case PW_AUTHENTICATION_REJECT:
839                         case PW_ACCESS_CHALLENGE:
840                           if (original) {
841                                   memcpy(packet->data + 4, original->vector, AUTH_VECTOR_LEN);
842                           }
843                           break;
844                         }
845
846                         lrad_hmac_md5(packet->data, packet->data_len,
847                                       secret, strlen(secret), calc_auth_vector);
848                         if (memcmp(calc_auth_vector, msg_auth_vector,
849                                     sizeof(calc_auth_vector)) != 0) {
850                                 char buffer[32];
851                                 librad_log("Received packet from %s with invalid Message-Authenticator!",
852                                            ip_ntoa(buffer, packet->src_ipaddr));
853                                 return 1;
854                         } /* else the message authenticator was good */
855
856                         /*
857                          *      Reinitialize Authenticators.
858                          */
859                         memcpy(&ptr[2], msg_auth_vector, AUTH_VECTOR_LEN);
860                         memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
861                         break;
862                 } /* switch over the attributes */
863
864                 ptr += attrlen;
865                 length -= attrlen;
866         } /* loop over the packet, sanity checking the attributes */
867
868         /*
869          *      Calculate and/or verify digest.
870          */
871         switch(packet->code) {
872                 case PW_AUTHENTICATION_REQUEST:
873                 case PW_STATUS_SERVER:
874                         /*
875                          *      The authentication vector is random
876                          *      nonsense, invented by the client.
877                          */
878                         break;
879
880                 case PW_ACCOUNTING_REQUEST:
881                         if (calc_acctdigest(packet, secret) > 1) {
882                                 char buffer[32];
883                                 librad_log("Received Accounting-Request packet "
884                                     "from %s with invalid signature!",
885                                     ip_ntoa(buffer, packet->src_ipaddr));
886                                 return 1;
887                         }
888                         break;
889
890                         /* Verify the reply digest */
891                 case PW_AUTHENTICATION_ACK:
892                 case PW_AUTHENTICATION_REJECT:
893                 case PW_ACCOUNTING_RESPONSE:
894                         if (calc_replydigest(packet, original, secret) > 1) {
895                                 char buffer[32];
896                                 librad_log("Received %s packet "
897                                            "from %s with invalid signature!",
898                                            packet_codes[packet->code],
899                                            ip_ntoa(buffer, packet->src_ipaddr));
900                                 return 1;
901                         }
902                   break;
903         }
904
905         /*
906          *      Extract attribute-value pairs
907          */
908         ptr = hdr->data;
909         length = packet->data_len - AUTH_HDR_LEN;
910         first_pair = NULL;
911         prev = NULL;
912
913         vendorcode = 0;
914         vendorlen  = 0;
915
916         while(length > 0) {
917                 if (vendorlen > 0) {
918                         attribute = *ptr++ | (vendorcode << 16);
919                         attrlen   = *ptr++;
920                 } else {
921                         attribute = *ptr++;
922                         attrlen   = *ptr++;
923                 }
924
925                 attrlen -= 2;
926                 length  -= 2;
927
928                 /*
929                  *      This could be a Vendor-Specific attribute.
930                  *
931                  */
932                 if ((vendorlen <= 0) &&
933                     (attribute == PW_VENDOR_SPECIFIC) && 
934                     (attrlen > 6)) {
935                         memcpy(&lvalue, ptr, 4);
936                         vendorpec = ntohl(lvalue);
937                         if ((vendorcode = dict_vendorcode(vendorpec)) != 0) {
938
939                                 if (vendorpec == VENDORPEC_USR) {
940                                         ptr += 4;
941                                         memcpy(&lvalue, ptr, 4);
942                                         /*printf("received USR %04x\n", ntohl(lvalue));*/
943                                         attribute = (ntohl(lvalue) & 0xFFFF) |
944                                                         (vendorcode << 16);
945                                         ptr += 4;
946                                         attrlen -= 8;
947                                         length -= 8;
948
949                                 } else {
950                                         ptr += 4;
951                                         vendorlen = attrlen - 4;
952                                         attribute = *ptr++ | (vendorcode << 16);
953                                         attrlen   = *ptr++;
954                                         attrlen -= 2;
955                                         length -= 6;
956                                 }
957                         }
958                         /*
959                          *  Else the vendor wasn't found...
960                          */
961                 }
962
963                 /*
964                  *      FIXME: should we us paircreate() ?
965                  */
966                 if ((pair = malloc(sizeof(VALUE_PAIR))) == NULL) {
967                         pairfree(&first_pair);
968                         librad_log("out of memory");
969                         errno = ENOMEM;
970                         return -1;
971                 }
972                 
973                 memset(pair, 0, sizeof(VALUE_PAIR));
974                 if ((attr = dict_attrbyvalue(attribute)) == NULL) {
975                         snprintf(pair->name, sizeof(pair->name), "Attr-%d", attribute);
976                         pair->type = PW_TYPE_STRING;
977                 } else {
978                         strcpy(pair->name, attr->name);
979                         pair->type = attr->type;
980                 }
981                 pair->attribute = attribute;
982                 pair->length = attrlen;
983                 pair->next = NULL;
984                 
985                 switch (pair->type) {
986                         
987                 case PW_TYPE_OCTETS:
988                 case PW_TYPE_ABINARY:
989                 case PW_TYPE_STRING:
990                         /*
991                          *      Hmm... this is based on names right
992                          *      now.  We really shouldn't do this.
993                          *      It should be based on the value of
994                          *      the attribute (VSA or not).
995                          */
996                         if ((strcmp(pair->name, "Ascend-Send-Secret") == 0) ||
997                             (strcmp(pair->name, "Ascend-Receive-Secret") == 0)) {
998                                 uint8_t my_digest[AUTH_VECTOR_LEN];
999                                 make_secret( my_digest, original->vector,
1000                                              secret, ptr);
1001                                 memcpy(pair->strvalue, my_digest, AUTH_VECTOR_LEN );
1002                                 pair->strvalue[AUTH_VECTOR_LEN] = '\0';
1003                                 pair->length = strlen(pair->strvalue);
1004                         } else
1005                                 /* attrlen always < MAX_STRING_LEN */
1006                                 memcpy(pair->strvalue, ptr, attrlen);
1007                         break;
1008                         
1009                 case PW_TYPE_INTEGER:
1010                 case PW_TYPE_DATE:
1011                 case PW_TYPE_IPADDR:
1012                         /*
1013                          *      Check for RFC compliance.  If the
1014                          *      attribute isn't compliant, turn it
1015                          *      into a string of raw octets.
1016                          *
1017                          *      Also set the lvalue to something
1018                          *      which should never match anything.
1019                          */
1020                         if (attrlen != 4) {
1021                                 pair->type = PW_TYPE_OCTETS;
1022                                 memcpy(pair->strvalue, ptr, attrlen);
1023                                 pair->lvalue = 0xbaddbadd;
1024                                 break;
1025                         }
1026                         memcpy(&lvalue, ptr, 4);
1027                         if (attr->type != PW_TYPE_IPADDR)
1028                                 pair->lvalue = ntohl(lvalue);
1029                         else
1030                                 pair->lvalue = lvalue;
1031                         break;
1032                         
1033                 default:
1034                         DEBUG("    %s (Unknown Type %d)\n",
1035                               attr->name,attr->type);
1036                         free(pair);
1037                         pair = NULL;
1038                         break;
1039                 }
1040                 
1041                 if (pair) {
1042                         debug_pair(pair);
1043                         if (first_pair == NULL)
1044                                 first_pair = pair;
1045                         else
1046                                         prev->next = pair;
1047                         prev = pair;
1048                 }
1049
1050                 ptr += attrlen;
1051                 length -= attrlen;
1052                 if (vendorlen > 0) vendorlen -= (attrlen + 2);
1053         }
1054
1055         packet->vps = first_pair;
1056
1057         /*
1058          *      Merge information from the outside world into our
1059          *      random vector pool.
1060          */
1061         for (length = 0; length < AUTH_VECTOR_LEN; length++) {
1062                 random_vector_pool[length] ^= packet->vector[length];
1063         }
1064
1065         return 0;
1066 }
1067
1068
1069 /*
1070  *      Encode password.
1071  *
1072  *      We assume that the passwd buffer passed is big enough.
1073  *      RFC2138 says the password is max 128 chars, so the size
1074  *      of the passwd buffer must be at least 129 characters.
1075  *      Preferably it's just MAX_STRING_LEN.
1076  *
1077  *      int *pwlen is updated to the new length of the encrypted
1078  *      password - a multiple of 16 bytes.
1079  */
1080 #define AUTH_PASS_LEN (16)
1081 int rad_pwencode(char *passwd, int *pwlen, const char *secret, const char *vector)
1082 {
1083         uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
1084         char    digest[AUTH_VECTOR_LEN];
1085         int     i, n, secretlen;
1086         int     len;
1087
1088         /*
1089          *      Padd password to multiple of AUTH_PASS_LEN bytes.
1090          */
1091         len = strlen(passwd);
1092         if (len > 128) len = 128;
1093         *pwlen = len;
1094         if (len % AUTH_PASS_LEN != 0) {
1095                 n = AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
1096                 for (i = len; n > 0; n--, i++)
1097                         passwd[i] = 0;
1098                 len = *pwlen = i;
1099         }
1100
1101         /*
1102          *      Use the secret to setup the decryption digest
1103          */
1104         secretlen = strlen(secret);
1105         memcpy(buffer, secret, secretlen);
1106         memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1107         librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
1108
1109         /*
1110          *      Now we can encode the password *in place*
1111          */
1112         for (i = 0; i < AUTH_PASS_LEN; i++)
1113                 passwd[i] ^= digest[i];
1114
1115         if (len <= AUTH_PASS_LEN) return 0;
1116
1117         /*
1118          *      Length > AUTH_PASS_LEN, so we need to use the extended
1119          *      algorithm.
1120          */
1121         for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) { 
1122                 memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
1123                 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1124                 for (i = 0; i < AUTH_PASS_LEN; i++)
1125                         passwd[i + n + AUTH_PASS_LEN] ^= digest[i];
1126         }
1127
1128         return 0;
1129 }
1130
1131 /*
1132  *      Decode password.
1133  */
1134 int rad_pwdecode(char *passwd, int pwlen, const char *secret, const char *vector)
1135 {
1136         uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
1137         char    digest[AUTH_VECTOR_LEN];
1138         char    r[AUTH_VECTOR_LEN];
1139         char    *s;
1140         int     i, n, secretlen;
1141         int     rlen;
1142
1143         /*
1144          *      Use the secret to setup the decryption digest
1145          */
1146         secretlen = strlen(secret);
1147         memcpy(buffer, secret, secretlen);
1148         memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
1149         librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
1150
1151         /*
1152          *      Now we can decode the password *in place*
1153          */
1154         memcpy(r, passwd, AUTH_PASS_LEN);
1155         for (i = 0; i < AUTH_PASS_LEN && i < pwlen; i++)
1156                 passwd[i] ^= digest[i];
1157
1158         if (pwlen <= AUTH_PASS_LEN) {
1159                 passwd[pwlen+1] = 0;
1160                 return pwlen;
1161         }
1162
1163         /*
1164          *      Length > AUTH_PASS_LEN, so we need to use the extended
1165          *      algorithm.
1166          */
1167         rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
1168
1169         for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) { 
1170                 s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
1171                 memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
1172                 librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
1173                 for (i = 0; i < AUTH_PASS_LEN && (i + n) < pwlen; i++)
1174                         passwd[i + n] ^= digest[i];
1175         }
1176         passwd[pwlen] = 0;
1177
1178         return pwlen;
1179 }
1180
1181 /*
1182  *      Encode a CHAP password
1183  *
1184  *      FIXME: might not work with Ascend because
1185  *      we use vp->length, and Ascend gear likes
1186  *      to send an extra '\0' in the string!
1187  */
1188 int rad_chap_encode(RADIUS_PACKET *packet, char *output, int id, VALUE_PAIR *password)
1189 {
1190         int             i;
1191         char            *ptr;
1192         char            string[MAX_STRING_LEN];
1193         VALUE_PAIR      *challenge;
1194
1195         /*
1196          *      Sanity check the input parameters
1197          */
1198         if ((packet == NULL) || (password == NULL)) {
1199                 return -1;
1200         }
1201
1202         /*
1203          *      Note that the password VP can be EITHER
1204          *      a Password attribute (from a check-item list),
1205          *      or a CHAP-Password attribute (the client asking
1206          *      the library to encode it).
1207          */
1208
1209         i = 0;
1210         ptr = string;
1211         *ptr++ = id;
1212
1213         i++;
1214         memcpy(ptr, password->strvalue, password->length);
1215         ptr += password->length;
1216         i += password->length;
1217
1218         /*
1219          *      Use Chap-Challenge pair if present,
1220          *      Request-Authenticator otherwise.
1221          */
1222         challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE);
1223         if (challenge) {
1224                 memcpy(ptr, challenge->strvalue, challenge->length);
1225                 i += challenge->length;
1226         } else {
1227                 memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
1228                 i += AUTH_VECTOR_LEN; 
1229         }
1230
1231         *output = id;
1232         librad_md5_calc((u_char *)output + 1, (u_char *)string, i);
1233
1234         return 0;
1235 }
1236
1237 /*
1238  *      Create a random vector of AUTH_VECTOR_LEN bytes.
1239  */
1240 static void random_vector(uint8_t *vector)
1241 {
1242         int             i;
1243         static int      did_srand = 0;
1244         static int      counter = 0;
1245 #ifdef __linux__
1246         static int      urandom_fd = -1;
1247
1248         /*
1249          *      Use /dev/urandom if available.
1250          */
1251         if (urandom_fd > -2) {
1252                 /*
1253                  *      Open urandom fd if not yet opened.
1254                  */
1255                 if (urandom_fd < 0)
1256                         urandom_fd = open("/dev/urandom", O_RDONLY);
1257                 if (urandom_fd < 0) {
1258                         /*
1259                          *      It's not there, don't try
1260                          *      it again.
1261                          */
1262                         DEBUG("Cannot open /dev/urandom, using rand()\n");
1263                         urandom_fd = -2;
1264                 } else {
1265
1266                         fcntl(urandom_fd, F_SETFD, 1);
1267
1268                         /*
1269                          *      Read 16 bytes.
1270                          */
1271                         if (read(urandom_fd, (char *) vector, AUTH_VECTOR_LEN)
1272                             == AUTH_VECTOR_LEN)
1273                                 return;
1274                         /*
1275                          *      We didn't get 16 bytes - fall
1276                          *      back on rand) and don't try again.
1277                          */
1278                 DEBUG("Read short packet from /dev/urandom, using rand()\n");
1279                         urandom_fd = -2;
1280                 }
1281         }
1282 #endif
1283
1284         if (!did_srand) {
1285                 srand(time(NULL) + getpid());
1286
1287                 /*
1288                  *      Now that we have a bad random seed, let's
1289                  *      make it a little better by MD5'ing it.
1290                  */
1291                 for (i = 0; i < (int)sizeof(random_vector_pool); i++) {
1292                         random_vector_pool[i] += rand() & 0xff;
1293                 }
1294
1295                 librad_md5_calc((u_char *) random_vector_pool,
1296                                 (u_char *) random_vector_pool,
1297                                 sizeof(random_vector_pool));
1298
1299                 did_srand = 1;
1300         }
1301
1302         /*
1303          *      Modify our random pool, based on the counter,
1304          *      and put the resulting information through MD5,
1305          *      so it's all mashed together.
1306          */
1307         counter++;
1308         random_vector_pool[AUTH_VECTOR_LEN] += (counter & 0xff);
1309         librad_md5_calc((u_char *) random_vector_pool,
1310                         (u_char *) random_vector_pool,
1311                         sizeof(random_vector_pool));
1312
1313         /*
1314          *      And do another MD5 hash of the result, to give
1315          *      the user a random vector.  This ensures that the
1316          *      user has a random vector, without giving them
1317          *      an exact image of what's in the random pool.
1318          */
1319         librad_md5_calc((u_char *) vector,
1320                         (u_char *) random_vector_pool,
1321                         sizeof(random_vector_pool));
1322 }
1323
1324
1325 /*
1326  *      Allocate a new RADIUS_PACKET
1327  */
1328 RADIUS_PACKET *rad_alloc(int newvector)
1329 {
1330         RADIUS_PACKET   *rp;
1331
1332         if ((rp = malloc(sizeof(RADIUS_PACKET))) == NULL) {
1333                 librad_log("out of memory");
1334                 return NULL;
1335         }
1336         memset(rp, 0, sizeof(RADIUS_PACKET));
1337         if (newvector)
1338                 random_vector(rp->vector);
1339
1340         return rp;
1341 }
1342
1343 /*
1344  *      Free a RADIUS_PACKET
1345  */
1346 void rad_free(RADIUS_PACKET **radius_packet_ptr)
1347 {
1348         RADIUS_PACKET *radius_packet;
1349
1350         if (!radius_packet_ptr) return;
1351         radius_packet = *radius_packet_ptr;
1352
1353         if (radius_packet->data) free(radius_packet->data);
1354         if (radius_packet->vps) pairfree(&radius_packet->vps);
1355
1356         free(radius_packet);
1357
1358         *radius_packet_ptr = NULL;
1359 }
1360
1361 /*************************************************************************
1362  *
1363  *      Function: make_secret
1364  *
1365  *      Purpose: Build an encrypted secret value to return in a reply
1366  *               packet.  The secret is hidden by xoring with a MD5 digest
1367  *               created from the shared secret and the authentication
1368  *               vector.  We put them into MD5 in the reverse order from
1369  *               that used when encrypting passwords to RADIUS.
1370  *
1371  *************************************************************************/
1372 static void make_secret(unsigned char *digest, uint8_t *vector,
1373                         const char *secret, char *value)
1374 {
1375         u_char  buffer[256 + AUTH_VECTOR_LEN];
1376         int             secretLen = strlen(secret);
1377         int             i;
1378
1379         memcpy(buffer, vector, AUTH_VECTOR_LEN );
1380         memcpy(buffer + AUTH_VECTOR_LEN, secret, secretLen );
1381
1382         librad_md5_calc(digest, buffer, AUTH_VECTOR_LEN + secretLen );
1383         memset(buffer, 0, sizeof(buffer));
1384
1385         for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
1386                 digest[i] ^= value[i];
1387         }
1388 }