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