replace strNcpy strlcpy -- `cat file_list`
[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         if (!client_cs) {
561                 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
562                        filename, cf_section_lineno(cs), section_name);
563                 return -1;
564         }
565
566         sock->clients = clients_parse_section(filename, client_cs);
567         if (!sock->clients) {
568                 return -1;
569         }
570
571         return 0;
572 }
573
574 /*
575  *      Send an authentication response packet
576  */
577 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
578 {
579         rad_assert(request->listener == listener);
580         rad_assert(listener->send == auth_socket_send);
581
582         /*
583          *      Ensure that the reply is sane
584          */
585         if (request->reply->code == 0) {
586                 DEBUG2("There was no response configured: rejecting request %d", request->number);
587                 request->reply->code = PW_AUTHENTICATION_REJECT;
588         }
589
590         /*
591          *      If we're delaying authentication rejects, then
592          *      mark the request as delayed, and do NOT send a
593          *      response right now.
594          *
595          *      However, if it's already marked as delayed, then
596          *      send it now.
597          */
598         if ((request->reply->code == PW_AUTHENTICATION_REJECT) &&
599             ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) == 0) &&
600             (mainconfig.reject_delay > 0) &&
601             ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0)) {
602                 DEBUG2("Delaying request %d for %d seconds",
603                        request->number, mainconfig.reject_delay);
604                 request->options |= RAD_REQUEST_OPTION_DELAYED_REJECT;
605                 return 0;
606         }
607
608         return rad_send(request->reply, request->packet, request->secret);
609 }
610
611
612 /*
613  *      Send an accounting response packet (or not)
614  */
615 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
616 {
617         rad_assert(request->listener == listener);
618         rad_assert(listener->send == acct_socket_send);
619
620         /*
621          *      Accounting reject's are silently dropped.
622          *
623          *      We do it here to avoid polluting the rest of the
624          *      code with this knowledge
625          */
626         if (request->reply->code == 0) return 0;
627
628         return rad_send(request->reply, request->packet, request->secret);
629 }
630
631
632 /*
633  *      Send a packet to a home server.
634  *
635  *      FIXME: have different code for proxy auth & acct!
636  */
637 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
638 {
639         listen_socket_t *sock = listener->data;
640
641         rad_assert(request->proxy_listener == listener);
642         rad_assert(listener->send == proxy_socket_send);
643
644         request->proxy->src_ipaddr = sock->ipaddr;
645         request->proxy->src_port = sock->port;
646
647         return rad_send(request->proxy, request->packet, request->proxysecret);
648 }
649
650
651 /*
652  *      Check if an incoming request is "ok"
653  *
654  *      It takes packets, not requests.  It sees if the packet looks
655  *      OK.  If so, it does a number of sanity checks on it.
656   */
657 static int auth_socket_recv(rad_listen_t *listener,
658                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
659 {
660         RADIUS_PACKET   *packet;
661         RAD_REQUEST_FUNP fun = NULL;
662         char            buffer[128];
663         RADCLIENT       *client;
664
665         packet = rad_recv(listener->fd);
666         if (!packet) {
667                 radlog(L_ERR, "%s", librad_errstr);
668                 return 0;
669         }
670
671         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: auth specific */
672
673         if ((client = client_listener_find(listener,
674                                            &packet->src_ipaddr)) == NULL) {
675                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
676                 
677                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
678                        inet_ntop(packet->src_ipaddr.af,
679                                  &packet->src_ipaddr.ipaddr,
680                                  buffer, sizeof(buffer)),
681                        packet->src_port);
682                 rad_free(&packet);
683                 return 0;
684         }
685
686         /*
687          *      Some sanity checks, based on the packet code.
688          */
689         switch(packet->code) {
690         case PW_AUTHENTICATION_REQUEST:
691                 fun = rad_authenticate;
692                 break;
693                 
694         case PW_STATUS_SERVER:
695                 if (!mainconfig.status_server) {
696                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
697                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
698                         rad_free(&packet);
699                         return 0;
700                 }
701                 fun = rad_status_server;
702                 break;
703
704         default:
705                 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
706                 
707                 radlog(L_ERR, "Invalid packet code %d sent to authentication port from client %s port %d "
708                        "- ID %d : IGNORED",
709                        packet->code, client->shortname,
710                        packet->src_port, packet->id);
711                 rad_free(&packet);
712                 return 0;
713                 break;
714         } /* switch over packet types */
715         
716         if (!common_checks(listener, packet, prequest, client)) {
717                 rad_free(&packet);
718                 return 0;
719         }
720
721         *pfun = fun;
722         return 1;
723 }
724
725
726 /*
727  *      Receive packets from an accounting socket
728  */
729 static int acct_socket_recv(rad_listen_t *listener,
730         RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
731 {
732         RADIUS_PACKET   *packet;
733         RAD_REQUEST_FUNP fun = NULL;
734         char            buffer[128];
735         RADCLIENT       *client;
736         
737         packet = rad_recv(listener->fd);
738         if (!packet) {
739                 radlog(L_ERR, "%s", librad_errstr);
740                 return 0;
741         }
742         
743         RAD_SNMP_TYPE_INC(listener, total_requests); /* FIXME: acct-specific */
744
745         if ((client = client_listener_find(listener,
746                                            &packet->src_ipaddr)) == NULL) {
747                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
748                 
749                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
750                        inet_ntop(packet->src_ipaddr.af,
751                                  &packet->src_ipaddr.ipaddr,
752                                  buffer, sizeof(buffer)),
753                        packet->src_port);
754                 rad_free(&packet);
755                 return 0;
756         }
757
758         switch(packet->code) {
759         case PW_ACCOUNTING_REQUEST:
760                 fun = rad_accounting;
761                 break;
762                 
763         case PW_STATUS_SERVER:
764                 if (!mainconfig.status_server) {
765                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
766                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
767                         rad_free(&packet);
768                         return 0;
769                 }
770                 fun = rad_status_server;
771                 break;
772
773         default:
774                 /*
775                  *      FIXME: Update MIB for packet types?
776                  */
777                 radlog(L_ERR, "Invalid packet code %d sent to a accounting port "
778                        "from client %s port %d - ID %d : IGNORED",
779                        packet->code, client->shortname,
780                        packet->src_port, packet->id);
781                 rad_free(&packet);
782                 return 0;
783         }
784
785         /*
786          *      FIXME: Accounting duplicates should be handled
787          *      differently than authentication duplicates.
788          */
789         if (!common_checks(listener, packet, prequest, client)) {
790                 rad_free(&packet);
791                 return 0;
792         }
793
794         *pfun = fun;
795         return 1;
796 }
797
798
799 /*
800  *      Recieve packets from a proxy socket.
801  */
802 static int proxy_socket_recv(rad_listen_t *listener,
803                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
804 {
805         REALM           *cl;
806         REQUEST         *oldreq;
807         RADIUS_PACKET   *packet;
808         RAD_REQUEST_FUNP fun = NULL;
809         char            buffer[128];
810         
811         packet = rad_recv(listener->fd);
812         if (!packet) {
813                 radlog(L_ERR, "%s", librad_errstr);
814                 return 0;
815         }
816
817         /*
818          *      Unsupported stuff
819          */
820         if (packet->src_ipaddr.af != AF_INET) {
821                 rad_assert("PROXY IPV6 NOT SUPPORTED" == NULL);
822         }
823         
824         /*
825          *      FIXME: Add support for home servers!
826          */
827         if ((cl = realm_findbyaddr(packet->src_ipaddr.ipaddr.ip4addr.s_addr,
828                                    packet->src_port)) == NULL) {
829                 radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
830                        inet_ntop(packet->src_ipaddr.af,
831                                  &packet->src_ipaddr.ipaddr,
832                                  buffer, sizeof(buffer)),
833                                packet->src_port);
834                 rad_free(&packet);
835                 return 0;
836         }
837
838         /*
839          *      FIXME: Client MIB updates?
840          */
841         switch(packet->code) {
842         case PW_AUTHENTICATION_ACK:
843         case PW_ACCESS_CHALLENGE:
844         case PW_AUTHENTICATION_REJECT:
845                 fun = rad_authenticate;
846                 break;
847                 
848         case PW_ACCOUNTING_RESPONSE:
849                 fun = rad_accounting;
850                 break;
851                 
852         default:
853                 /*
854                  *      FIXME: Update MIB for packet types?
855                  */
856                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
857                        "from home server %s port %d - ID %d : IGNORED",
858                        packet->code,
859                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
860                        packet->src_port, packet->id);
861                 rad_free(&packet);
862                 return 0;
863         }
864
865         /*
866          *      Find the original request in the request list
867          */
868         oldreq = rl_find_proxy(packet);
869
870         /*
871          *      If we haven't found the original request which was
872          *      sent, to get this reply.  Complain, and discard this
873          *      request, as there's no way for us to send it to a NAS.
874          */
875         if (!oldreq) {
876                 radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
877                        inet_ntop(packet->src_ipaddr.af,
878                                  &packet->src_ipaddr.ipaddr,
879                                  buffer, sizeof(buffer)),
880                        packet->src_port, packet->id);
881                 rad_free(&packet);
882                 return 0;
883         }
884
885         /*
886          *      The proxy reply has arrived too late, as the original
887          *      (old) request has timed out, been rejected, and marked
888          *      as finished.  The client has already received a
889          *      response, so there is nothing that can be done. Delete
890          *      the tardy reply from the home server, and return nothing.
891          */
892         if ((oldreq->reply->code != 0) ||
893             (oldreq->finished)) {
894                 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'",
895                        inet_ntop(packet->src_ipaddr.af,
896                                  &packet->src_ipaddr.ipaddr,
897                                  buffer, sizeof(buffer)),
898                        packet->src_port, packet->id,
899                        oldreq->number);
900                 rad_free(&packet);
901                 return 0;
902         }
903
904         /*
905          *      If there is already a reply, maybe this one is a
906          *      duplicate?
907          */
908         if (oldreq->proxy_reply) {
909                 if (memcmp(oldreq->proxy_reply->vector,
910                            packet->vector,
911                            sizeof(oldreq->proxy_reply->vector)) == 0) {
912                         radlog(L_ERR, "Discarding duplicate reply from home server %s port %d  - ID: %d for request %d",
913                                inet_ntop(packet->src_ipaddr.af,
914                                          &packet->src_ipaddr.ipaddr,
915                                          buffer, sizeof(buffer)),
916                                packet->src_port, packet->id,
917                                oldreq->number);
918                 } else {
919                         /*
920                          *      ? The home server gave us a new proxy
921                          *      reply, which doesn't match the old
922                          *      one.  Delete it.
923                          */
924                         DEBUG2("Ignoring conflicting proxy reply");
925                 }
926
927                 /*
928                  *      We've already received a reply, so
929                  *      we discard this one, as we don't want
930                  *      to do duplicate work.
931                  */
932                 rad_free(&packet);
933                 return 0;
934         } /* else there wasn't a proxy reply yet, so we can process it */
935
936         /*
937          *       Refresh the old request, and update it with the proxy
938          *       reply.
939          *
940          *      ? Can we delete the proxy request here?  * Is there
941          *      any more need for it?
942          *
943          *      FIXME: we probably shouldn't be updating the time
944          *      stamp here.
945          */
946         oldreq->timestamp = time_now;
947         oldreq->proxy_reply = packet;
948
949         /*
950          *      FIXME: we should really verify the digest here,
951          *      before marking this packet as a valid response.
952          *
953          *      This is a security problem, I think...
954          */
955
956         /*
957          *      Now that we've verified the packet IS actually from
958          *      that home server, and not forged, we can go mark the
959          *      entries for this home server as active.
960          *
961          *      If we had done this check in the 'find realm by IP address'
962          *      function, then an attacker could force us to use a home
963          *      server which was inactive, by forging reply packets
964          *      which didn't match any request.  We would think that
965          *      the reply meant the home server was active, would
966          *      re-activate the realms, and THEN bounce the packet
967          *      as garbage.
968          */
969         for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
970                 if (oldreq->proxy_reply->src_ipaddr.af != cl->ipaddr.af) continue;
971                 if (cl->ipaddr.af != AF_INET) continue; /* FIXME */
972
973                 if (oldreq->proxy_reply->src_ipaddr.ipaddr.ip4addr.s_addr == cl->ipaddr.ipaddr.ip4addr.s_addr) {
974                         if (oldreq->proxy_reply->src_port == cl->auth_port) {
975                                 cl->active = TRUE;
976                                 cl->last_reply = oldreq->timestamp;
977                         } else if (oldreq->proxy_reply->src_port == cl->acct_port) {
978                                 cl->acct_active = TRUE;
979                                 cl->last_reply = oldreq->timestamp;
980                         }
981                 }
982         }
983
984         rad_assert(fun != NULL);
985         *pfun = fun;
986         *prequest = oldreq;
987
988         return 1;
989 }
990
991 #define STATE_UNOPENED  (0)
992 #define STATE_UNLOCKED  (1)
993 #define STATE_HEADER    (2)
994 #define STATE_READING   (3)
995 #define STATE_DONE      (4)
996 #define STATE_WAITING   (5)
997
998 /*
999  *      If we're limiting outstanding packets, then mark the response
1000  *      as being sent.
1001  */
1002 static int detail_send(rad_listen_t *listener, REQUEST *request)
1003 {
1004         listen_detail_t *data = listener->data;
1005
1006         rad_assert(request->listener == listener);
1007         rad_assert(listener->send == detail_send);
1008
1009         if (request->simul_max >= 0) {
1010                 rad_assert(data->outstanding != NULL);
1011                 rad_assert(request->simul_max < data->max_outstanding);
1012
1013                 data->outstanding[request->simul_max] = 0;
1014         }
1015
1016         return 0;
1017 }
1018
1019
1020 /*
1021  *      Open the detail file..
1022  *
1023  *      FIXME: create it, if it's not already there, so that the main
1024  *      server select() will wake us up if there's anything to read.
1025  */
1026 static int detail_open(rad_listen_t *this)
1027 {
1028         struct stat st;
1029         char buffer[2048];
1030         listen_detail_t *data = this->data;
1031
1032         rad_assert(data->state == STATE_UNOPENED);
1033         snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1034         
1035         /*
1036          *      FIXME: Have "one-shot" configuration, where it
1037          *      will read the detail file, and exit once it's
1038          *      done.
1039          *
1040          *      FIXME: Try harder to open the detail file.
1041          *      Maybe sleep for X usecs if it doesn't exist?
1042          */
1043
1044         /*
1045          *      Open detail.work first, so we don't lose
1046          *      accounting packets.  It's probably better to
1047          *      duplicate them than to lose them.
1048          *
1049          *      Note that we're not writing to the file, but
1050          *      we've got to open it for writing in order to
1051          *      establish the lock, to prevent rlm_detail from
1052          *      writing to it.
1053          */
1054         this->fd = open(buffer, O_RDWR);
1055         if (this->fd < 0) {
1056                 /*
1057                  *      Try reading the detail file.  If it
1058                  *      doesn't exist, we can't do anything.
1059                  *
1060                  *      Doing the stat will tell us if the file
1061                  *      exists, even if we don't have permissions
1062                  *      to read it.
1063                  */
1064                 if (stat(data->detail, &st) < 0) {
1065                         return 0;
1066                 }
1067                 
1068                 /*
1069                  *      Open it BEFORE we rename it, just to
1070                  *      be safe...
1071                  */
1072                 this->fd = open(data->detail, O_RDWR);
1073                 if (this->fd < 0) {
1074                         radlog(L_ERR, "Failed to open %s: %s",
1075                                data->detail, strerror(errno));
1076                         return 0;
1077                 }
1078                 
1079                 /*
1080                  *      Rename detail to detail.work
1081                  */
1082                 if (rename(data->detail, buffer) < 0) {
1083                         close(this->fd);
1084                         this->fd = -1;
1085                         return 0;
1086                 }
1087         } /* else detail.work existed, and we opened it */
1088         
1089         rad_assert(data->vps == NULL);
1090         
1091         rad_assert(data->fp == NULL);
1092         data->fp = fdopen(this->fd, "r");
1093         if (!data->fp) {
1094                 radlog(L_ERR, "Failed to re-open %s: %s",
1095                        data->detail, strerror(errno));
1096                 return 0;
1097         }
1098
1099         data->state = STATE_UNLOCKED;
1100
1101         data->client_ip.af = AF_UNSPEC;
1102         data->timestamp = 0;
1103         
1104         return 1;
1105 }
1106
1107 /*
1108  *      This is a bad hack, just so complaints have meaningful text.
1109  */
1110 static const RADCLIENT detail_client = {
1111         {               /* ipaddr */
1112                 AF_INET,
1113                 {{ INADDR_NONE }}
1114         },
1115         32,
1116         "<detail-file>",
1117         "secret",
1118         "UNKNOWN-CLIENT",
1119         "other",
1120         "",
1121         "",
1122         -1
1123 };
1124
1125 static int detail_recv(rad_listen_t *listener,
1126                        RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1127 {
1128         int             free_slot = -1;
1129         char            key[256], value[1024];
1130         VALUE_PAIR      *vp, **tail;
1131         RADIUS_PACKET   *packet;
1132         char            buffer[2048];
1133         listen_detail_t *data = listener->data;
1134
1135         if (data->state == STATE_UNOPENED) {
1136                 rad_assert(listener->fd < 0);
1137                 if (!detail_open(listener)) return 0;
1138         }
1139         rad_assert(listener->fd >= 0);
1140
1141         /*
1142          *      Try to lock fd.  If we can't, return.  If we can,
1143          *      continue.  This means that the server doesn't block
1144          *      while waiting for the lock to open...
1145          */
1146         if (data->state == STATE_UNLOCKED) {
1147                 /*
1148                  *      Note that we do NOT block waiting for the
1149                  *      lock.  We've re-named the file above, so we've
1150                  *      already guaranteed that any *new* detail
1151                  *      writer will not be opening this file.  The
1152                  *      only purpose of the lock is to catch a race
1153                  *      condition where the execution "ping-pongs"
1154                  *      between radiusd & radrelay.
1155                  */
1156                 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
1157                         return 0;
1158                 }
1159                 /*
1160                  *      Look for the header
1161                  */
1162                 data->state = STATE_HEADER;
1163         }
1164
1165         /*
1166          *      If we keep track of the outstanding requests, do so
1167          *      here.  Note that to minimize potential work, we do
1168          *      so only once the file is opened & locked.
1169          */
1170         if (data->max_outstanding) {
1171                 int i;
1172
1173                 for (i = 0; i < data->max_outstanding; i++) {
1174                         if (!data->outstanding[i]) {
1175                                 free_slot = i;
1176                                 break;
1177                         }
1178                 }
1179
1180                 /*
1181                  *      All of the slots are full, don't read data.
1182                  */
1183                 if (free_slot < 0) return 0;
1184         }
1185
1186         /*
1187          *      Catch an out of memory condition which will most likely
1188          *      never be met.
1189          */
1190         if (data->state == STATE_DONE) goto alloc_packet;
1191
1192         /*
1193          *      If we're in another state, then it means that we read
1194          *      a partial packet, which is bad.
1195          */
1196         rad_assert(data->state == STATE_HEADER);
1197         rad_assert(data->vps == NULL);
1198
1199         /*
1200          *      We read the last packet, and returned it for
1201          *      processing.  We later come back here to shut
1202          *      everything down, and unlink the file.
1203          */
1204         if (feof(data->fp)) {
1205                 rad_assert(data->state == STATE_HEADER);
1206
1207                 /*
1208                  *      Don't unlink the file until we've received
1209                  *      all of the responses.
1210                  */
1211                 if (data->max_outstanding > 0) {
1212                         int i;
1213
1214                         for (i = 0; i < data->max_outstanding; i++) {
1215                                 /*
1216                                  *      FIXME: close the file?
1217                                  */
1218                                 if (data->outstanding[i]) {
1219                                         data->state = STATE_WAITING;
1220                                         return 0;
1221                                 }
1222                         }
1223                 }
1224
1225         cleanup:
1226                 rad_assert(data->vps == NULL);
1227
1228                 snprintf(buffer, sizeof(buffer), "%s.work", data->detail);
1229                 unlink(buffer);
1230                 fclose(data->fp); /* closes listener->fd */
1231                 data->fp = NULL;
1232                 listener->fd = -1;
1233                 data->state = STATE_UNOPENED;
1234
1235                 /*
1236                  *      Try to open "detail" again.  If we're on a
1237                  *      busy RADIUS server, odds are that it will
1238                  *      now exist.
1239                  */
1240                 detail_open(listener);
1241                 return 0;
1242         }
1243
1244         tail = &data->vps;
1245
1246         /*
1247          *      Fill the buffer...
1248          */
1249         while (fgets(buffer, sizeof(buffer), data->fp)) {
1250                 /*
1251                  *      No CR, die.
1252                  */
1253                 if (!strchr(buffer, '\n')) {
1254                         pairfree(&data->vps);
1255                         goto cleanup;
1256                 }
1257
1258                 /*
1259                  *      We've read a header, possibly packet contents,
1260                  *      and are now at the end of the packet.
1261                  */
1262                 if ((data->state == STATE_READING) &&
1263                     (buffer[0] == '\n')) {
1264                         data->state = STATE_DONE;
1265                         break;
1266                 }
1267
1268                 /*
1269                  *      Look for date/time header, and read VP's if
1270                  *      found.  If not, keep reading lines until we
1271                  *      find one.
1272                  */
1273                 if (data->state == STATE_HEADER) {
1274                         int y;
1275                         
1276                         if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1277                                 data->state = STATE_READING;
1278                         }
1279                         continue;
1280                 }
1281
1282                 /*
1283                  *      We have a full "attribute = value" line.
1284                  *      If it doesn't look reasonable, skip it.
1285                  */
1286                 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1287                         continue;
1288                 }
1289
1290                 /*
1291                  *      Skip non-protocol attributes.
1292                  */
1293                 if (!strcasecmp(key, "Request-Authenticator")) continue;
1294
1295                 /*
1296                  *      Set the original client IP address, based on
1297                  *      what's in the detail file.
1298                  *
1299                  *      Hmm... we don't set the server IP address.
1300                  *      or port.  Oh well.
1301                  */
1302                 if (!strcasecmp(key, "Client-IP-Address")) {
1303                         data->client_ip.af = AF_INET;
1304                         ip_hton(value, AF_INET, &data->client_ip);
1305                         continue;
1306                 }
1307
1308                 /*
1309                  *      The original time at which we received the
1310                  *      packet.  We need this to properly calculate
1311                  *      Acct-Delay-Time.
1312                  */
1313                 if (!strcasecmp(key, "Timestamp")) {
1314                         data->timestamp = atoi(value);
1315                         continue;
1316                 }
1317
1318                 /*
1319                  *      Read one VP.
1320                  *
1321                  *      FIXME: do we want to check for non-protocol
1322                  *      attributes like radsqlrelay does?
1323                  */
1324                 vp = NULL;
1325                 if ((userparse(buffer, &vp) > 0) &&
1326                     (vp != NULL)) {
1327                         *tail = vp;
1328                         tail = &(vp->next);
1329                 }               
1330         }
1331
1332         /*
1333          *      We got to EOF,  If we're in STATE_HEADER, it's OK.
1334          *      Otherwise it's a problem.  In any case, nuke the file
1335          *      and start over from scratch,
1336          */
1337         if (feof(data->fp)) {
1338                 goto cleanup;
1339         }
1340
1341         /*
1342          *      FIXME: Do load management.
1343          */
1344
1345         /*
1346          *      If we're not done, then there's a problem.  The checks
1347          *      above for EOF
1348          */
1349         rad_assert(data->state == STATE_DONE);
1350
1351         /*
1352          *      The packet we read was empty, re-set the state to look
1353          *      for a header, and don't return anything.
1354          */
1355         if (!data->vps) {
1356                 data->state = STATE_HEADER;
1357                 return 0;
1358         }
1359
1360         /*
1361          *      Allocate the packet.  If we fail, it's a serious
1362          *      problem.
1363          */
1364  alloc_packet:
1365         packet = rad_alloc(1);
1366         if (!packet) {
1367                 return 0;       /* maybe memory will magically free up... */
1368         }
1369
1370         memset(packet, 0, sizeof(*packet));
1371         packet->sockfd = -1;
1372         packet->src_ipaddr.af = AF_INET;
1373         packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1374         packet->code = PW_ACCOUNTING_REQUEST;
1375         packet->timestamp = time(NULL);
1376
1377         /*
1378          *      Look for Acct-Delay-Time, and update
1379          *      based on Acct-Delay-Time += (time(NULL) - timestamp)
1380          */
1381         vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1382         if (!vp) {
1383                 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1384                 rad_assert(vp != NULL);
1385         }
1386         if (data->timestamp != 0) {
1387                 vp->lvalue += time(NULL) - data->timestamp;
1388         }
1389
1390         /*
1391          *      Remember where it came from, so that we don't
1392          *      proxy it to the place it came from...
1393          */
1394         if (data->client_ip.af != AF_UNSPEC) {
1395                 packet->src_ipaddr = data->client_ip;
1396         }
1397
1398         vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1399         if (vp) {
1400                 packet->src_ipaddr.af = AF_INET;
1401                 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1402         } else {
1403                 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1404                 if (vp) {
1405                         packet->src_ipaddr.af = AF_INET6;
1406                         memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1407                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1408                 }
1409         }
1410
1411         vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1412         if (vp) {
1413                 packet->dst_ipaddr.af = AF_INET;
1414                 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
1415         } else {
1416                 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1417                 if (vp) {
1418                         packet->dst_ipaddr.af = AF_INET6;
1419                         memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1420                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1421                 }
1422         }
1423
1424         /*
1425          *      We've got to give SOME value for Id & ports, so that
1426          *      the packets can be added to the request queue.
1427          *      However, we don't want to keep track of used/unused
1428          *      id's and ports, as that's a lot of work.  This hack
1429          *      ensures that (if we have real random numbers), that
1430          *      there will be a collision on every (2^(16+16+2+24))/2
1431          *      packets, on average.  That means we can read 2^32 (4G)
1432          *      packets before having a collision, which means it's
1433          *      effectively impossible.  Having 4G packets currently
1434          *      being process is ridiculous.
1435          */
1436         packet->id = lrad_rand() & 0xff;
1437         packet->src_port = lrad_rand() & 0xffff;
1438         packet->dst_port = lrad_rand() & 0xffff;
1439
1440         packet->dst_ipaddr.af = AF_INET;
1441         packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1442
1443         packet->vps = data->vps;
1444
1445         /*
1446          *      Re-set the state.
1447          */
1448         data->vps = NULL;
1449         data->state = STATE_HEADER;
1450
1451         /*
1452          *      FIXME: many of these checks may not be necessary...
1453          */
1454         if (!common_checks(listener, packet, prequest, &detail_client)) {
1455                 rad_free(&packet);
1456                 return 0;
1457         }
1458
1459         /*
1460          *      Keep track of free slots, as a hack, in an otherwise
1461          *      unused 'int'
1462          */
1463         (*prequest)->simul_max = free_slot;
1464         if (free_slot) data->outstanding[free_slot] = 1;
1465
1466         *pfun = rad_accounting;
1467
1468         if (debug_flag) {
1469                 printf("detail_recv: Read packet from %s\n", data->detail);
1470                 for (vp = packet->vps; vp; vp = vp->next) {
1471                         putchar('\t');
1472                         vp_print(stdout, vp);
1473                         putchar('\n');
1474                 }
1475         }
1476
1477         return 1;
1478 }
1479
1480
1481 /*
1482  *      Free detail-specific stuff.
1483  */
1484 static void detail_free(rad_listen_t *this)
1485 {
1486         listen_detail_t *data = this->data;
1487
1488         free(data->detail);
1489         pairfree(&data->vps);
1490         free(data->outstanding);
1491
1492         if (data->fp != NULL) fclose(data->fp);
1493 }
1494
1495
1496 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1497 {
1498         return snprintf(buffer, bufsize, "%s",
1499                         ((listen_detail_t *)(this->data))->detail);
1500 }
1501
1502
1503 static const CONF_PARSER detail_config[] = {
1504         { "detail",   PW_TYPE_STRING_PTR,
1505           offsetof(listen_detail_t, detail), NULL,  NULL },
1506         { "max_outstanding",  PW_TYPE_INTEGER,
1507            offsetof(listen_detail_t, max_outstanding), NULL, "100" },
1508
1509         { NULL, -1, 0, NULL, NULL }             /* end the list */
1510 };
1511
1512
1513 /*
1514  *      Parse a detail section.
1515  */
1516 static int detail_parse(const char *filename, int lineno,
1517                         const CONF_SECTION *cs, rad_listen_t *this)
1518 {
1519         int             rcode;
1520         listen_detail_t *data;
1521
1522         data = this->data;
1523
1524         rcode = cf_section_parse(cs, data, detail_config);
1525         if (rcode < 0) {
1526                 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1527                        filename, lineno);
1528                 return -1;
1529         }
1530
1531         if (!data->detail) {
1532                 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1533                        filename, lineno);
1534                 return -1;
1535         }
1536         
1537         data->vps = NULL;
1538         data->fp = NULL;
1539         data->state = STATE_UNOPENED;
1540
1541         if (data->max_outstanding > 32768) data->max_outstanding = 32768;
1542
1543         if (data->max_outstanding > 0) {
1544                 data->outstanding = rad_malloc(sizeof(int) * data->max_outstanding);
1545         }
1546         
1547         detail_open(this);
1548
1549         return 0;
1550 }
1551
1552
1553 /*
1554  *      See radiusd.c & request_list.c
1555  */
1556 #define SLEEP_FOREVER (65536)
1557 /*
1558  *      A generic "update the request list once a second" function.
1559  */
1560 static int generic_update(rad_listen_t *this, time_t now)
1561 {
1562         if (!this->rl) return SLEEP_FOREVER;
1563
1564         return rl_clean_list(this->rl, now);
1565 }
1566
1567
1568
1569 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1570         { NULL, NULL, NULL, NULL, NULL, NULL},  /* RAD_LISTEN_NONE */
1571
1572         /* authentication */
1573         { common_socket_parse, NULL,
1574           auth_socket_recv, auth_socket_send,
1575           generic_update, socket_print },
1576
1577         /* accounting */
1578         { common_socket_parse, NULL,
1579           acct_socket_recv, acct_socket_send,
1580           generic_update, socket_print},
1581
1582         /* proxying */
1583         { NULL, NULL,
1584           proxy_socket_recv, proxy_socket_send,
1585           generic_update, socket_print }, /* FIXME: update func is wrong! */
1586
1587         /* detail */
1588         { detail_parse, detail_free,
1589           detail_recv, detail_send,
1590           generic_update, detail_print }
1591 };
1592
1593
1594 /*
1595  *      Binds a listener to a socket.
1596  */
1597 static int listen_bind(rad_listen_t *this)
1598 {
1599         rad_listen_t    **last;
1600         listen_socket_t *sock = this->data;
1601
1602         /*
1603          *      If the port is zero, then it means the appropriate
1604          *      thing from /etc/services.
1605          */
1606         if (sock->port == 0) {
1607                 struct servent  *svp;
1608
1609                 switch (this->type) {
1610                 case RAD_LISTEN_AUTH:
1611                         svp = getservbyname ("radius", "udp");
1612                         if (svp != NULL) {
1613                                 sock->port = ntohs(svp->s_port);
1614                         } else {
1615                                 sock->port = PW_AUTH_UDP_PORT;
1616                         }
1617                         break;
1618
1619                 case RAD_LISTEN_ACCT:
1620                         svp = getservbyname ("radacct", "udp");
1621                         if (svp != NULL) {
1622                                 sock->port = ntohs(svp->s_port);
1623                         } else {
1624                                 sock->port = PW_ACCT_UDP_PORT;
1625                         }
1626                         break;
1627
1628                 default:
1629                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1630                         return -1;
1631                 }
1632         }
1633
1634         /*
1635          *      Find it in the old list, AFTER updating the port.  If
1636          *      it's there, use that, rather than creating a new
1637          *      socket.  This allows HUP's to re-use the old sockets,
1638          *      which means that packets waiting in the socket queue
1639          *      don't get lost.
1640          */
1641         for (last = &mainconfig.listen;
1642              *last != NULL;
1643              last = &((*last)->next)) {
1644                 if ((this->type == (*last)->type) &&
1645                     (sock->port == ((listen_socket_t *)((*last)->data))->port) &&
1646                     (sock->ipaddr.af == ((listen_socket_t *)((*last)->data))->ipaddr.af)) {
1647                         int equal;
1648
1649                         if (sock->ipaddr.af == AF_INET) {
1650                                 equal = (sock->ipaddr.ipaddr.ip4addr.s_addr == ((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip4addr.s_addr);
1651                         } else if (sock->ipaddr.af == AF_INET6) {
1652                                 equal = IN6_ARE_ADDR_EQUAL(&(sock->ipaddr.ipaddr.ip6addr), &(((listen_socket_t *)((*last)->data))->ipaddr.ipaddr.ip6addr));
1653                         } else {
1654                                 equal = 0;
1655                         }
1656                         
1657                         if (equal) {
1658                                 this->rl = (*last)->rl;
1659                                 this->fd = (*last)->fd;
1660                                 (*last)->fd = -1;
1661                                 (*last)->rl = NULL;
1662                                 return 0;
1663                         }
1664                 }
1665         }
1666
1667         this->fd = lrad_socket(&sock->ipaddr, sock->port);
1668         if (this->fd < 0) {
1669                 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1670                        librad_errstr);
1671                 return -1;
1672         }
1673
1674         return 0;
1675 }
1676
1677
1678 /*
1679  *      Allocate & initialize a new listener.
1680  */
1681 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1682 {
1683         rad_listen_t *this;
1684
1685         this = rad_malloc(sizeof(*this));
1686         memset(this, 0, sizeof(*this));
1687
1688         this->type = type;
1689         this->recv = master_listen[this->type].recv;
1690         this->send = master_listen[this->type].send;
1691         this->update = master_listen[this->type].update;
1692         this->print = master_listen[this->type].print;
1693
1694         switch (type) {
1695         case RAD_LISTEN_AUTH:
1696         case RAD_LISTEN_ACCT:
1697         case RAD_LISTEN_PROXY:
1698                 this->data = rad_malloc(sizeof(listen_socket_t));
1699                 memset(this->data, 0, sizeof(listen_socket_t));
1700                 break;
1701
1702         case RAD_LISTEN_DETAIL:
1703                 this->data = rad_malloc(sizeof(listen_detail_t));
1704                 memset(this->data, 0, sizeof(listen_detail_t));
1705                 
1706         default:
1707                 break;
1708         }
1709
1710         return this;
1711 }
1712
1713
1714 /*
1715  *      Externally visible function for creating a new proxy LISTENER.
1716  *
1717  *      For now, don't take ipaddr or port.
1718  *
1719  *      Not thread-safe, but all calls to it are protected by the
1720  *      proxy mutex in request_list.c
1721  */
1722 rad_listen_t *proxy_new_listener()
1723 {
1724         int last_proxy_port, port;
1725         rad_listen_t *this, *tmp, **last;
1726         listen_socket_t *sock, *old;
1727
1728         this = listen_alloc(RAD_LISTEN_PROXY);
1729
1730         /*
1731          *      Find an existing proxy socket to copy.
1732          *
1733          *      FIXME: Make it per-realm, or per-home server!
1734          */
1735         last_proxy_port = 0;
1736         old = NULL;
1737         last = &mainconfig.listen;
1738         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1739                 if (tmp->type == RAD_LISTEN_PROXY) {
1740                         sock = tmp->data;
1741                         if (sock->port > last_proxy_port) {
1742                                 last_proxy_port = sock->port + 1;
1743                         }
1744                         if (!old) old = sock;
1745                 }
1746
1747                 last = &(tmp->next);
1748         }
1749
1750         if (!old) return NULL;  /* This is a serious error. */
1751
1752         /*
1753          *      FIXME: find a new IP address to listen on?
1754          */
1755         sock = this->data;
1756         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1757
1758         /*
1759          *      Keep going until we find an unused port.
1760          */
1761         for (port = last_proxy_port; port < 64000; port++) {
1762                 sock->port = port;
1763                 if (listen_bind(this) == 0) {
1764                         /*
1765                          *      Add the new listener to the list of
1766                          *      listeners.
1767                          */
1768                         *last = this;
1769                         return this;
1770                 }
1771         }
1772
1773         return NULL;
1774 }
1775
1776
1777 static const LRAD_NAME_NUMBER listen_compare[] = {
1778         { "auth",       RAD_LISTEN_AUTH },
1779         { "acct",       RAD_LISTEN_ACCT },
1780         { "detail",     RAD_LISTEN_DETAIL },
1781         { NULL, 0 },
1782 };
1783
1784
1785 /*
1786  *      Generate a list of listeners.  Takes an input list of
1787  *      listeners, too, so we don't close sockets with waiting packets.
1788  */
1789 int listen_init(const char *filename, rad_listen_t **head)
1790 {
1791         int             rcode;
1792         CONF_SECTION    *cs;
1793         rad_listen_t    **last;
1794         rad_listen_t    *this;
1795         lrad_ipaddr_t   server_ipaddr;
1796         int             auth_port = 0;
1797
1798         /*
1799          *      We shouldn't be called with a pre-existing list.
1800          */
1801         rad_assert(head && (*head == NULL));
1802         
1803         if (start_time != 0) start_time = time(NULL);
1804
1805         last = head;
1806         server_ipaddr.af = AF_UNSPEC;
1807
1808         /*
1809          *      If the port is specified on the command-line,
1810          *      it over-rides the configuration file.
1811          */
1812         if (mainconfig.port >= 0) {
1813                 auth_port = mainconfig.port;
1814         } else {
1815                 rcode = cf_item_parse(mainconfig.config, "port",
1816                                       PW_TYPE_INTEGER, &auth_port,
1817                                       Stringify(PW_AUTH_UDP_PORT));
1818                 if (rcode < 0) return -1; /* error parsing it */
1819
1820                 if (rcode == 0)
1821                         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'.");
1822         }
1823
1824         /*
1825          *      If the IP address was configured on the command-line,
1826          *      use that as the "bind_address"
1827          */
1828         if (mainconfig.myip.af != AF_UNSPEC) {
1829                 memcpy(&server_ipaddr, &mainconfig.myip,
1830                        sizeof(server_ipaddr));
1831                 goto bind_it;
1832         }
1833
1834         /*
1835          *      Else look for bind_address and/or listen sections.
1836          */
1837         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1838         rcode = cf_item_parse(mainconfig.config, "bind_address",
1839                               PW_TYPE_IPADDR,
1840                               &server_ipaddr.ipaddr.ip4addr, NULL);
1841         if (rcode < 0) return -1; /* error parsing it */
1842         
1843         if (rcode == 0) { /* successfully parsed IPv4 */
1844                 listen_socket_t *sock;
1845                 server_ipaddr.af = AF_INET;
1846
1847                 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'.");
1848
1849         bind_it:
1850                 this = listen_alloc(RAD_LISTEN_AUTH);
1851                 sock = this->data;
1852
1853                 sock->ipaddr = server_ipaddr;
1854                 sock->port = auth_port;
1855                 
1856                 if (listen_bind(this) < 0) {
1857                         listen_free(&this);
1858                         listen_free(head);
1859                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1860                         return -1;
1861                 }
1862                 auth_port = sock->port; /* may have been updated in listen_bind */
1863                 *last = this;
1864                 last = &(this->next);
1865                 
1866                 /*
1867                  *      Open Accounting Socket.
1868                  *
1869                  *      If we haven't already gotten acct_port from
1870                  *      /etc/services, then make it auth_port + 1.
1871                  */
1872                 this = listen_alloc(RAD_LISTEN_ACCT);
1873                 sock = this->data;
1874                 
1875                 /*
1876                  *      Create the accounting socket.
1877                  *
1878                  *      The accounting port is always the
1879                  *      authentication port + 1
1880                  */
1881                 sock->ipaddr = server_ipaddr;
1882                 sock->port = auth_port + 1;
1883                 
1884                 if (listen_bind(this) < 0) {
1885                         listen_free(&this);
1886                         listen_free(head);
1887                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1888                         return -1;
1889                 }
1890
1891                 *last = this;
1892                 last = &(this->next);
1893
1894         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1895                 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1896                        mainconfig.port);
1897                 return -1;
1898         }
1899
1900         /*
1901          *      They specified an IP on the command-line, ignore
1902          *      all listen sections.
1903          */
1904         if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1905
1906         /*
1907          *      Walk through the "listen" sections, if they exist.
1908          */
1909         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1910              cs != NULL;
1911              cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1912                 int             type;
1913                 char            *listen_type, *identity;
1914                 int             lineno = cf_section_lineno(cs);
1915
1916                 listen_type = identity = NULL;
1917                 
1918                 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1919                                       &listen_type, "");
1920                 if (rcode < 0) return -1;
1921                 if (rcode == 1) {
1922                         listen_free(head);
1923                         free(listen_type);
1924                         radlog(L_ERR, "%s[%d]: No type specified in listen section",
1925                                filename, lineno);
1926                         return -1;
1927                 }
1928
1929                 /*
1930                  *      See if there's an identity.
1931                  */
1932                 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1933                                       &identity, NULL);
1934                 if (rcode < 0) {
1935                         listen_free(head);
1936                         free(identity);
1937                         return -1;
1938                 }
1939
1940                 type = lrad_str2int(listen_compare, listen_type,
1941                                     RAD_LISTEN_NONE);
1942                 free(listen_type);
1943                 if (type == RAD_LISTEN_NONE) {
1944                         listen_free(head);
1945                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1946                                filename, lineno);
1947                         return -1;
1948                 }
1949
1950                 /*
1951                  *      Set up cross-type data.
1952                  */
1953                 this = listen_alloc(type);
1954                 this->identity = identity;
1955                 this->fd = -1;
1956                 
1957                 /*
1958                  *      Call per-type parser.
1959                  */
1960                 if (master_listen[type].parse(filename, lineno,
1961                                               cs, this) < 0) {
1962                         listen_free(&this);
1963                         listen_free(head);
1964                         return -1;
1965                 }
1966
1967                 *last = this;
1968                 last = &(this->next);   
1969         }
1970
1971         /*
1972          *      If we're proxying requests, open the proxy FD.
1973          *      Otherwise, don't do anything.
1974          */
1975  do_proxy:
1976         if (mainconfig.proxy_requests == TRUE) {
1977                 int             port = -1;
1978                 listen_socket_t *sock = NULL;
1979
1980                 /*
1981                  *      No sockets to receive packets, therefore
1982                  *      proxying is pointless.
1983                  */
1984                 if (!*head) return -1;
1985
1986                 /*
1987                  *      If we previously had proxy sockets, copy them
1988                  *      to the new config.
1989                  */
1990                 if (mainconfig.listen != NULL) {
1991                         rad_listen_t *old, *next, **tail;
1992
1993                         tail = &mainconfig.listen;
1994                         for (old = mainconfig.listen;
1995                              old != NULL;
1996                              old = next) {
1997                                 next = old->next;
1998
1999                                 if (old->type != RAD_LISTEN_PROXY) {
2000                                         tail = &((*tail)->next);
2001                                         continue;
2002                                 }
2003
2004                                 *last = old;
2005                                 *tail = next;
2006                                 old->next = NULL;
2007                                 last = &(old->next);
2008                         }
2009
2010                         goto done;
2011                 }
2012
2013                 /*
2014                  *      Find the first authentication port,
2015                  *      and use it
2016                  */
2017                 for (this = *head; this != NULL; this = this->next) {
2018                         if (this->type == RAD_LISTEN_AUTH) {
2019                                 sock = this->data;
2020                                 if (server_ipaddr.af == AF_UNSPEC) {
2021                                         server_ipaddr = sock->ipaddr;
2022                                 }
2023                                 port = sock->port + 2; /* skip acct port */
2024                                 break;
2025                         }
2026                 }
2027
2028                 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
2029
2030                 /*
2031                  *      Address is still unspecified, use IPv4.
2032                  */
2033                 if (server_ipaddr.af == AF_UNSPEC) {
2034                         server_ipaddr.af = AF_INET;
2035                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2036                 }
2037
2038                 this = listen_alloc(RAD_LISTEN_PROXY);
2039                 sock = this->data;
2040
2041                 /*
2042                  *      Create the first proxy socket.
2043                  */
2044                 sock->ipaddr = server_ipaddr;
2045
2046                 /*
2047                  *      Try to find a proxy port (value doesn't matter)
2048                  */
2049                 for (sock->port = port;
2050                      sock->port < 64000;
2051                      sock->port++) {
2052                         if (listen_bind(this) == 0) {
2053                                 *last = this;
2054                                 last = &(this->next); /* just in case */
2055                                 break;
2056                         }
2057                 }
2058
2059                 if (sock->port >= 64000) {
2060                         listen_free(head);
2061                         listen_free(&this);
2062                         radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
2063                         return -1;
2064                 }
2065         }
2066
2067         /*
2068          *      Sanity check the configuration.
2069          */
2070         rcode = 0;
2071         for (this = *head; this != NULL; this = this->next) {
2072                 if ((this->type != RAD_LISTEN_PROXY) &&
2073                     !this->rl) {
2074                         /*
2075                          *      FIXME: Pass type to rl_init, so that
2076                          *      it knows how to deal with accounting
2077                          *      packets.  i.e. it caches them, but
2078                          *      doesn't bother trying to re-transmit.
2079                          */
2080                         this->rl = rl_init();
2081                         if (!this->rl) {
2082                                 rad_assert(0 == 1); /* FIXME: */
2083                         }
2084                 }
2085
2086                 if (((this->type == RAD_LISTEN_ACCT) &&
2087                      (rcode == RAD_LISTEN_DETAIL)) ||
2088                     ((this->type == RAD_LISTEN_DETAIL) &&
2089                      (rcode == RAD_LISTEN_ACCT))) {
2090                         rad_assert(0 == 1); /* FIXME: configuration error */
2091                 }
2092
2093                 if (rcode != 0) continue;
2094
2095                 if ((this->type == RAD_LISTEN_ACCT) ||
2096                     (this->type == RAD_LISTEN_DETAIL)) {
2097                         rcode = this->type;
2098                 }
2099         }
2100
2101  done:
2102         return 0;
2103 }
2104
2105 /*
2106  *      Free a linked list of listeners;
2107  */
2108 void listen_free(rad_listen_t **head)
2109 {
2110         rad_listen_t *this;
2111
2112         if (!head || !*head) return;
2113
2114         this = *head;
2115         while (this) {
2116                 rad_listen_t *next = this->next;
2117                 
2118                 free(this->identity);
2119
2120                 rl_deinit(this->rl);
2121
2122                 /*
2123                  *      Other code may have eaten the FD.
2124                  */
2125                 if (this->fd >= 0) close(this->fd);
2126
2127                 if (master_listen[this->type].free) {
2128                         master_listen[this->type].free(this);
2129                 }
2130                 free(this->data);
2131                 free(this);
2132                 
2133                 this = next;
2134         }
2135
2136         *head = NULL;
2137 }