import from branch_1_1:
[freeradius.git] / src / main / listen.c
1 /*
2  * listen.c     Handle socket stuff
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2005,2006  The FreeRADIUS server project
21  * Copyright 2005  Alan DeKok <aland@ox.org>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/autoconf.h>
28
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
34 #endif
35
36 #ifdef HAVE_ARPA_INET_H
37 #include <arpa/inet.h>
38 #endif
39
40 #include <sys/resource.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netdb.h>
45
46 #ifdef HAVE_NET_IF_H
47 #include <net/if.h>
48 #endif
49
50 #ifdef HAVE_SYS_STAT_H
51 #include <sys/stat.h>
52 #endif
53
54 #ifdef WITH_UDPFROMTO
55 #include <freeradius-devel/udpfromto.h>
56 #endif
57
58 #include <fcntl.h>
59
60 #include <freeradius-devel/radiusd.h>
61 #include <freeradius-devel/rad_assert.h>
62
63 #include <freeradius-devel/radius_snmp.h>
64 #include <freeradius-devel/request_list.h>
65
66 static time_t start_time = 0;
67
68 /*
69  *      FIXME: Delete this crap!
70  */
71 extern time_t time_now;
72
73 /*
74  *      We'll use this below.
75  */
76 typedef int (*rad_listen_parse_t)(const char *, int, const CONF_SECTION *, rad_listen_t *);
77 typedef void (*rad_listen_free_t)(rad_listen_t *);
78
79 typedef struct rad_listen_master_t {
80         rad_listen_parse_t      parse;
81         rad_listen_free_t       free;
82         rad_listen_recv_t       recv;
83         rad_listen_send_t       send;
84         rad_listen_update_t     update;
85         rad_listen_print_t      print;
86 } rad_listen_master_t;
87
88 typedef struct listen_socket_t {
89         /*
90          *      For normal sockets.
91          */
92         lrad_ipaddr_t   ipaddr;
93         int             port;
94         RADCLIENT_LIST  *clients;
95 } listen_socket_t;
96
97 typedef struct listen_detail_t {
98         const char      *detail;
99         VALUE_PAIR      *vps;
100         FILE            *fp;
101         int             state;
102         time_t          timestamp;
103         lrad_ipaddr_t   client_ip;
104         int             max_outstanding;
105         int             *outstanding;
106 } listen_detail_t;
107                                
108
109 /*
110  *      Find a per-socket client.
111  */
112 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
113                                        const lrad_ipaddr_t *ipaddr)
114 {
115         const RADCLIENT_LIST *clients;
116
117         rad_assert(listener != NULL);
118         rad_assert(ipaddr != NULL);
119
120         rad_assert((listener->type == RAD_LISTEN_AUTH) ||
121                    (listener->type == RAD_LISTEN_ACCT));
122
123         clients = ((listen_socket_t *)listener->data)->clients;
124         if (!clients) clients = mainconfig.clients;
125
126         rad_assert(clients != NULL);
127         
128         return client_find(clients, ipaddr);
129 }
130
131 static int listen_bind(rad_listen_t *this);
132
133 /*
134  *      FIXME: have the detail reader use another config "exit when done",
135  *      so that it can be used as a one-off tool to update stuff.
136  */
137
138 /*
139  *      Process and reply to a server-status request.
140  *      Like rad_authenticate and rad_accounting this should
141  *      live in it's own file but it's so small we don't bother.
142  */
143 static int rad_status_server(REQUEST *request)
144 {
145         switch (request->listener->type) {
146         case RAD_LISTEN_AUTH:
147                 request->reply->code = PW_AUTHENTICATION_ACK;
148
149                 /*
150                  *      Commented out for now.
151                  */
152 #if 0
153  { 
154                 char            reply_msg[64];
155                 time_t          t;
156                 VALUE_PAIR      *vp;
157                 
158                 /*
159                  *      Reply with an ACK. We might want to add some more
160                  *      interesting reply attributes, such as server uptime.
161                  */
162                 t = request->timestamp - start_time;
163                 sprintf(reply_msg, "FreeRADIUS STUFF %d day%s, %02d:%02d",
164                         (int)(t / 86400), (t / 86400) == 1 ? "" : "s",
165                         (int)((t / 3600) % 24), (int)(t / 60) % 60);
166                 
167                 vp = pairmake("Reply-Message", reply_msg, T_OP_SET);
168                 pairadd(&request->reply->vps, vp); /* don't need to check if !vp */
169  }
170 #endif
171                 break;
172
173         case RAD_LISTEN_ACCT:
174                 request->reply->code = PW_ACCOUNTING_RESPONSE;
175                 break;
176
177         default:
178                 return 0;
179         }
180         
181
182         return 0;
183 }
184
185 static int request_num_counter = 0;
186
187 /*
188  *      Check for dups, etc.  Common to Access-Request &&
189  *      Accounting-Request packets.
190  */
191 static int common_checks(rad_listen_t *listener,
192                          RADIUS_PACKET *packet, REQUEST **prequest,
193                          const RADCLIENT *client)
194 {
195         REQUEST *curreq;
196         char buffer[128];
197
198         rad_assert(listener->rl != NULL);
199
200         /*
201          *      If there is no existing request of id, code, etc.,
202          *      then we can return, and let it be processed.
203          */
204         if ((curreq = rl_find(listener->rl, packet)) == NULL) {
205                 /*
206                  *      Count the total number of requests, to see if
207                  *      there are too many.  If so, return with an
208                  *      error.
209                  */
210                 if (mainconfig.max_requests) {
211                         /*
212                          *      FIXME: This is now per-socket,
213                          *      when it should really be global
214                          *      to the server!
215                          */
216                         int request_count = rl_num_requests(listener->rl);
217
218                         /*
219                          *      This is a new request.  Let's see if
220                          *      it makes us go over our configured
221                          *      bounds.
222                          */
223                         if (request_count > mainconfig.max_requests) {
224                                 radlog(L_ERR, "Dropping request (%d is too many): "
225                                        "from client %s port %d - ID: %d", request_count,
226                                        client->shortname,
227                                        packet->src_port, packet->id);
228                                 radlog(L_INFO, "WARNING: Please check the %s file.\n"
229                                        "\tThe value for 'max_requests' is probably set too low.\n", mainconfig.radiusd_conf);
230                                 return 0;
231                         } /* else there were a small number of requests */
232                 } /* else there was no configured limit for requests */
233
234                 /*
235                  *      FIXME: Add checks for system load.  If the
236                  *      system is busy, start dropping requests...
237                  *
238                  *      We can probably keep some statistics
239                  *      ourselves...  if there are more requests
240                  *      coming in than we can handle, start dropping
241                  *      some.
242                  */
243
244         /*
245          *      The current request isn't finished, which
246          *      means that the NAS sent us a new packet, while
247          *      we are still processing the old request.
248          */
249         } else if (!curreq->finished) {
250                 /*
251                  *      If the authentication vectors are identical,
252                  *      then the NAS is re-transmitting it, trying to
253                  *      kick us into responding to the request.
254                  */
255                 if (memcmp(curreq->packet->vector, packet->vector,
256                            sizeof(packet->vector)) == 0) {
257                         RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
258
259                         /*
260                          *      It's not finished because the request
261                          *      was proxied, but there was no reply
262                          *      from the home server.
263                          *
264                          *      This code will never get hit for
265                          *      accounting packets, as they're always
266                          *      updated, and never re-transmitted.
267                          */
268                         if (curreq->proxy && !curreq->proxy_reply) {
269                                 DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
270                                        inet_ntop(curreq->proxy->dst_ipaddr.af,
271                                                  &curreq->proxy->dst_ipaddr.ipaddr,
272                                                  buffer, sizeof(buffer)),                                              curreq->proxy->dst_port,
273                                        
274                                        curreq->proxy->id);
275                                 curreq->proxy_listener->send(curreq->proxy_listener, curreq);
276                                 return 0;
277                         } /* else the packet was not proxied */
278
279                         /*
280                          *      Someone's still working on it, so we
281                          *      ignore the duplicate request.
282                          */
283                         radlog(L_ERR, "Discarding duplicate request from "
284                                "client %s port %d - ID: %d due to unfinished request %d",
285                                client->shortname,
286                                packet->src_port, packet->id,
287                                curreq->number);
288                         return 0;
289                 } /* else the authentication vectors were different */
290
291                 /*
292                  *      We're waiting for a proxy reply, but no one is
293                  *      currently processing the request.  We can
294                  *      discard the old request, and ignore any reply
295                  *      from the home server, because the NAS will
296                  *      never care...
297                  */
298                 if (curreq->proxy && !curreq->proxy_reply &&
299                     (curreq->child_pid == NO_SUCH_CHILD_PID)) {
300                         radlog(L_ERR, "Discarding old proxied request %d from "
301                                "client %s port %d - ID: %d due to new request from the client",
302                                curreq->number, client->shortname,
303                                packet->src_port, packet->id);
304                 } else {
305                         /*
306                          *      The authentication vectors are different, so
307                          *      the NAS has given up on us, as we've taken too
308                          *      long to process the request.  This is a
309                          *      SERIOUS problem!
310                          */
311                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
312                         
313                         radlog(L_ERR, "Dropping conflicting packet from "
314                                "client %s port %d - ID: %d due to unfinished request %d",
315                                client->shortname,
316                                packet->src_port, packet->id,
317                                curreq->number);
318                         return 0;
319                 }
320                 
321                 /*
322                  *      The old request is finished.  We now check the
323                  *      authentication vectors.  If the client has sent us a
324                  *      request with identical code && ID, but different
325                  *      vector, then they MUST have gotten our response, so we
326                  *      can delete the original request, and process the new
327                  *      one.
328                  *
329                  *      If the vectors are the same, then it's a duplicate
330                  *      request, and we can send a duplicate reply.
331                  */
332         } else if (memcmp(curreq->packet->vector, packet->vector,
333                           sizeof(packet->vector)) == 0) {
334                 RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
335
336                 /*
337                  *      If the packet has been delayed, then silently
338                  *      send a response, and clear the delayed flag.
339                  *
340                  *      Note that this means if the NAS kicks us while
341                  *      we're delaying a reject, then the reject may
342                  *      be sent sooner than otherwise.
343                  *
344                  *      This COULD be construed as a bug.  Maybe what
345                  *      we want to do is to ignore the duplicate
346                  *      packet, and send the reject later.
347                  */
348                 if (curreq->options & RAD_REQUEST_OPTION_DELAYED_REJECT) {
349                         curreq->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
350                         rad_assert(curreq->listener == listener);
351                         listener->send(listener, curreq);
352                         return 0;
353                 }
354
355                 /*
356                  *      Maybe we've saved a reply packet.  If so,
357                  *      re-send it.  Otherwise, just complain.
358                  */
359                 if (curreq->reply->code != 0) {
360                         DEBUG2("Sending duplicate reply "
361                                "to client %s port %d - ID: %d",
362                                client->shortname,
363                                packet->src_port, packet->id);
364                         rad_assert(curreq->listener == listener);
365                         listener->send(listener, curreq);
366                         return 0;
367                 }
368
369                 /*
370                  *      Else we never sent a reply to the NAS,
371                  *      as we decided somehow we didn't like the request.
372                  *
373                  *      This shouldn't happen, in general...
374                  */
375                 DEBUG2("Discarding duplicate request from client %s port %d - ID: %d",
376                        client->shortname, packet->src_port, packet->id);
377                 return 0;
378         } /* else the vectors were different, so we discard the old request. */
379
380         /*
381          *      'packet' has the same source IP, source port, code,
382          *      and Id as 'curreq', but a different authentication
383          *      vector.  We can therefore delete 'curreq', as we were
384          *      only keeping it around to send out duplicate replies,
385          *      if the first reply got lost in the network.
386          */
387         if (curreq) {
388                 rl_yank(listener->rl, curreq);
389                 request_free(&curreq);
390         }
391
392         /*
393          *      A unique per-request counter.
394          */
395         curreq = request_alloc(); /* never fails */
396         
397         if ((curreq->reply = rad_alloc(0)) == NULL) {
398                 radlog(L_ERR, "No memory");
399                 exit(1);
400         }
401         curreq->listener = listener;
402         curreq->packet = packet;
403         curreq->packet->timestamp = curreq->timestamp;
404         curreq->number = request_num_counter++;
405         strlcpy(curreq->secret, client->secret, sizeof(curreq->secret));
406         
407         /*
408          *      Remember the request in the list.
409          */
410         if (!rl_add(listener->rl, curreq)) {
411                 radlog(L_ERR, "Failed to insert request %d in the list of live requests: discarding", curreq->number);
412                 request_free(&curreq);
413                 return 0;
414         }
415         
416         /*
417          *      The request passes many of our sanity checks.
418          *      From here on in, if anything goes wrong, we
419          *      send a reject message, instead of dropping the
420          *      packet.
421          */
422
423         /*
424          *      Build the reply template from the request.
425          */
426
427         curreq->reply->sockfd = curreq->packet->sockfd;
428         curreq->reply->dst_ipaddr = curreq->packet->src_ipaddr;
429         curreq->reply->src_ipaddr = curreq->packet->dst_ipaddr;
430         curreq->reply->dst_port = curreq->packet->src_port;
431         curreq->reply->src_port = curreq->packet->dst_port;
432         curreq->reply->id = curreq->packet->id;
433         curreq->reply->code = 0; /* UNKNOWN code */
434         memcpy(curreq->reply->vector, curreq->packet->vector,
435                sizeof(curreq->reply->vector));
436         curreq->reply->vps = NULL;
437         curreq->reply->data = NULL;
438         curreq->reply->data_len = 0;
439
440         *prequest = curreq;
441         return 1;
442 }
443
444
445 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
446 {
447         size_t len;
448         listen_socket_t *sock = this->data;
449
450         if ((sock->ipaddr.af == AF_INET) &&
451             (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
452                 strcpy(buffer, "*");
453         } else {
454                 ip_ntoh(&sock->ipaddr, buffer, bufsize);
455         }
456
457         len = strlen(buffer);
458
459         return len + snprintf(buffer + len, bufsize - len, " port %d",
460                               sock->port);
461 }
462
463
464 /*
465  *      Parse an authentication or accounting socket.
466  */
467 static int common_socket_parse(const char *filename, int lineno,
468                              const CONF_SECTION *cs, rad_listen_t *this)
469 {
470         int             rcode;
471         int             listen_port;
472         lrad_ipaddr_t   ipaddr;
473         listen_socket_t *sock = this->data;
474         const char      *section_name = NULL;
475         CONF_SECTION    *client_cs;
476
477         /*
478          *      Try IPv4 first
479          */
480         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
481         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
482                               &ipaddr.ipaddr.ip4addr, NULL);
483         if (rcode < 0) return -1;
484         
485         if (rcode == 0) { /* successfully parsed IPv4 */
486                 ipaddr.af = AF_INET;
487                 
488         } else {        /* maybe IPv6? */
489                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
490                                       &ipaddr.ipaddr.ip6addr, NULL);
491                 if (rcode < 0) return -1;
492                 
493                 if (rcode == 1) {
494                         radlog(L_ERR, "%s[%d]: No address specified in listen section",
495                                filename, lineno);
496                         return -1;
497                 }
498                 ipaddr.af = AF_INET6;
499         }
500         
501         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
502                               &listen_port, "0");
503         if (rcode < 0) return -1;
504         
505         sock->ipaddr = ipaddr;
506         sock->port = listen_port;
507
508         /*
509          *      And bind it to the port.
510          */
511         if (listen_bind(this) < 0) {
512                 char buffer[128];
513                 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
514                        filename, cf_section_lineno(cs),
515                        ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
516                        sock->port);
517                 return -1;
518         }
519
520         /*
521          *      If we can bind to interfaces, do so,
522          *      else don't.
523          */
524         if (cf_pair_find(cs, "interface")) {
525 #ifndef SO_BINDTODEVICE
526                 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
527                        filename, cf_section_lineno(cs));
528                 return -1;
529 #else
530                 const char *value;
531                 const CONF_PAIR *cp = cf_pair_find(cs, "interface");
532                 struct ifreq ifreq;
533
534                 rad_assert(cp != NULL);
535                 value = cf_pair_value(cp);
536                 rad_assert(value != NULL);
537                 
538                 strcpy(ifreq.ifr_name, value);
539         
540                 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
541                                (char *)&ifreq, sizeof(ifreq)) < 0) {
542                         radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
543                                filename, cf_section_lineno(cs),
544                                value, strerror(errno));
545                         return -1;
546                 } /* else it worked. */
547 #endif
548         }
549
550         /*
551          *      Look for the name of a section that holds a list
552          *      of clients.
553          */
554         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
555                               &section_name, NULL);
556         if (rcode < 0) return -1; /* bad string */
557         if (rcode > 0) return 0; /* non-existent is OK. */
558
559         client_cs = cf_section_find(section_name);
560         free(section_name);
561         if (!client_cs) {
562                 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
563                        filename, cf_section_lineno(cs), section_name);
564                 return -1;
565         }
566
567         sock->clients = clients_parse_section(filename, client_cs);
568         if (!sock->clients) {
569                 return -1;
570         }
571
572         return 0;
573 }
574
575 /*
576  *      Send an authentication response packet
577  */
578 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
579 {
580         rad_assert(request->listener == listener);
581         rad_assert(listener->send == auth_socket_send);
582
583         /*
584          *      Ensure that the reply is sane
585          */
586         if (request->reply->code == 0) {
587                 DEBUG2("There was no response configured: rejecting request %d", request->number);
588                 request->reply->code = PW_AUTHENTICATION_REJECT;
589         }
590
591         /*
592          *      If we're delaying authentication rejects, then
593          *      mark the request as delayed, and do NOT send a
594          *      response right now.
595          *
596          *      However, if it's already marked as delayed, then
597          *      send it now.
598          */
599         if ((request->reply->code == PW_AUTHENTICATION_REJECT) &&
600             ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) == 0) &&
601             (mainconfig.reject_delay > 0) &&
602             ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0)) {
603                 DEBUG2("Delaying request %d for %d seconds",
604                        request->number, mainconfig.reject_delay);
605                 request->options |= RAD_REQUEST_OPTION_DELAYED_REJECT;
606                 return 0;
607         }
608
609         return rad_send(request->reply, request->packet, request->secret);
610 }
611
612
613 /*
614  *      Send an accounting response packet (or not)
615  */
616 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
617 {
618         rad_assert(request->listener == listener);
619         rad_assert(listener->send == acct_socket_send);
620
621         /*
622          *      Accounting reject's are silently dropped.
623          *
624          *      We do it here to avoid polluting the rest of the
625          *      code with this knowledge
626          */
627         if (request->reply->code == 0) return 0;
628
629         return rad_send(request->reply, request->packet, request->secret);
630 }
631
632
633 /*
634  *      Send a packet to a home server.
635  *
636  *      FIXME: have different code for proxy auth & acct!
637  */
638 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
639 {
640         listen_socket_t *sock = listener->data;
641
642         rad_assert(request->proxy_listener == listener);
643         rad_assert(listener->send == proxy_socket_send);
644
645         request->proxy->src_ipaddr = sock->ipaddr;
646         request->proxy->src_port = sock->port;
647
648         return rad_send(request->proxy, request->packet, request->proxysecret);
649 }
650
651
652 /*
653  *      Check if an incoming request is "ok"
654  *
655  *      It takes packets, not requests.  It sees if the packet looks
656  *      OK.  If so, it does a number of sanity checks on it.
657   */
658 static int auth_socket_recv(rad_listen_t *listener,
659                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
660 {
661         RADIUS_PACKET   *packet;
662         RAD_REQUEST_FUNP fun = NULL;
663         char            buffer[128];
664         RADCLIENT       *client;
665
666         packet = rad_recv(listener->fd);
667         if (!packet) {
668                 radlog(L_ERR, "%s", librad_errstr);
669                 return 0;
670         }
671
672         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: auth specific */
673
674         if ((client = client_listener_find(listener,
675                                            &packet->src_ipaddr)) == NULL) {
676                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
677                 
678                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
679                        inet_ntop(packet->src_ipaddr.af,
680                                  &packet->src_ipaddr.ipaddr,
681                                  buffer, sizeof(buffer)),
682                        packet->src_port);
683                 rad_free(&packet);
684                 return 0;
685         }
686
687         /*
688          *      Some sanity checks, based on the packet code.
689          */
690         switch(packet->code) {
691         case PW_AUTHENTICATION_REQUEST:
692                 fun = rad_authenticate;
693                 break;
694                 
695         case PW_STATUS_SERVER:
696                 if (!mainconfig.status_server) {
697                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
698                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
699                         rad_free(&packet);
700                         return 0;
701                 }
702                 fun = rad_status_server;
703                 break;
704
705         default:
706                 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
707                 
708                 radlog(L_ERR, "Invalid packet code %d sent to authentication port from client %s port %d "
709                        "- ID %d : IGNORED",
710                        packet->code, client->shortname,
711                        packet->src_port, packet->id);
712                 rad_free(&packet);
713                 return 0;
714                 break;
715         } /* switch over packet types */
716         
717         if (!common_checks(listener, packet, prequest, client)) {
718                 rad_free(&packet);
719                 return 0;
720         }
721
722         *pfun = fun;
723         return 1;
724 }
725
726
727 /*
728  *      Receive packets from an accounting socket
729  */
730 static int acct_socket_recv(rad_listen_t *listener,
731         RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
732 {
733         RADIUS_PACKET   *packet;
734         RAD_REQUEST_FUNP fun = NULL;
735         char            buffer[128];
736         RADCLIENT       *client;
737         
738         packet = rad_recv(listener->fd);
739         if (!packet) {
740                 radlog(L_ERR, "%s", librad_errstr);
741                 return 0;
742         }
743         
744         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: acct-specific */
745
746         if ((client = client_listener_find(listener,
747                                            &packet->src_ipaddr)) == NULL) {
748                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
749                 
750                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
751                        inet_ntop(packet->src_ipaddr.af,
752                                  &packet->src_ipaddr.ipaddr,
753                                  buffer, sizeof(buffer)),
754                        packet->src_port);
755                 rad_free(&packet);
756                 return 0;
757         }
758
759         switch(packet->code) {
760         case PW_ACCOUNTING_REQUEST:
761                 fun = rad_accounting;
762                 break;
763                 
764         case PW_STATUS_SERVER:
765                 if (!mainconfig.status_server) {
766                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
767                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
768                         rad_free(&packet);
769                         return 0;
770                 }
771                 fun = rad_status_server;
772                 break;
773
774         default:
775                 /*
776                  *      FIXME: Update MIB for packet types?
777                  */
778                 radlog(L_ERR, "Invalid packet code %d sent to a accounting port "
779                        "from client %s port %d - ID %d : IGNORED",
780                        packet->code, client->shortname,
781                        packet->src_port, packet->id);
782                 rad_free(&packet);
783                 return 0;
784         }
785
786         /*
787          *      FIXME: Accounting duplicates should be handled
788          *      differently than authentication duplicates.
789          */
790         if (!common_checks(listener, packet, prequest, client)) {
791                 rad_free(&packet);
792                 return 0;
793         }
794
795         *pfun = fun;
796         return 1;
797 }
798
799
800 /*
801  *      Recieve packets from a proxy socket.
802  */
803 static int proxy_socket_recv(rad_listen_t *listener,
804                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
805 {
806         REALM           *cl;
807         REQUEST         *oldreq;
808         RADIUS_PACKET   *packet;
809         RAD_REQUEST_FUNP fun = NULL;
810         char            buffer[128];
811         
812         packet = rad_recv(listener->fd);
813         if (!packet) {
814                 radlog(L_ERR, "%s", librad_errstr);
815                 return 0;
816         }
817
818         /*
819          *      Unsupported stuff
820          */
821         if (packet->src_ipaddr.af != AF_INET) {
822                 rad_assert("PROXY IPV6 NOT SUPPORTED" == NULL);
823         }
824         
825         /*
826          *      FIXME: Add support for home servers!
827          */
828         if ((cl = realm_findbyaddr(packet->src_ipaddr.ipaddr.ip4addr.s_addr,
829                                    packet->src_port)) == NULL) {
830                 radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
831                        inet_ntop(packet->src_ipaddr.af,
832                                  &packet->src_ipaddr.ipaddr,
833                                  buffer, sizeof(buffer)),
834                                packet->src_port);
835                 rad_free(&packet);
836                 return 0;
837         }
838
839         /*
840          *      FIXME: Client MIB updates?
841          */
842         switch(packet->code) {
843         case PW_AUTHENTICATION_ACK:
844         case PW_ACCESS_CHALLENGE:
845         case PW_AUTHENTICATION_REJECT:
846                 fun = rad_authenticate;
847                 break;
848                 
849         case PW_ACCOUNTING_RESPONSE:
850                 fun = rad_accounting;
851                 break;
852                 
853         default:
854                 /*
855                  *      FIXME: Update MIB for packet types?
856                  */
857                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
858                        "from home server %s port %d - ID %d : IGNORED",
859                        packet->code,
860                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
861                        packet->src_port, packet->id);
862                 rad_free(&packet);
863                 return 0;
864         }
865
866         /*
867          *      Find the original request in the request list
868          */
869         oldreq = rl_find_proxy(packet);
870
871         /*
872          *      If we haven't found the original request which was
873          *      sent, to get this reply.  Complain, and discard this
874          *      request, as there's no way for us to send it to a NAS.
875          */
876         if (!oldreq) {
877                 radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
878                        inet_ntop(packet->src_ipaddr.af,
879                                  &packet->src_ipaddr.ipaddr,
880                                  buffer, sizeof(buffer)),
881                        packet->src_port, packet->id);
882                 rad_free(&packet);
883                 return 0;
884         }
885
886         /*
887          *      The proxy reply has arrived too late, as the original
888          *      (old) request has timed out, been rejected, and marked
889          *      as finished.  The client has already received a
890          *      response, so there is nothing that can be done. Delete
891          *      the tardy reply from the home server, and return nothing.
892          */
893         if ((oldreq->reply->code != 0) ||
894             (oldreq->finished)) {
895                 radlog(L_ERR, "Reply from home server %s port %d  - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
896                        inet_ntop(packet->src_ipaddr.af,
897                                  &packet->src_ipaddr.ipaddr,
898                                  buffer, sizeof(buffer)),
899                        packet->src_port, packet->id,
900                        oldreq->number);
901                 rad_free(&packet);
902                 return 0;
903         }
904
905         /*
906          *      If there is already a reply, maybe this one is a
907          *      duplicate?
908          */
909         if (oldreq->proxy_reply) {
910                 if (memcmp(oldreq->proxy_reply->vector,
911                            packet->vector,
912                            sizeof(oldreq->proxy_reply->vector)) == 0) {
913                         radlog(L_ERR, "Discarding duplicate reply from home server %s port %d  - ID: %d for request %d",
914                                inet_ntop(packet->src_ipaddr.af,
915                                          &packet->src_ipaddr.ipaddr,
916                                          buffer, sizeof(buffer)),
917                                packet->src_port, packet->id,
918                                oldreq->number);
919                 } else {
920                         /*
921                          *      ? The home server gave us a new proxy
922                          *      reply, which doesn't match the old
923                          *      one.  Delete it.
924                          */
925                         DEBUG2("Ignoring conflicting proxy reply");
926                 }
927
928                 /*
929                  *      We've already received a reply, so
930                  *      we discard this one, as we don't want
931                  *      to do duplicate work.
932                  */
933                 rad_free(&packet);
934                 return 0;
935         } /* else there wasn't a proxy reply yet, so we can process it */
936
937         /*
938          *       Refresh the old request, and update it with the proxy
939          *       reply.
940          *
941          *      ? Can we delete the proxy request here?  * Is there
942          *      any more need for it?
943          *
944          *      FIXME: we probably shouldn't be updating the time
945          *      stamp here.
946          */
947         oldreq->timestamp = time_now;
948         oldreq->proxy_reply = packet;
949
950         /*
951          *      FIXME: we should really verify the digest here,
952          *      before marking this packet as a valid response.
953          *
954          *      This is a security problem, I think...
955          */
956
957         /*
958          *      Now that we've verified the packet IS actually from
959          *      that home server, and not forged, we can go mark the
960          *      entries for this home server as active.
961          *
962          *      If we had done this check in the 'find realm by IP address'
963          *      function, then an attacker could force us to use a home
964          *      server which was inactive, by forging reply packets
965          *      which didn't match any request.  We would think that
966          *      the reply meant the home server was active, would
967          *      re-activate the realms, and THEN bounce the packet
968          *      as garbage.
969          */
970         for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
971                 if (oldreq->proxy_reply->src_ipaddr.af != cl->ipaddr.af) continue;
972                 if (cl->ipaddr.af != AF_INET) continue; /* FIXME */
973
974                 if (oldreq->proxy_reply->src_ipaddr.ipaddr.ip4addr.s_addr == cl->ipaddr.ipaddr.ip4addr.s_addr) {
975                         if (oldreq->proxy_reply->src_port == cl->auth_port) {
976                                 cl->active = TRUE;
977                                 cl->last_reply = oldreq->timestamp;
978                         } else if (oldreq->proxy_reply->src_port == cl->acct_port) {
979                                 cl->acct_active = TRUE;
980                                 cl->last_reply = oldreq->timestamp;
981                         }
982                 }
983         }
984
985         rad_assert(fun != NULL);
986         *pfun = fun;
987         *prequest = oldreq;
988
989         return 1;
990 }
991
992 #define STATE_UNOPENED  (0)
993 #define STATE_UNLOCKED  (1)
994 #define STATE_HEADER    (2)
995 #define STATE_READING   (3)
996 #define STATE_DONE      (4)
997 #define STATE_WAITING   (5)
998
999 /*
1000  *      If we're limiting outstanding packets, then mark the response
1001  *      as being sent.
1002  */
1003 static int detail_send(rad_listen_t *listener, REQUEST *request)
1004 {
1005         listen_detail_t *data = listener->data;
1006
1007         rad_assert(request->listener == listener);
1008         rad_assert(listener->send == detail_send);
1009
1010         if (request->simul_max >= 0) {
1011                 rad_assert(data->outstanding != NULL);
1012                 rad_assert(request->simul_max < data->max_outstanding);
1013
1014                 data->outstanding[request->simul_max] = 0;
1015         }
1016
1017         return 0;
1018 }
1019
1020
1021 /*
1022  *      Open the detail file..
1023  *
1024  *      FIXME: create it, if it's not already there, so that the main
1025  *      server select() will wake us up if there's anything to read.
1026  */
1027 static int detail_open(rad_listen_t *this)
1028 {
1029         struct stat st;
1030         char buffer[2048];
1031         listen_detail_t *data = this->data;
1032
1033         rad_assert(data->state == STATE_UNOPENED);
1034         snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1035         
1036         /*
1037          *      FIXME: Have "one-shot" configuration, where it
1038          *      will read the detail file, and exit once it's
1039          *      done.
1040          *
1041          *      FIXME: Try harder to open the detail file.
1042          *      Maybe sleep for X usecs if it doesn't exist?
1043          */
1044
1045         /*
1046          *      Open detail.work first, so we don't lose
1047          *      accounting packets.  It's probably better to
1048          *      duplicate them than to lose them.
1049          *
1050          *      Note that we're not writing to the file, but
1051          *      we've got to open it for writing in order to
1052          *      establish the lock, to prevent rlm_detail from
1053          *      writing to it.
1054          */
1055         this->fd = open(buffer, O_RDWR);
1056         if (this->fd < 0) {
1057                 /*
1058                  *      Try reading the detail file.  If it
1059                  *      doesn't exist, we can't do anything.
1060                  *
1061                  *      Doing the stat will tell us if the file
1062                  *      exists, even if we don't have permissions
1063                  *      to read it.
1064                  */
1065                 if (stat(data->detail, &st) < 0) {
1066                         return 0;
1067                 }
1068                 
1069                 /*
1070                  *      Open it BEFORE we rename it, just to
1071                  *      be safe...
1072                  */
1073                 this->fd = open(data->detail, O_RDWR);
1074                 if (this->fd < 0) {
1075                         radlog(L_ERR, "Failed to open %s: %s",
1076                                data->detail, strerror(errno));
1077                         return 0;
1078                 }
1079                 
1080                 /*
1081                  *      Rename detail to detail.work
1082                  */
1083                 if (rename(data->detail, buffer) < 0) {
1084                         close(this->fd);
1085                         this->fd = -1;
1086                         return 0;
1087                 }
1088         } /* else detail.work existed, and we opened it */
1089         
1090         rad_assert(data->vps == NULL);
1091         
1092         rad_assert(data->fp == NULL);
1093         data->fp = fdopen(this->fd, "r");
1094         if (!data->fp) {
1095                 radlog(L_ERR, "Failed to re-open %s: %s",
1096                        data->detail, strerror(errno));
1097                 return 0;
1098         }
1099
1100         data->state = STATE_UNLOCKED;
1101
1102         data->client_ip.af = AF_UNSPEC;
1103         data->timestamp = 0;
1104         
1105         return 1;
1106 }
1107
1108 /*
1109  *      This is a bad hack, just so complaints have meaningful text.
1110  */
1111 static const RADCLIENT detail_client = {
1112         {               /* ipaddr */
1113                 AF_INET,
1114                 {{ INADDR_NONE }}
1115         },
1116         32,
1117         "<detail-file>",
1118         "secret",
1119         "UNKNOWN-CLIENT",
1120         "other",
1121         "",
1122         "",
1123         -1
1124 };
1125
1126 static int detail_recv(rad_listen_t *listener,
1127                        RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1128 {
1129         int             free_slot = -1;
1130         char            key[256], value[1024];
1131         VALUE_PAIR      *vp, **tail;
1132         RADIUS_PACKET   *packet;
1133         char            buffer[2048];
1134         listen_detail_t *data = listener->data;
1135
1136         if (data->state == STATE_UNOPENED) {
1137                 rad_assert(listener->fd < 0);
1138                 if (!detail_open(listener)) return 0;
1139         }
1140         rad_assert(listener->fd >= 0);
1141
1142         /*
1143          *      Try to lock fd.  If we can't, return.  If we can,
1144          *      continue.  This means that the server doesn't block
1145          *      while waiting for the lock to open...
1146          */
1147         if (data->state == STATE_UNLOCKED) {
1148                 /*
1149                  *      Note that we do NOT block waiting for the
1150                  *      lock.  We've re-named the file above, so we've
1151                  *      already guaranteed that any *new* detail
1152                  *      writer will not be opening this file.  The
1153                  *      only purpose of the lock is to catch a race
1154                  *      condition where the execution "ping-pongs"
1155                  *      between radiusd & radrelay.
1156                  */
1157                 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
1158                         return 0;
1159                 }
1160                 /*
1161                  *      Look for the header
1162                  */
1163                 data->state = STATE_HEADER;
1164         }
1165
1166         /*
1167          *      If we keep track of the outstanding requests, do so
1168          *      here.  Note that to minimize potential work, we do
1169          *      so only once the file is opened & locked.
1170          */
1171         if (data->max_outstanding) {
1172                 int i;
1173
1174                 for (i = 0; i < data->max_outstanding; i++) {
1175                         if (!data->outstanding[i]) {
1176                                 free_slot = i;
1177                                 break;
1178                         }
1179                 }
1180
1181                 /*
1182                  *      All of the slots are full, don't read data.
1183                  */
1184                 if (free_slot < 0) return 0;
1185         }
1186
1187         /*
1188          *      Catch an out of memory condition which will most likely
1189          *      never be met.
1190          */
1191         if (data->state == STATE_DONE) goto alloc_packet;
1192
1193         /*
1194          *      If we're in another state, then it means that we read
1195          *      a partial packet, which is bad.
1196          */
1197         rad_assert(data->state == STATE_HEADER);
1198         rad_assert(data->vps == NULL);
1199
1200         /*
1201          *      We read the last packet, and returned it for
1202          *      processing.  We later come back here to shut
1203          *      everything down, and unlink the file.
1204          */
1205         if (feof(data->fp)) {
1206                 rad_assert(data->state == STATE_HEADER);
1207
1208                 /*
1209                  *      Don't unlink the file until we've received
1210                  *      all of the responses.
1211                  */
1212                 if (data->max_outstanding > 0) {
1213                         int i;
1214
1215                         for (i = 0; i < data->max_outstanding; i++) {
1216                                 /*
1217                                  *      FIXME: close the file?
1218                                  */
1219                                 if (data->outstanding[i]) {
1220                                         data->state = STATE_WAITING;
1221                                         return 0;
1222                                 }
1223                         }
1224                 }
1225
1226         cleanup:
1227                 rad_assert(data->vps == NULL);
1228
1229                 snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1230                 unlink(buffer);
1231                 fclose(data->fp); /* closes listener->fd */
1232                 data->fp = NULL;
1233                 listener->fd = -1;
1234                 data->state = STATE_UNOPENED;
1235
1236                 /*
1237                  *      Try to open "detail" again.  If we're on a
1238                  *      busy RADIUS server, odds are that it will
1239                  *      now exist.
1240                  */
1241                 detail_open(listener);
1242                 return 0;
1243         }
1244
1245         tail = &data->vps;
1246
1247         /*
1248          *      Fill the buffer...
1249          */
1250         while (fgets(buffer, sizeof(buffer), data->fp)) {
1251                 /*
1252                  *      No CR, die.
1253                  */
1254                 if (!strchr(buffer, '\n')) {
1255                         pairfree(&data->vps);
1256                         goto cleanup;
1257                 }
1258
1259                 /*
1260                  *      We've read a header, possibly packet contents,
1261                  *      and are now at the end of the packet.
1262                  */
1263                 if ((data->state == STATE_READING) &&
1264                     (buffer[0] == '\n')) {
1265                         data->state = STATE_DONE;
1266                         break;
1267                 }
1268
1269                 /*
1270                  *      Look for date/time header, and read VP's if
1271                  *      found.  If not, keep reading lines until we
1272                  *      find one.
1273                  */
1274                 if (data->state == STATE_HEADER) {
1275                         int y;
1276                         
1277                         if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1278                                 data->state = STATE_READING;
1279                         }
1280                         continue;
1281                 }
1282
1283                 /*
1284                  *      We have a full "attribute = value" line.
1285                  *      If it doesn't look reasonable, skip it.
1286                  */
1287                 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1288                         continue;
1289                 }
1290
1291                 /*
1292                  *      Skip non-protocol attributes.
1293                  */
1294                 if (!strcasecmp(key, "Request-Authenticator")) continue;
1295
1296                 /*
1297                  *      Set the original client IP address, based on
1298                  *      what's in the detail file.
1299                  *
1300                  *      Hmm... we don't set the server IP address.
1301                  *      or port.  Oh well.
1302                  */
1303                 if (!strcasecmp(key, "Client-IP-Address")) {
1304                         data->client_ip.af = AF_INET;
1305                         ip_hton(value, AF_INET, &data->client_ip);
1306                         continue;
1307                 }
1308
1309                 /*
1310                  *      The original time at which we received the
1311                  *      packet.  We need this to properly calculate
1312                  *      Acct-Delay-Time.
1313                  */
1314                 if (!strcasecmp(key, "Timestamp")) {
1315                         data->timestamp = atoi(value);
1316                         continue;
1317                 }
1318
1319                 /*
1320                  *      Read one VP.
1321                  *
1322                  *      FIXME: do we want to check for non-protocol
1323                  *      attributes like radsqlrelay does?
1324                  */
1325                 vp = NULL;
1326                 if ((userparse(buffer, &vp) > 0) &&
1327                     (vp != NULL)) {
1328                         *tail = vp;
1329                         tail = &(vp->next);
1330                 }               
1331         }
1332
1333         /*
1334          *      We got to EOF,  If we're in STATE_HEADER, it's OK.
1335          *      Otherwise it's a problem.  In any case, nuke the file
1336          *      and start over from scratch,
1337          */
1338         if (feof(data->fp)) {
1339                 goto cleanup;
1340         }
1341
1342         /*
1343          *      FIXME: Do load management.
1344          */
1345
1346         /*
1347          *      If we're not done, then there's a problem.  The checks
1348          *      above for EOF
1349          */
1350         rad_assert(data->state == STATE_DONE);
1351
1352         /*
1353          *      The packet we read was empty, re-set the state to look
1354          *      for a header, and don't return anything.
1355          */
1356         if (!data->vps) {
1357                 data->state = STATE_HEADER;
1358                 return 0;
1359         }
1360
1361         /*
1362          *      Allocate the packet.  If we fail, it's a serious
1363          *      problem.
1364          */
1365  alloc_packet:
1366         packet = rad_alloc(1);
1367         if (!packet) {
1368                 return 0;       /* maybe memory will magically free up... */
1369         }
1370
1371         memset(packet, 0, sizeof(*packet));
1372         packet->sockfd = -1;
1373         packet->src_ipaddr.af = AF_INET;
1374         packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1375         packet->code = PW_ACCOUNTING_REQUEST;
1376         packet->timestamp = time(NULL);
1377
1378         /*
1379          *      Look for Acct-Delay-Time, and update
1380          *      based on Acct-Delay-Time += (time(NULL) - timestamp)
1381          */
1382         vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1383         if (!vp) {
1384                 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1385                 rad_assert(vp != NULL);
1386         }
1387         if (data->timestamp != 0) {
1388                 vp->lvalue += time(NULL) - data->timestamp;
1389         }
1390
1391         /*
1392          *      Remember where it came from, so that we don't
1393          *      proxy it to the place it came from...
1394          */
1395         if (data->client_ip.af != AF_UNSPEC) {
1396                 packet->src_ipaddr = data->client_ip;
1397         }
1398
1399         vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1400         if (vp) {
1401                 packet->src_ipaddr.af = AF_INET;
1402                 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1403         } else {
1404                 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1405                 if (vp) {
1406                         packet->src_ipaddr.af = AF_INET6;
1407                         memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1408                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1409                 }
1410         }
1411
1412         vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1413         if (vp) {
1414                 packet->dst_ipaddr.af = AF_INET;
1415                 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1416         } else {
1417                 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1418                 if (vp) {
1419                         packet->dst_ipaddr.af = AF_INET6;
1420                         memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1421                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1422                 }
1423         }
1424
1425         /*
1426          *      We've got to give SOME value for Id & ports, so that
1427          *      the packets can be added to the request queue.
1428          *      However, we don't want to keep track of used/unused
1429          *      id's and ports, as that's a lot of work.  This hack
1430          *      ensures that (if we have real random numbers), that
1431          *      there will be a collision on every (2^(16+16+2+24))/2
1432          *      packets, on average.  That means we can read 2^32 (4G)
1433          *      packets before having a collision, which means it's
1434          *      effectively impossible.  Having 4G packets currently
1435          *      being process is ridiculous.
1436          */
1437         packet->id = lrad_rand() & 0xff;
1438         packet->src_port = lrad_rand() & 0xffff;
1439         packet->dst_port = lrad_rand() & 0xffff;
1440
1441         packet->dst_ipaddr.af = AF_INET;
1442         packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1443
1444         packet->vps = data->vps;
1445
1446         /*
1447          *      Re-set the state.
1448          */
1449         data->vps = NULL;
1450         data->state = STATE_HEADER;
1451
1452         /*
1453          *      FIXME: many of these checks may not be necessary...
1454          */
1455         if (!common_checks(listener, packet, prequest, &detail_client)) {
1456                 rad_free(&packet);
1457                 return 0;
1458         }
1459
1460         /*
1461          *      Keep track of free slots, as a hack, in an otherwise
1462          *      unused 'int'
1463          */
1464         (*prequest)->simul_max = free_slot;
1465         if (free_slot) data->outstanding[free_slot] = 1;
1466
1467         *pfun = rad_accounting;
1468
1469         if (debug_flag) {
1470                 printf("detail_recv: Read packet from %s\n", data->detail);
1471                 for (vp = packet->vps; vp; vp = vp->next) {
1472                         putchar('\t');
1473                         vp_print(stdout, vp);
1474                         putchar('\n');
1475                 }
1476         }
1477
1478         return 1;
1479 }
1480
1481
1482 /*
1483  *      Free detail-specific stuff.
1484  */
1485 static void detail_free(rad_listen_t *this)
1486 {
1487         listen_detail_t *data = this->data;
1488
1489         free(data->detail);
1490         pairfree(&data->vps);
1491         free(data->outstanding);
1492
1493         if (data->fp != NULL) fclose(data->fp);
1494 }
1495
1496
1497 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1498 {
1499         return snprintf(buffer, bufsize, "%s",
1500                         ((listen_detail_t *)(this->data))->detail);
1501 }
1502
1503
1504 static const CONF_PARSER detail_config[] = {
1505         { "detail",   PW_TYPE_STRING_PTR,
1506           offsetof(listen_detail_t, detail), NULL,  NULL },
1507         { "max_outstanding",  PW_TYPE_INTEGER,
1508            offsetof(listen_detail_t, max_outstanding), NULL, "100" },
1509
1510         { NULL, -1, 0, NULL, NULL }             /* end the list */
1511 };
1512
1513
1514 /*
1515  *      Parse a detail section.
1516  */
1517 static int detail_parse(const char *filename, int lineno,
1518                         const CONF_SECTION *cs, rad_listen_t *this)
1519 {
1520         int             rcode;
1521         listen_detail_t *data;
1522
1523         data = this->data;
1524
1525         rcode = cf_section_parse(cs, data, detail_config);
1526         if (rcode < 0) {
1527                 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1528                        filename, lineno);
1529                 return -1;
1530         }
1531
1532         if (!data->detail) {
1533                 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1534                        filename, lineno);
1535                 return -1;
1536         }
1537         
1538         data->vps = NULL;
1539         data->fp = NULL;
1540         data->state = STATE_UNOPENED;
1541
1542         if (data->max_outstanding > 32768) data->max_outstanding = 32768;
1543
1544         if (data->max_outstanding > 0) {
1545                 data->outstanding = rad_malloc(sizeof(int) * data->max_outstanding);
1546         }
1547         
1548         detail_open(this);
1549
1550         return 0;
1551 }
1552
1553
1554 /*
1555  *      See radiusd.c & request_list.c
1556  */
1557 #define SLEEP_FOREVER (65536)
1558 /*
1559  *      A generic "update the request list once a second" function.
1560  */
1561 static int generic_update(rad_listen_t *this, time_t now)
1562 {
1563         if (!this->rl) return SLEEP_FOREVER;
1564
1565         return rl_clean_list(this->rl, now);
1566 }
1567
1568
1569
1570 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1571         { NULL, NULL, NULL, NULL, NULL, NULL},  /* RAD_LISTEN_NONE */
1572
1573         /* authentication */
1574         { common_socket_parse, NULL,
1575           auth_socket_recv, auth_socket_send,
1576           generic_update, socket_print },
1577
1578         /* accounting */
1579         { common_socket_parse, NULL,
1580           acct_socket_recv, acct_socket_send,
1581           generic_update, socket_print},
1582
1583         /* proxying */
1584         { NULL, NULL,
1585           proxy_socket_recv, proxy_socket_send,
1586           generic_update, socket_print }, /* FIXME: update func is wrong! */
1587
1588         /* detail */
1589         { detail_parse, detail_free,
1590           detail_recv, detail_send,
1591           generic_update, detail_print }
1592 };
1593
1594
1595 /*
1596  *      Binds a listener to a socket.
1597  */
1598 static int listen_bind(rad_listen_t *this)
1599 {
1600         rad_listen_t    **last;
1601         listen_socket_t *sock = this->data;
1602
1603         /*
1604          *      If the port is zero, then it means the appropriate
1605          *      thing from /etc/services.
1606          */
1607         if (sock->port == 0) {
1608                 struct servent  *svp;
1609
1610                 switch (this->type) {
1611                 case RAD_LISTEN_AUTH:
1612                         svp = getservbyname ("radius", "udp");
1613                         if (svp != NULL) {
1614                                 sock->port = ntohs(svp->s_port);
1615                         } else {
1616                                 sock->port = PW_AUTH_UDP_PORT;
1617                         }
1618                         break;
1619
1620                 case RAD_LISTEN_ACCT:
1621                         svp = getservbyname ("radacct", "udp");
1622                         if (svp != NULL) {
1623                                 sock->port = ntohs(svp->s_port);
1624                         } else {
1625                                 sock->port = PW_ACCT_UDP_PORT;
1626                         }
1627                         break;
1628
1629                 default:
1630                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1631                         return -1;
1632                 }
1633         }
1634
1635         /*
1636          *      Find it in the old list, AFTER updating the port.  If
1637          *      it's there, use that, rather than creating a new
1638          *      socket.  This allows HUP's to re-use the old sockets,
1639          *      which means that packets waiting in the socket queue
1640          *      don't get lost.
1641          */
1642         for (last = &mainconfig.listen;
1643              *last != NULL;
1644              last = &((*last)->next)) {
1645                 if ((this->type == (*last)->type) &&
1646                     (sock->port == ((listen_socket_t *)((*last)->data))->port) &&
1647                     (sock->ipaddr.af == ((listen_socket_t *)((*last)->data))->ipaddr.af)) {
1648                         int equal;
1649
1650                         if (sock->ipaddr.af == AF_INET) {
1651                                 equal = (sock->ipaddr.ipaddr.ip4addr.s_addr == ((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip4addr.s_addr);
1652                         } else if (sock->ipaddr.af == AF_INET6) {
1653                                 equal = IN6_ARE_ADDR_EQUAL(&(sock->ipaddr.ipaddr.ip6addr), &(((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip6addr));
1654                         } else {
1655                                 equal = 0;
1656                         }
1657                         
1658                         if (equal) {
1659                                 this->rl = (*last)->rl;
1660                                 this->fd = (*last)->fd;
1661                                 (*last)->fd = -1;
1662                                 (*last)->rl = NULL;
1663                                 return 0;
1664                         }
1665                 }
1666         }
1667
1668         this->fd = lrad_socket(&sock->ipaddr, sock->port);
1669         if (this->fd < 0) {
1670                 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1671                        librad_errstr);
1672                 return -1;
1673         }
1674
1675         return 0;
1676 }
1677
1678
1679 /*
1680  *      Allocate & initialize a new listener.
1681  */
1682 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1683 {
1684         rad_listen_t *this;
1685
1686         this = rad_malloc(sizeof(*this));
1687         memset(this, 0, sizeof(*this));
1688
1689         this->type = type;
1690         this->recv = master_listen[this->type].recv;
1691         this->send = master_listen[this->type].send;
1692         this->update = master_listen[this->type].update;
1693         this->print = master_listen[this->type].print;
1694
1695         switch (type) {
1696         case RAD_LISTEN_AUTH:
1697         case RAD_LISTEN_ACCT:
1698         case RAD_LISTEN_PROXY:
1699                 this->data = rad_malloc(sizeof(listen_socket_t));
1700                 memset(this->data, 0, sizeof(listen_socket_t));
1701                 break;
1702
1703         case RAD_LISTEN_DETAIL:
1704                 this->data = rad_malloc(sizeof(listen_detail_t));
1705                 memset(this->data, 0, sizeof(listen_detail_t));
1706                 
1707         default:
1708                 break;
1709         }
1710
1711         return this;
1712 }
1713
1714
1715 /*
1716  *      Externally visible function for creating a new proxy LISTENER.
1717  *
1718  *      For now, don't take ipaddr or port.
1719  *
1720  *      Not thread-safe, but all calls to it are protected by the
1721  *      proxy mutex in request_list.c
1722  */
1723 rad_listen_t *proxy_new_listener()
1724 {
1725         int last_proxy_port, port;
1726         rad_listen_t *this, *tmp, **last;
1727         listen_socket_t *sock, *old;
1728
1729         this = listen_alloc(RAD_LISTEN_PROXY);
1730
1731         /*
1732          *      Find an existing proxy socket to copy.
1733          *
1734          *      FIXME: Make it per-realm, or per-home server!
1735          */
1736         last_proxy_port = 0;
1737         old = NULL;
1738         last = &mainconfig.listen;
1739         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1740                 if (tmp->type == RAD_LISTEN_PROXY) {
1741                         sock = tmp->data;
1742                         if (sock->port > last_proxy_port) {
1743                                 last_proxy_port = sock->port + 1;
1744                         }
1745                         if (!old) old = sock;
1746                 }
1747
1748                 last = &(tmp->next);
1749         }
1750
1751         if (!old) return NULL;  /* This is a serious error. */
1752
1753         /*
1754          *      FIXME: find a new IP address to listen on?
1755          */
1756         sock = this->data;
1757         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1758
1759         /*
1760          *      Keep going until we find an unused port.
1761          */
1762         for (port = last_proxy_port; port < 64000; port++) {
1763                 sock->port = port;
1764                 if (listen_bind(this) == 0) {
1765                         /*
1766                          *      Add the new listener to the list of
1767                          *      listeners.
1768                          */
1769                         *last = this;
1770                         return this;
1771                 }
1772         }
1773
1774         return NULL;
1775 }
1776
1777
1778 static const LRAD_NAME_NUMBER listen_compare[] = {
1779         { "auth",       RAD_LISTEN_AUTH },
1780         { "acct",       RAD_LISTEN_ACCT },
1781         { "detail",     RAD_LISTEN_DETAIL },
1782         { NULL, 0 },
1783 };
1784
1785
1786 /*
1787  *      Generate a list of listeners.  Takes an input list of
1788  *      listeners, too, so we don't close sockets with waiting packets.
1789  */
1790 int listen_init(const char *filename, rad_listen_t **head)
1791 {
1792         int             rcode;
1793         CONF_SECTION    *cs;
1794         rad_listen_t    **last;
1795         rad_listen_t    *this;
1796         lrad_ipaddr_t   server_ipaddr;
1797         int             auth_port = 0;
1798
1799         /*
1800          *      We shouldn't be called with a pre-existing list.
1801          */
1802         rad_assert(head && (*head == NULL));
1803         
1804         if (start_time != 0) start_time = time(NULL);
1805
1806         last = head;
1807         server_ipaddr.af = AF_UNSPEC;
1808
1809         /*
1810          *      If the port is specified on the command-line,
1811          *      it over-rides the configuration file.
1812          */
1813         if (mainconfig.port >= 0) {
1814                 auth_port = mainconfig.port;
1815         } else {
1816                 rcode = cf_item_parse(mainconfig.config, "port",
1817                                       PW_TYPE_INTEGER, &auth_port,
1818                                       Stringify(PW_AUTH_UDP_PORT));
1819                 if (rcode < 0) return -1; /* error parsing it */
1820
1821                 if (rcode == 0)
1822                         radlog(L_INFO, "WARNING: The directive 'port' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1823         }
1824
1825         /*
1826          *      If the IP address was configured on the command-line,
1827          *      use that as the "bind_address"
1828          */
1829         if (mainconfig.myip.af != AF_UNSPEC) {
1830                 memcpy(&server_ipaddr, &mainconfig.myip,
1831                        sizeof(server_ipaddr));
1832                 goto bind_it;
1833         }
1834
1835         /*
1836          *      Else look for bind_address and/or listen sections.
1837          */
1838         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1839         rcode = cf_item_parse(mainconfig.config, "bind_address",
1840                               PW_TYPE_IPADDR,
1841                               &server_ipaddr.ipaddr.ip4addr, NULL);
1842         if (rcode < 0) return -1; /* error parsing it */
1843         
1844         if (rcode == 0) { /* successfully parsed IPv4 */
1845                 listen_socket_t *sock;
1846                 server_ipaddr.af = AF_INET;
1847
1848                 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1849
1850         bind_it:
1851                 this = listen_alloc(RAD_LISTEN_AUTH);
1852                 sock = this->data;
1853
1854                 sock->ipaddr = server_ipaddr;
1855                 sock->port = auth_port;
1856                 
1857                 if (listen_bind(this) < 0) {
1858                         listen_free(&this);
1859                         listen_free(head);
1860                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1861                         return -1;
1862                 }
1863                 auth_port = sock->port; /* may have been updated in listen_bind */
1864                 *last = this;
1865                 last = &(this->next);
1866                 
1867                 /*
1868                  *      Open Accounting Socket.
1869                  *
1870                  *      If we haven't already gotten acct_port from
1871                  *      /etc/services, then make it auth_port + 1.
1872                  */
1873                 this = listen_alloc(RAD_LISTEN_ACCT);
1874                 sock = this->data;
1875                 
1876                 /*
1877                  *      Create the accounting socket.
1878                  *
1879                  *      The accounting port is always the
1880                  *      authentication port + 1
1881                  */
1882                 sock->ipaddr = server_ipaddr;
1883                 sock->port = auth_port + 1;
1884                 
1885                 if (listen_bind(this) < 0) {
1886                         listen_free(&this);
1887                         listen_free(head);
1888                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1889                         return -1;
1890                 }
1891
1892                 *last = this;
1893                 last = &(this->next);
1894
1895         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1896                 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1897                        mainconfig.port);
1898                 return -1;
1899         }
1900
1901         /*
1902          *      They specified an IP on the command-line, ignore
1903          *      all listen sections.
1904          */
1905         if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1906
1907         /*
1908          *      Walk through the "listen" sections, if they exist.
1909          */
1910         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1911              cs != NULL;
1912              cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1913                 int             type;
1914                 char            *listen_type, *identity;
1915                 int             lineno = cf_section_lineno(cs);
1916
1917                 listen_type = identity = NULL;
1918                 
1919                 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1920                                       &listen_type, "");
1921                 if (rcode < 0) return -1;
1922                 if (rcode == 1) {
1923                         listen_free(head);
1924                         free(listen_type);
1925                         radlog(L_ERR, "%s[%d]: No type specified in listen section",
1926                                filename, lineno);
1927                         return -1;
1928                 }
1929
1930                 /*
1931                  *      See if there's an identity.
1932                  */
1933                 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1934                                       &identity, NULL);
1935                 if (rcode < 0) {
1936                         listen_free(head);
1937                         free(identity);
1938                         return -1;
1939                 }
1940
1941                 type = lrad_str2int(listen_compare, listen_type,
1942                                     RAD_LISTEN_NONE);
1943                 free(listen_type);
1944                 if (type == RAD_LISTEN_NONE) {
1945                         listen_free(head);
1946                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1947                                filename, lineno);
1948                         return -1;
1949                 }
1950
1951                 /*
1952                  *      Set up cross-type data.
1953                  */
1954                 this = listen_alloc(type);
1955                 this->identity = identity;
1956                 this->fd = -1;
1957                 
1958                 /*
1959                  *      Call per-type parser.
1960                  */
1961                 if (master_listen[type].parse(filename, lineno,
1962                                               cs, this) < 0) {
1963                         listen_free(&this);
1964                         listen_free(head);
1965                         return -1;
1966                 }
1967
1968                 *last = this;
1969                 last = &(this->next);   
1970         }
1971
1972         /*
1973          *      If we're proxying requests, open the proxy FD.
1974          *      Otherwise, don't do anything.
1975          */
1976  do_proxy:
1977         if (mainconfig.proxy_requests == TRUE) {
1978                 int             port = -1;
1979                 listen_socket_t *sock = NULL;
1980
1981                 /*
1982                  *      No sockets to receive packets, therefore
1983                  *      proxying is pointless.
1984                  */
1985                 if (!*head) return -1;
1986
1987                 /*
1988                  *      If we previously had proxy sockets, copy them
1989                  *      to the new config.
1990                  */
1991                 if (mainconfig.listen != NULL) {
1992                         rad_listen_t *old, *next, **tail;
1993
1994                         tail = &mainconfig.listen;
1995                         for (old = mainconfig.listen;
1996                              old != NULL;
1997                              old = next) {
1998                                 next = old->next;
1999
2000                                 if (old->type != RAD_LISTEN_PROXY) {
2001                                         tail = &((*tail)->next);
2002                                         continue;
2003                                 }
2004
2005                                 *last = old;
2006                                 *tail = next;
2007                                 old->next = NULL;
2008                                 last = &(old->next);
2009                         }
2010
2011                         goto done;
2012                 }
2013
2014                 /*
2015                  *      Find the first authentication port,
2016                  *      and use it
2017                  */
2018                 for (this = *head; this != NULL; this = this->next) {
2019                         if (this->type == RAD_LISTEN_AUTH) {
2020                                 sock = this->data;
2021                                 if (server_ipaddr.af == AF_UNSPEC) {
2022                                         server_ipaddr = sock->ipaddr;
2023                                 }
2024                                 port = sock->port + 2; /* skip acct port */
2025                                 break;
2026                         }
2027                 }
2028
2029                 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
2030
2031                 /*
2032                  *      Address is still unspecified, use IPv4.
2033                  */
2034                 if (server_ipaddr.af == AF_UNSPEC) {
2035                         server_ipaddr.af = AF_INET;
2036                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2037                 }
2038
2039                 this = listen_alloc(RAD_LISTEN_PROXY);
2040                 sock = this->data;
2041
2042                 /*
2043                  *      Create the first proxy socket.
2044                  */
2045                 sock->ipaddr = server_ipaddr;
2046
2047                 /*
2048                  *      Try to find a proxy port (value doesn't matter)
2049                  */
2050                 for (sock->port = port;
2051                      sock->port < 64000;
2052                      sock->port++) {
2053                         if (listen_bind(this) == 0) {
2054                                 *last = this;
2055                                 last = &(this->next); /* just in case */
2056                                 break;
2057                         }
2058                 }
2059
2060                 if (sock->port >= 64000) {
2061                         listen_free(head);
2062                         listen_free(&this);
2063                         radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
2064                         return -1;
2065                 }
2066         }
2067
2068         /*
2069          *      Sanity check the configuration.
2070          */
2071         rcode = 0;
2072         for (this = *head; this != NULL; this = this->next) {
2073                 if ((this->type != RAD_LISTEN_PROXY) &&
2074                     !this->rl) {
2075                         /*
2076                          *      FIXME: Pass type to rl_init, so that
2077                          *      it knows how to deal with accounting
2078                          *      packets.  i.e. it caches them, but
2079                          *      doesn't bother trying to re-transmit.
2080                          */
2081                         this->rl = rl_init();
2082                         if (!this->rl) {
2083                                 rad_assert(0 == 1); /* FIXME: */
2084                         }
2085                 }
2086
2087                 if (((this->type == RAD_LISTEN_ACCT) &&
2088                      (rcode == RAD_LISTEN_DETAIL)) ||
2089                     ((this->type == RAD_LISTEN_DETAIL) &&
2090                      (rcode == RAD_LISTEN_ACCT))) {
2091                         rad_assert(0 == 1); /* FIXME: configuration error */
2092                 }
2093
2094                 if (rcode != 0) continue;
2095
2096                 if ((this->type == RAD_LISTEN_ACCT) ||
2097                     (this->type == RAD_LISTEN_DETAIL)) {
2098                         rcode = this->type;
2099                 }
2100         }
2101
2102  done:
2103         return 0;
2104 }
2105
2106 /*
2107  *      Free a linked list of listeners;
2108  */
2109 void listen_free(rad_listen_t **head)
2110 {
2111         rad_listen_t *this;
2112
2113         if (!head || !*head) return;
2114
2115         this = *head;
2116         while (this) {
2117                 rad_listen_t *next = this->next;
2118                 
2119                 free(this->identity);
2120
2121                 rl_deinit(this->rl);
2122
2123                 /*
2124                  *      Other code may have eaten the FD.
2125                  */
2126                 if (this->fd >= 0) close(this->fd);
2127
2128                 if (master_listen[this->type].free) {
2129                         master_listen[this->type].free(this);
2130                 }
2131                 free(this->data);
2132                 free(this);
2133                 
2134                 this = next;
2135         }
2136
2137         *head = NULL;
2138 }