Note issue as reported in bug #622
[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/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/rad_assert.h>
30 #include <freeradius-devel/vqp.h>
31 #include <freeradius-devel/dhcp.h>
32
33 #include <freeradius-devel/vmps.h>
34 #include <freeradius-devel/detail.h>
35
36 #ifdef HAVE_SYS_RESOURCE_H
37 #include <sys/resource.h>
38 #endif
39
40 #ifdef HAVE_NET_IF_H
41 #include <net/if.h>
42 #endif
43
44 #ifdef HAVE_FCNTL_H
45 #include <fcntl.h>
46 #endif
47
48
49 /*
50  *      We'll use this below.
51  */
52 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
53 typedef void (*rad_listen_free_t)(rad_listen_t *);
54
55 typedef struct rad_listen_master_t {
56         rad_listen_parse_t      parse;
57         rad_listen_free_t       free;
58         rad_listen_recv_t       recv;
59         rad_listen_send_t       send;
60         rad_listen_print_t      print;
61         rad_listen_encode_t     encode;
62         rad_listen_decode_t     decode;
63 } rad_listen_master_t;
64
65 typedef struct listen_socket_t {
66         /*
67          *      For normal sockets.
68          */
69         fr_ipaddr_t     ipaddr;
70         int             port;
71 #ifdef SO_BINDTODEVICE
72         const char              *interface;
73 #endif
74         RADCLIENT_LIST  *clients;
75 } listen_socket_t;
76
77 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
78
79 /*
80  *      Find a per-socket client.
81  */
82 RADCLIENT *client_listener_find(const rad_listen_t *listener,
83                                 const fr_ipaddr_t *ipaddr, int src_port)
84 {
85 #ifdef WITH_DYNAMIC_CLIENTS
86         int rcode;
87         listen_socket_t *sock;
88         REQUEST *request;
89         RADCLIENT *created;
90 #endif
91         time_t now;
92         RADCLIENT *client;
93         RADCLIENT_LIST *clients;
94
95         rad_assert(listener != NULL);
96         rad_assert(ipaddr != NULL);
97
98         rad_assert((listener->type == RAD_LISTEN_AUTH)
99 #ifdef WITH_STATS
100                    || (listener->type == RAD_LISTEN_NONE)
101 #endif
102 #ifdef WITH_ACCOUNTING
103                    || (listener->type == RAD_LISTEN_ACCT)
104 #endif
105 #ifdef WITH_VMPS
106                    || (listener->type == RAD_LISTEN_VQP)
107 #endif
108 #ifdef WITH_DHCP
109                    || (listener->type == RAD_LISTEN_DHCP)
110 #endif
111                    );
112
113         clients = ((listen_socket_t *)listener->data)->clients;
114
115         /*
116          *      This HAS to have been initialized previously.
117          */
118         rad_assert(clients != NULL);
119
120         client = client_find(clients, ipaddr);
121         if (!client) {
122                 static time_t last_printed = 0;
123                 char name[256], buffer[128];
124                                         
125 #ifdef WITH_DYNAMIC_CLIENTS
126         unknown:                /* used only for dynamic clients */
127 #endif
128
129                 /*
130                  *      DoS attack quenching, but only in debug mode.
131                  *      If they're running in debug mode, show them
132                  *      every packet.
133                  */
134                 if (debug_flag == 0) {
135                         now = time(NULL);
136                         if (last_printed == now) return NULL;
137                         
138                         last_printed = now;
139                 }
140
141                 listener->print(listener, name, sizeof(name));
142
143                 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d",
144                        name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
145                                        buffer, sizeof(buffer)),
146                        src_port);
147                 return NULL;
148         }
149
150 #ifndef WITH_DYNAMIC_CLIENTS
151         return client;          /* return the found client. */
152 #else
153
154         /*
155          *      No server defined, and it's not dynamic.  Return it.
156          */
157         if (!client->client_server && !client->dynamic) return client;
158
159         now = time(NULL);
160         
161         /*
162          *      It's a dynamically generated client, check it.
163          */
164         if (client->dynamic) {
165                 /*
166                  *      Lives forever.  Return it.
167                  */
168                 if (client->lifetime == 0) return client;
169                 
170                 /*
171                  *      Rate-limit the deletion of known clients.
172                  *      This makes them last a little longer, but
173                  *      prevents the server from melting down if (say)
174                  *      10k clients all expire at once.
175                  */
176                 if (now == client->last_new_client) return client;
177
178                 /*
179                  *      It's not dead yet.  Return it.
180                  */
181                 if ((client->created + client->lifetime) > now) return client;
182                 
183                 /*
184                  *      FIXME: Don't delete it until after the last
185                  *      request using it has expired.  i.e. keep a
186                  *      "use counter" (ugh).  Why can't we use a
187                  *      language with garbage collection?
188                  *      
189                  */
190                 client_delete(clients, client);
191
192                 /*
193                  *      Go find the enclosing network again.
194                  */
195                 client = client_find(clients, ipaddr);
196
197                 /*
198                  *      WTF?
199                  */
200                 if (!client) goto unknown;
201                 if (!client->client_server) goto unknown;
202
203                 /*
204                  *      At this point, 'client' is the enclosing
205                  *      network that configures where dynamic clients
206                  *      can be defined.
207                  */
208                 rad_assert(client->dynamic == 0);
209         } else {
210                 /*
211                  *      The IP is unknown, so we've found an enclosing
212                  *      network.  Enable DoS protection.  We only
213                  *      allow one new client per second.  Known
214                  *      clients aren't subject to this restriction.
215                  */
216                 if (now == client->last_new_client) goto unknown;
217         }
218
219         client->last_new_client = now;
220
221         request = request_alloc();
222         if (!request) goto unknown;
223
224         request->listener = listener;
225         request->client = client;
226         request->packet = rad_alloc(0);
227         if (!request->packet) {
228                 request_free(&request);
229                 goto unknown;
230         }
231         request->reply = rad_alloc(0);
232         if (!request->reply) {
233                 request_free(&request);
234                 goto unknown;
235         }
236         request->packet->timestamp = request->timestamp;
237         request->number = 0;
238         request->priority = listener->type;
239         request->server = client->client_server;
240         request->root = &mainconfig;
241
242         /*
243          *      Run a fake request through the given virtual server.
244          *      Look for FreeRADIUS-Client-IP-Address
245          *               FreeRADIUS-Client-Secret
246          *              ...
247          *
248          *      and create the RADCLIENT structure from that.
249          */
250
251         sock = listener->data;
252         request->packet->sockfd = listener->fd;
253         request->packet->src_ipaddr = *ipaddr;
254         request->packet->src_port = 0; /* who cares... */
255         request->packet->dst_ipaddr = sock->ipaddr;
256         request->packet->dst_port = sock->port;
257
258         request->reply->sockfd = request->packet->sockfd;
259         request->reply->dst_ipaddr = request->packet->src_ipaddr;
260         request->reply->src_ipaddr = request->packet->dst_ipaddr;
261         request->reply->dst_port = request->packet->src_port;
262         request->reply->src_port = request->packet->dst_port;
263         request->reply->id = request->packet->id;
264         request->reply->code = 0; /* UNKNOWN code */
265
266         
267         DEBUG("server %s {", request->server);
268
269         rcode = module_authorize(0, request);
270
271         DEBUG("} # server %s", request->server);
272
273         if (rcode != RLM_MODULE_OK) {
274                 request_free(&request);
275                 goto unknown;
276         }
277
278         /*
279          *      If the client was updated by rlm_dynamic_clients,
280          *      don't create the client from attribute-value pairs.
281          */
282         if (request->client == client) {
283                 created = client_create(clients, request);
284         } else {
285                 created = request->client;
286
287                 /*
288                  *      This frees the client if it isn't valid.
289                  */
290                 if (!client_validate(clients, client, created)) goto unknown;
291         }
292         request_free(&request);
293
294         if (!created) goto unknown;
295
296         return created;
297 #endif
298 }
299
300 static int listen_bind(rad_listen_t *this);
301
302
303 /*
304  *      Process and reply to a server-status request.
305  *      Like rad_authenticate and rad_accounting this should
306  *      live in it's own file but it's so small we don't bother.
307  */
308 static int rad_status_server(REQUEST *request)
309 {
310         int rcode = RLM_MODULE_OK;
311         DICT_VALUE *dval;
312
313         switch (request->listener->type) {
314 #ifdef WITH_STATS
315         case RAD_LISTEN_NONE:
316 #endif
317         case RAD_LISTEN_AUTH:
318                 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
319                 if (dval) {
320                         rcode = module_authorize(dval->value, request);
321                 } else {
322                         rcode = RLM_MODULE_OK;
323                 }
324
325                 switch (rcode) {
326                 case RLM_MODULE_OK:
327                 case RLM_MODULE_UPDATED:
328                         request->reply->code = PW_AUTHENTICATION_ACK;
329                         break;
330
331                 case RLM_MODULE_FAIL:
332                 case RLM_MODULE_HANDLED:
333                         request->reply->code = 0; /* don't reply */
334                         break;
335
336                 default:
337                 case RLM_MODULE_REJECT:
338                         request->reply->code = PW_AUTHENTICATION_REJECT;
339                         break;
340                 }
341                 break;
342
343 #ifdef WITH_ACCOUNTING
344         case RAD_LISTEN_ACCT:
345                 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
346                 if (dval) {
347                         rcode = module_accounting(dval->value, request);
348                 } else {
349                         rcode = RLM_MODULE_OK;
350                 }
351
352                 switch (rcode) {
353                 case RLM_MODULE_OK:
354                 case RLM_MODULE_UPDATED:
355                         request->reply->code = PW_ACCOUNTING_RESPONSE;
356                         break;
357
358                 default:
359                         request->reply->code = 0; /* don't reply */
360                         break;
361                 }
362                 break;
363 #endif
364
365         default:
366                 return 0;
367         }
368
369 #ifdef WITH_STATS
370         /*
371          *      Full statistics are available only on a statistics
372          *      socket.
373          */
374         if (request->listener->type == RAD_LISTEN_NONE) {
375                 request_stats_reply(request);
376         }
377 #endif
378
379         return 0;
380 }
381
382
383 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
384 {
385         size_t len;
386         listen_socket_t *sock = this->data;
387         const char *name;
388
389         switch (this->type) {
390 #ifdef WITH_STATS
391         case RAD_LISTEN_NONE:   /* what a hack... */
392                 name = "status";
393                 break;
394 #endif
395
396         case RAD_LISTEN_AUTH:
397                 name = "authentication";
398                 break;
399
400 #ifdef WITH_ACCOUNTING
401         case RAD_LISTEN_ACCT:
402                 name = "accounting";
403                 break;
404 #endif
405
406 #ifdef WITH_PROXY
407         case RAD_LISTEN_PROXY:
408                 name = "proxy";
409                 break;
410 #endif
411
412 #ifdef WITH_VMPS
413         case RAD_LISTEN_VQP:
414                 name = "vmps";
415                 break;
416 #endif
417
418 #ifdef WITH_DHCP
419         case RAD_LISTEN_DHCP:
420                 name = "dhcp";
421                 break;
422 #endif
423
424         default:
425                 name = "??";
426                 break;
427         }
428
429 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
430 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
431
432         ADDSTRING(name);
433
434 #ifdef SO_BINDTODEVICE
435         if (sock->interface) {
436                 ADDSTRING(" interface ");
437                 ADDSTRING(sock->interface);
438         }
439 #endif
440
441         ADDSTRING(" address ");
442         
443         if ((sock->ipaddr.af == AF_INET) &&
444             (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
445                 strlcpy(buffer, "*", bufsize);
446         } else {
447                 ip_ntoh(&sock->ipaddr, buffer, bufsize);
448         }
449         FORWARD;
450
451         ADDSTRING(" port ");
452         snprintf(buffer, bufsize, "%d", sock->port);
453         FORWARD;
454
455         if (this->server) {
456                 ADDSTRING(" as server ");
457                 ADDSTRING(this->server);
458         }
459
460 #undef ADDSTRING
461 #undef FORWARD
462
463         return 1;
464 }
465
466
467 /*
468  *      Parse an authentication or accounting socket.
469  */
470 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
471 {
472         int             rcode;
473         int             listen_port;
474         fr_ipaddr_t     ipaddr;
475         listen_socket_t *sock = this->data;
476         char            *section_name = NULL;
477         CONF_SECTION    *client_cs, *parentcs;
478
479         /*
480          *      Try IPv4 first
481          */
482         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
483         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
484                               &ipaddr.ipaddr.ip4addr, NULL);
485         if (rcode < 0) return -1;
486
487         if (rcode == 0) { /* successfully parsed IPv4 */
488                 ipaddr.af = AF_INET;
489
490         } else {        /* maybe IPv6? */
491                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
492                                       &ipaddr.ipaddr.ip6addr, NULL);
493                 if (rcode < 0) return -1;
494
495                 if (rcode == 1) {
496                         cf_log_err(cf_sectiontoitem(cs),
497                                    "No address specified in listen section");
498                         return -1;
499                 }
500                 ipaddr.af = AF_INET6;
501         }
502
503         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
504                               &listen_port, "0");
505         if (rcode < 0) return -1;
506
507         if ((listen_port < 0) || (listen_port > 65535)) {
508                         cf_log_err(cf_sectiontoitem(cs),
509                                    "Invalid value for \"port\"");
510                         return -1;
511         }
512
513         sock->ipaddr = ipaddr;
514         sock->port = listen_port;
515
516         /*
517          *      If we can bind to interfaces, do so,
518          *      else don't.
519          */
520         if (cf_pair_find(cs, "interface")) {
521 #ifndef SO_BINDTODEVICE
522                 cf_log_err(cf_sectiontoitem(cs),
523                            "System does not support binding to interfaces.  Delete this line from the configuration file.");
524                 return -1;
525 #else
526                 const char *value;
527                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
528
529                 rad_assert(cp != NULL);
530                 value = cf_pair_value(cp);
531                 if (!value) {
532                         cf_log_err(cf_sectiontoitem(cs),
533                                    "No interface name given");
534                         return -1;
535                 }
536                 sock->interface = value;
537 #endif
538         }
539
540         /*
541          *      And bind it to the port.
542          */
543         if (listen_bind(this) < 0) {
544                 char buffer[128];
545                 cf_log_err(cf_sectiontoitem(cs),
546                            "Error binding to port for %s port %d",
547                            ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
548                            sock->port);
549                 return -1;
550         }
551
552 #ifdef WITH_PROXY
553         /*
554          *      Proxy sockets don't have clients.
555          */
556         if (this->type == RAD_LISTEN_PROXY) return 0;
557 #endif
558         
559         /*
560          *      The more specific configurations are preferred to more
561          *      generic ones.
562          */
563         client_cs = NULL;
564         parentcs = cf_top_section(cs);
565         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
566                               &section_name, NULL);
567         if (rcode < 0) return -1; /* bad string */
568         if (rcode == 0) {
569                 /*
570                  *      Explicit list given: use it.
571                  */
572                 client_cs = cf_section_sub_find_name2(parentcs,
573                                                       "clients",
574                                                       section_name);
575                 if (!client_cs) {
576                         client_cs = cf_section_find(section_name);
577                 }
578                 if (!client_cs) {
579                         cf_log_err(cf_sectiontoitem(cs),
580                                    "Failed to find clients %s {...}",
581                                    section_name);
582                         free(section_name);
583                         return -1;
584                 }
585                 free(section_name);
586         } /* else there was no "clients = " entry. */
587
588         if (!client_cs) {
589                 CONF_SECTION *server_cs;
590
591                 server_cs = cf_section_sub_find_name2(parentcs,
592                                                       "server",
593                                                       this->server);
594                 /*
595                  *      Found a "server foo" section.  If there are clients
596                  *      in it, use them.
597                  */
598                 if (server_cs &&
599                     (cf_section_sub_find(server_cs, "client") != NULL)) {
600                         client_cs = server_cs;
601                 }
602         }
603
604         /*
605          *      Still nothing.  Look for global clients.
606          */
607         if (!client_cs) client_cs = parentcs;
608
609         sock->clients = clients_parse_section(client_cs);
610         if (!sock->clients) {
611                 cf_log_err(cf_sectiontoitem(cs),
612                            "Failed to load clients for this listen section");
613                 return -1;
614         }
615
616         return 0;
617 }
618
619 /*
620  *      Send an authentication response packet
621  */
622 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
623 {
624         rad_assert(request->listener == listener);
625         rad_assert(listener->send == auth_socket_send);
626
627         return rad_send(request->reply, request->packet,
628                         request->client->secret);
629 }
630
631
632 #ifdef WITH_ACCOUNTING
633 /*
634  *      Send an accounting response packet (or not)
635  */
636 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
637 {
638         rad_assert(request->listener == listener);
639         rad_assert(listener->send == acct_socket_send);
640
641         /*
642          *      Accounting reject's are silently dropped.
643          *
644          *      We do it here to avoid polluting the rest of the
645          *      code with this knowledge
646          */
647         if (request->reply->code == 0) return 0;
648
649         return rad_send(request->reply, request->packet,
650                         request->client->secret);
651 }
652 #endif
653
654 #ifdef WITH_PROXY
655 /*
656  *      Send a packet to a home server.
657  *
658  *      FIXME: have different code for proxy auth & acct!
659  */
660 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
661 {
662         listen_socket_t *sock = listener->data;
663
664         rad_assert(request->proxy_listener == listener);
665         rad_assert(listener->send == proxy_socket_send);
666
667         request->proxy->src_ipaddr = sock->ipaddr;
668         request->proxy->src_port = sock->port;
669
670         return rad_send(request->proxy, request->packet,
671                         request->home_server->secret);
672 }
673 #endif
674
675 #ifdef WITH_STATS
676 /*
677  *      Check if an incoming request is "ok"
678  *
679  *      It takes packets, not requests.  It sees if the packet looks
680  *      OK.  If so, it does a number of sanity checks on it.
681   */
682 static int stats_socket_recv(rad_listen_t *listener,
683                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
684 {
685         ssize_t         rcode;
686         int             code, src_port;
687         RADIUS_PACKET   *packet;
688         RADCLIENT       *client;
689         fr_ipaddr_t     src_ipaddr;
690
691         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
692         if (rcode < 0) return 0;
693
694         RAD_STATS_TYPE_INC(listener, total_requests);
695
696         if (rcode < 20) {       /* AUTH_HDR_LEN */
697                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
698                 return 0;
699         }
700
701         if ((client = client_listener_find(listener,
702                                            &src_ipaddr, src_port)) == NULL) {
703                 rad_recv_discard(listener->fd);
704                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
705                 return 0;
706         }
707
708         /*
709          *      We only understand Status-Server on this socket.
710          */
711         if (code != PW_STATUS_SERVER) {
712                 DEBUG("Ignoring packet code %d sent to Status-Server port",
713                       code);
714                 rad_recv_discard(listener->fd);
715                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
716                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
717                 return 0;
718         }
719
720         /*
721          *      Now that we've sanity checked everything, receive the
722          *      packet.
723          */
724         packet = rad_recv(listener->fd, 1); /* require message authenticator */
725         if (!packet) {
726                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
727                 DEBUG("%s", fr_strerror());
728                 return 0;
729         }
730
731         if (!received_request(listener, packet, prequest, client)) {
732                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
733                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
734                 rad_free(&packet);
735                 return 0;
736         }
737
738         *pfun = rad_status_server;
739         return 1;
740 }
741 #endif
742
743
744 /*
745  *      Check if an incoming request is "ok"
746  *
747  *      It takes packets, not requests.  It sees if the packet looks
748  *      OK.  If so, it does a number of sanity checks on it.
749   */
750 static int auth_socket_recv(rad_listen_t *listener,
751                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
752 {
753         ssize_t         rcode;
754         int             code, src_port;
755         RADIUS_PACKET   *packet;
756         RAD_REQUEST_FUNP fun = NULL;
757         RADCLIENT       *client;
758         fr_ipaddr_t     src_ipaddr;
759
760         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
761         if (rcode < 0) return 0;
762
763         RAD_STATS_TYPE_INC(listener, total_requests);
764
765         if (rcode < 20) {       /* AUTH_HDR_LEN */
766                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
767                 return 0;
768         }
769
770         if ((client = client_listener_find(listener,
771                                            &src_ipaddr, src_port)) == NULL) {
772                 rad_recv_discard(listener->fd);
773                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
774                 return 0;
775         }
776
777         /*
778          *      Some sanity checks, based on the packet code.
779          */
780         switch(code) {
781         case PW_AUTHENTICATION_REQUEST:
782                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
783                 fun = rad_authenticate;
784                 break;
785
786         case PW_STATUS_SERVER:
787                 if (!mainconfig.status_server) {
788                         rad_recv_discard(listener->fd);
789                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
790                         RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
791                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
792                         return 0;
793                 }
794                 fun = rad_status_server;
795                 break;
796
797         default:
798                 rad_recv_discard(listener->fd);
799                 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
800                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
801
802                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
803                       code, client->shortname, src_port);
804                 return 0;
805                 break;
806         } /* switch over packet types */
807
808         /*
809          *      Now that we've sanity checked everything, receive the
810          *      packet.
811          */
812         packet = rad_recv(listener->fd, client->message_authenticator);
813         if (!packet) {
814                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
815                 DEBUG("%s", fr_strerror());
816                 return 0;
817         }
818
819         if (!received_request(listener, packet, prequest, client)) {
820                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
821                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
822                 rad_free(&packet);
823                 return 0;
824         }
825
826         *pfun = fun;
827         return 1;
828 }
829
830
831 #ifdef WITH_ACCOUNTING
832 /*
833  *      Receive packets from an accounting socket
834  */
835 static int acct_socket_recv(rad_listen_t *listener,
836                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
837 {
838         ssize_t         rcode;
839         int             code, src_port;
840         RADIUS_PACKET   *packet;
841         RAD_REQUEST_FUNP fun = NULL;
842         RADCLIENT       *client;
843         fr_ipaddr_t     src_ipaddr;
844
845         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
846         if (rcode < 0) return 0;
847
848         RAD_STATS_TYPE_INC(listener, total_requests);
849
850         if (rcode < 20) {       /* AUTH_HDR_LEN */
851                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
852                 return 0;
853         }
854
855         if ((client = client_listener_find(listener,
856                                            &src_ipaddr, src_port)) == NULL) {
857                 rad_recv_discard(listener->fd);
858                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
859                 return 0;
860         }
861
862         /*
863          *      Some sanity checks, based on the packet code.
864          */
865         switch(code) {
866         case PW_ACCOUNTING_REQUEST:
867                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
868                 fun = rad_accounting;
869                 break;
870
871         case PW_STATUS_SERVER:
872                 if (!mainconfig.status_server) {
873                         rad_recv_discard(listener->fd);
874                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
875                         RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
876
877                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
878                         return 0;
879                 }
880                 fun = rad_status_server;
881                 break;
882
883         default:
884                 rad_recv_discard(listener->fd);
885                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
886                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
887
888                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
889                       code, client->shortname, src_port);
890                 return 0;
891         } /* switch over packet types */
892
893         /*
894          *      Now that we've sanity checked everything, receive the
895          *      packet.
896          */
897         packet = rad_recv(listener->fd, 0);
898         if (!packet) {
899                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
900                 radlog(L_ERR, "%s", fr_strerror());
901                 return 0;
902         }
903
904         /*
905          *      There can be no duplicate accounting packets.
906          */
907         if (!received_request(listener, packet, prequest, client)) {
908                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
909                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
910                 rad_free(&packet);
911                 return 0;
912         }
913
914         *pfun = fun;
915         return 1;
916 }
917 #endif
918
919
920 #ifdef WITH_COA
921 /*
922  *      For now, all CoA requests are *only* originated, and not
923  *      proxied.  So all of the necessary work is done in the
924  *      post-proxy section, which is automatically handled by event.c.
925  *      As a result, we don't have to do anything here.
926  */
927 static int rad_coa_reply(REQUEST *request)
928 {
929         VALUE_PAIR *s1, *s2;
930
931         /*
932          *      Inform the user about RFC requirements.
933          */
934         s1 = pairfind(request->proxy->vps, PW_STATE);
935         if (s1) {
936                 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
937
938                 if (!s2) {
939                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
940
941                 } else if ((s1->length != s2->length) ||
942                            (memcmp(s1->vp_octets, s2->vp_octets,
943                                    s1->length) != 0)) {
944                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
945                 }
946         }
947
948         return RLM_MODULE_OK;
949 }
950 #endif
951
952 #ifdef WITH_PROXY
953 /*
954  *      Recieve packets from a proxy socket.
955  */
956 static int proxy_socket_recv(rad_listen_t *listener,
957                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
958 {
959         REQUEST         *request;
960         RADIUS_PACKET   *packet;
961         RAD_REQUEST_FUNP fun = NULL;
962         char            buffer[128];
963
964         packet = rad_recv(listener->fd, 0);
965         if (!packet) {
966                 radlog(L_ERR, "%s", fr_strerror());
967                 return 0;
968         }
969
970         /*
971          *      FIXME: Client MIB updates?
972          */
973         switch(packet->code) {
974         case PW_AUTHENTICATION_ACK:
975         case PW_ACCESS_CHALLENGE:
976         case PW_AUTHENTICATION_REJECT:
977                 fun = rad_authenticate;
978                 break;
979
980 #ifdef WITH_ACCOUNTING
981         case PW_ACCOUNTING_RESPONSE:
982                 fun = rad_accounting;
983                 break;
984 #endif
985
986 #ifdef WITH_COA
987         case PW_DISCONNECT_ACK:
988         case PW_DISCONNECT_NAK:
989         case PW_COA_ACK:
990         case PW_COA_NAK:
991                 fun = rad_coa_reply;
992                 break;
993 #endif
994
995         default:
996                 /*
997                  *      FIXME: Update MIB for packet types?
998                  */
999                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1000                        "from home server %s port %d - ID %d : IGNORED",
1001                        packet->code,
1002                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1003                        packet->src_port, packet->id);
1004                 rad_free(&packet);
1005                 return 0;
1006         }
1007
1008         request = received_proxy_response(packet);
1009         if (!request) {
1010                 rad_free(&packet);
1011                 return 0;
1012         }
1013
1014         rad_assert(fun != NULL);
1015         *pfun = fun;
1016         *prequest = request;
1017
1018         return 1;
1019 }
1020 #endif
1021
1022
1023 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1024 {
1025         if (!request->reply->code) return 0;
1026
1027         rad_encode(request->reply, request->packet,
1028                    request->client->secret);
1029         rad_sign(request->reply, request->packet,
1030                  request->client->secret);
1031
1032         return 0;
1033 }
1034
1035
1036 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1037 {
1038         if (rad_verify(request->packet, NULL,
1039                        request->client->secret) < 0) {
1040                 return -1;
1041         }
1042
1043         return rad_decode(request->packet, NULL,
1044                           request->client->secret);
1045 }
1046
1047 #ifdef WITH_PROXY
1048 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1049 {
1050         rad_encode(request->proxy, NULL, request->home_server->secret);
1051         rad_sign(request->proxy, NULL, request->home_server->secret);
1052
1053         return 0;
1054 }
1055
1056
1057 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1058 {
1059         if (rad_verify(request->proxy_reply, request->proxy,
1060                        request->home_server->secret) < 0) {
1061                 return -1;
1062         }
1063
1064         return rad_decode(request->proxy_reply, request->proxy,
1065                            request->home_server->secret);
1066 }
1067 #endif
1068
1069 #include "dhcpd.c"
1070
1071 #include "command.c"
1072
1073 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1074 #ifdef WITH_STATS
1075         { common_socket_parse, NULL,
1076           stats_socket_recv, auth_socket_send,
1077           socket_print, client_socket_encode, client_socket_decode },
1078 #else
1079         /*
1080          *      This always gets defined.
1081          */
1082         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1083 #endif
1084
1085 #ifdef WITH_PROXY
1086         /* proxying */
1087         { common_socket_parse, NULL,
1088           proxy_socket_recv, proxy_socket_send,
1089           socket_print, proxy_socket_encode, proxy_socket_decode },
1090 #endif
1091
1092         /* authentication */
1093         { common_socket_parse, NULL,
1094           auth_socket_recv, auth_socket_send,
1095           socket_print, client_socket_encode, client_socket_decode },
1096
1097 #ifdef WITH_ACCOUNTING
1098         /* accounting */
1099         { common_socket_parse, NULL,
1100           acct_socket_recv, acct_socket_send,
1101           socket_print, client_socket_encode, client_socket_decode},
1102 #endif
1103
1104 #ifdef WITH_DETAIL
1105         /* detail */
1106         { detail_parse, detail_free,
1107           detail_recv, detail_send,
1108           detail_print, detail_encode, detail_decode },
1109 #endif
1110
1111 #ifdef WITH_VMPS
1112         /* vlan query protocol */
1113         { common_socket_parse, NULL,
1114           vqp_socket_recv, vqp_socket_send,
1115           socket_print, vqp_socket_encode, vqp_socket_decode },
1116 #endif
1117
1118 #ifdef WITH_DHCP
1119         /* dhcp query protocol */
1120         { dhcp_socket_parse, NULL,
1121           dhcp_socket_recv, dhcp_socket_send,
1122           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1123 #endif
1124
1125 #ifdef WITH_COMMAND_SOCKET
1126         /* TCP command socket */
1127         { command_socket_parse, NULL,
1128           command_domain_accept, command_domain_send,
1129           command_socket_print, command_socket_encode, command_socket_decode },
1130 #endif
1131
1132 };
1133
1134
1135
1136 /*
1137  *      Binds a listener to a socket.
1138  */
1139 static int listen_bind(rad_listen_t *this)
1140 {
1141         int rcode;
1142         struct sockaddr_storage salocal;
1143         socklen_t       salen;
1144         listen_socket_t *sock = this->data;
1145
1146         /*
1147          *      If the port is zero, then it means the appropriate
1148          *      thing from /etc/services.
1149          */
1150         if (sock->port == 0) {
1151                 struct servent  *svp;
1152
1153                 switch (this->type) {
1154                 case RAD_LISTEN_AUTH:
1155                         svp = getservbyname ("radius", "udp");
1156                         if (svp != NULL) {
1157                                 sock->port = ntohs(svp->s_port);
1158                         } else {
1159                                 sock->port = PW_AUTH_UDP_PORT;
1160                         }
1161                         break;
1162
1163 #ifdef WITH_ACCOUNTING
1164                 case RAD_LISTEN_ACCT:
1165                         svp = getservbyname ("radacct", "udp");
1166                         if (svp != NULL) {
1167                                 sock->port = ntohs(svp->s_port);
1168                         } else {
1169                                 sock->port = PW_ACCT_UDP_PORT;
1170                         }
1171                         break;
1172 #endif
1173
1174 #ifdef WITH_PROXY
1175                 case RAD_LISTEN_PROXY:
1176                         sock->port = 0;
1177                         break;
1178 #endif
1179
1180 #ifdef WITH_VMPS
1181                 case RAD_LISTEN_VQP:
1182                         sock->port = 1589;
1183                         break;
1184 #endif
1185
1186                 default:
1187                         radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");
1188                         return -1;
1189                 }
1190         }
1191
1192         /*
1193          *      Copy fr_socket() here, as we may need to bind to a device.
1194          */
1195         this->fd = socket(sock->ipaddr.af, SOCK_DGRAM, 0);
1196         if (this->fd < 0) {
1197                 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1198                 return -1;
1199         }
1200                 
1201 #ifdef SO_BINDTODEVICE
1202         /*
1203          *      Bind to a device BEFORE touching IP addresses.
1204          */
1205         if (sock->interface) {
1206                 struct ifreq ifreq;
1207                 strcpy(ifreq.ifr_name, sock->interface);
1208
1209                 fr_suid_up();
1210                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1211                                    (char *)&ifreq, sizeof(ifreq));
1212                 fr_suid_down();
1213                 if (rcode < 0) {
1214                         close(this->fd);
1215                         radlog(L_ERR, "Failed binding to interface %s: %s",
1216                                sock->interface, strerror(errno));
1217                         return -1;
1218                 } /* else it worked. */
1219         }
1220 #endif
1221
1222 #ifdef WITH_UDPFROMTO
1223         /*
1224          *      Initialize udpfromto for all sockets.
1225          */
1226         if (udpfromto_init(this->fd) != 0) {
1227                 close(this->fd);
1228                 return -1;
1229         }
1230 #endif
1231         
1232         /*
1233          *      Set up sockaddr stuff.
1234          */
1235         if (!fr_ipaddr2sockaddr(&sock->ipaddr, sock->port, &salocal, &salen)) {
1236                 close(this->fd);
1237                 return -1;
1238         }
1239                 
1240 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1241         if (sock->ipaddr.af == AF_INET6) {
1242                 /*
1243                  *      Listening on '::' does NOT get you IPv4 to
1244                  *      IPv6 mapping.  You've got to listen on an IPv4
1245                  *      address, too.  This makes the rest of the server
1246                  *      design a little simpler.
1247                  */
1248 #ifdef IPV6_V6ONLY
1249                 
1250                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr)) {
1251                         int on = 1;
1252                         
1253                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
1254                                    (char *)&on, sizeof(on));
1255                 }
1256 #endif /* IPV6_V6ONLY */
1257         }
1258 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
1259
1260         /*
1261          *      May be binding to priviledged ports.
1262          */
1263         fr_suid_up();
1264         rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
1265         fr_suid_down();
1266         if (rcode < 0) {
1267                 close(this->fd);
1268                 radlog(L_ERR, "Failed binding to socket: %s\n",
1269                        strerror(errno));
1270                 return -1;
1271         }
1272         
1273         /*
1274          *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
1275          *      kernel instead binds us to a 1.2.3.4.  If this
1276          *      happens, notice, and remember our real IP.
1277          */
1278         {
1279                 struct sockaddr_storage src;
1280                 socklen_t               sizeof_src = sizeof(src);
1281
1282                 memset(&src, 0, sizeof_src);
1283                 if (getsockname(this->fd, (struct sockaddr *) &src,
1284                                 &sizeof_src) < 0) {
1285                         radlog(L_ERR, "Failed getting socket name: %s",
1286                                strerror(errno));
1287                         return -1;
1288                 }
1289
1290                 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
1291                                         &sock->ipaddr, &sock->port)) {
1292                         radlog(L_ERR, "Socket has unsupported address family");
1293                         return -1;
1294                 }
1295         }
1296
1297 #ifdef O_NONBLOCK
1298         {
1299                 int flags;
1300                 
1301                 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0)  {
1302                         radlog(L_ERR, "Failure getting socket flags: %s)\n",
1303                                strerror(errno));
1304                         return -1;
1305                 }
1306                 
1307                 flags |= O_NONBLOCK;
1308                 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1309                         radlog(L_ERR, "Failure setting socket flags: %s)\n",
1310                                strerror(errno));
1311                         return -1;
1312                 }
1313         }
1314 #endif
1315
1316         return 0;
1317 }
1318
1319
1320 /*
1321  *      Allocate & initialize a new listener.
1322  */
1323 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1324 {
1325         rad_listen_t *this;
1326
1327         this = rad_malloc(sizeof(*this));
1328         memset(this, 0, sizeof(*this));
1329
1330         this->type = type;
1331         this->recv = master_listen[this->type].recv;
1332         this->send = master_listen[this->type].send;
1333         this->print = master_listen[this->type].print;
1334         this->encode = master_listen[this->type].encode;
1335         this->decode = master_listen[this->type].decode;
1336
1337         switch (type) {
1338 #ifdef WITH_STATS
1339         case RAD_LISTEN_NONE:
1340 #endif
1341         case RAD_LISTEN_AUTH:
1342 #ifdef WITH_ACCOUNTING
1343         case RAD_LISTEN_ACCT:
1344 #endif
1345 #ifdef WITH_PROXY
1346         case RAD_LISTEN_PROXY:
1347 #endif
1348 #ifdef WITH_VMPS
1349         case RAD_LISTEN_VQP:
1350 #endif
1351 #ifdef WITH_DHCP
1352         case RAD_LISTEN_DHCP:
1353 #endif
1354                 this->data = rad_malloc(sizeof(listen_socket_t));
1355                 memset(this->data, 0, sizeof(listen_socket_t));
1356                 break;
1357
1358 #ifdef WITH_DETAIL
1359         case RAD_LISTEN_DETAIL:
1360                 this->data = NULL;
1361                 break;
1362 #endif
1363
1364 #ifdef WITH_COMMAND_SOCKET
1365         case RAD_LISTEN_COMMAND:
1366                 this->data = rad_malloc(sizeof(fr_command_socket_t));
1367                 memset(this->data, 0, sizeof(fr_command_socket_t));
1368                 break;
1369 #endif
1370
1371         default:
1372                 rad_assert("Unsupported option!" == NULL);
1373                 break;
1374         }
1375
1376         return this;
1377 }
1378
1379
1380 #ifdef WITH_PROXY
1381 /*
1382  *      Externally visible function for creating a new proxy LISTENER.
1383  *
1384  *      For now, don't take ipaddr or port.
1385  *
1386  *      Not thread-safe, but all calls to it are protected by the
1387  *      proxy mutex in request_list.c
1388  */
1389 rad_listen_t *proxy_new_listener()
1390 {
1391         int last_proxy_port, port;
1392         rad_listen_t *this, *tmp, **last;
1393         listen_socket_t *sock, *old;
1394
1395         this = listen_alloc(RAD_LISTEN_PROXY);
1396
1397         /*
1398          *      Find an existing proxy socket to copy.
1399          *
1400          *      FIXME: Make it per-realm, or per-home server!
1401          */
1402         last_proxy_port = 0;
1403         old = NULL;
1404         last = &mainconfig.listen;
1405         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1406                 if (tmp->type == RAD_LISTEN_PROXY) {
1407                         sock = tmp->data;
1408                         if (sock->port > last_proxy_port) {
1409                                 last_proxy_port = sock->port + 1;
1410                         }
1411                         if (!old) old = sock;
1412                 }
1413
1414                 last = &(tmp->next);
1415         }
1416
1417         if (!old) {
1418                 listen_free(&this);
1419                 return NULL;    /* This is a serious error. */
1420         }
1421
1422         /*
1423          *      FIXME: find a new IP address to listen on?
1424          *
1425          *      This could likely be done in the "home server"
1426          *      configuration, to have per-home-server source IP's.
1427          */
1428         sock = this->data;
1429         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1430
1431         /*
1432          *      Keep going until we find an unused port.
1433          */
1434         for (port = last_proxy_port; port < 64000; port++) {
1435                 sock->port = port;
1436                 if (listen_bind(this) == 0) {
1437                         /*
1438                          *      Add the new listener to the list of
1439                          *      listeners.
1440                          */
1441                         *last = this;
1442                         return this;
1443                 }
1444         }
1445
1446         listen_free(&this);
1447         return NULL;
1448 }
1449 #endif
1450
1451 static const FR_NAME_NUMBER listen_compare[] = {
1452 #ifdef WITH_STATS
1453         { "status",     RAD_LISTEN_NONE },
1454 #endif
1455         { "auth",       RAD_LISTEN_AUTH },
1456 #ifdef WITH_ACCOUNTING
1457         { "acct",       RAD_LISTEN_ACCT },
1458 #endif
1459 #ifdef WITH_DETAIL
1460         { "detail",     RAD_LISTEN_DETAIL },
1461 #endif
1462 #ifdef WITH_PROXY
1463         { "proxy",      RAD_LISTEN_PROXY },
1464 #endif
1465 #ifdef WITH_VMPS
1466         { "vmps",       RAD_LISTEN_VQP },
1467 #endif
1468 #ifdef WITH_DHCP
1469         { "dhcp",       RAD_LISTEN_DHCP },
1470 #endif
1471 #ifdef WITH_COMMAND_SOCKET
1472         { "control",    RAD_LISTEN_COMMAND },
1473 #endif
1474         { NULL, 0 },
1475 };
1476
1477
1478 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1479 {
1480         int             type, rcode;
1481         char            *listen_type;
1482         rad_listen_t    *this;
1483
1484         listen_type = NULL;
1485         
1486         cf_log_info(cs, "listen {");
1487
1488         rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1489                               &listen_type, "");
1490         if (rcode < 0) return NULL;
1491         if (rcode == 1) {
1492                 free(listen_type);
1493                 cf_log_err(cf_sectiontoitem(cs),
1494                            "No type specified in listen section");
1495                 return NULL;
1496         }
1497
1498         type = fr_str2int(listen_compare, listen_type, -1);
1499         if (type < 0) {
1500                 cf_log_err(cf_sectiontoitem(cs),
1501                            "Invalid type \"%s\" in listen section.",
1502                            listen_type);
1503                 free(listen_type);
1504                 return NULL;
1505         }
1506         free(listen_type);
1507         
1508         /*
1509          *      Allow listen sections in the default config to
1510          *      refer to a server.
1511          */
1512         if (!server) {
1513                 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
1514                                       &server, NULL);
1515                 if (rcode == 1) { /* compatiblity with 2.0-pre */
1516                         rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1517                                               &server, NULL);
1518                 }
1519                 if (rcode < 0) return NULL;
1520         }
1521
1522         /*
1523          *      Set up cross-type data.
1524          */
1525         this = listen_alloc(type);
1526         this->server = server;
1527         this->fd = -1;
1528
1529         /*
1530          *      Call per-type parser.
1531          */
1532         if (master_listen[type].parse(cs, this) < 0) {
1533                 listen_free(&this);
1534                 return NULL;
1535         }
1536
1537         cf_log_info(cs, "}");
1538
1539         return this;
1540 }
1541
1542 /*
1543  *      Generate a list of listeners.  Takes an input list of
1544  *      listeners, too, so we don't close sockets with waiting packets.
1545  */
1546 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1547 {
1548         int             override = FALSE;
1549         int             rcode;
1550         CONF_SECTION    *cs = NULL;
1551         rad_listen_t    **last;
1552         rad_listen_t    *this;
1553         fr_ipaddr_t     server_ipaddr;
1554         int             auth_port = 0;
1555 #ifdef WITH_PROXY
1556         int             defined_proxy = 0;
1557 #endif
1558
1559         /*
1560          *      We shouldn't be called with a pre-existing list.
1561          */
1562         rad_assert(head && (*head == NULL));
1563
1564         last = head;
1565         server_ipaddr.af = AF_UNSPEC;
1566
1567         /*
1568          *      If the port is specified on the command-line,
1569          *      it over-rides the configuration file.
1570          *
1571          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1572          */
1573         if (mainconfig.port >= 0) auth_port = mainconfig.port;
1574
1575         /*
1576          *      If the IP address was configured on the command-line,
1577          *      use that as the "bind_address"
1578          */
1579         if (mainconfig.myip.af != AF_UNSPEC) {
1580                 memcpy(&server_ipaddr, &mainconfig.myip,
1581                        sizeof(server_ipaddr));
1582                 override = TRUE;
1583                 goto bind_it;
1584         }
1585
1586         /*
1587          *      Else look for bind_address and/or listen sections.
1588          */
1589         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1590         rcode = cf_item_parse(config, "bind_address",
1591                               PW_TYPE_IPADDR,
1592                               &server_ipaddr.ipaddr.ip4addr, NULL);
1593         if (rcode < 0) return -1; /* error parsing it */
1594
1595         if (rcode == 0) { /* successfully parsed IPv4 */
1596                 listen_socket_t *sock;
1597                 server_ipaddr.af = AF_INET;
1598
1599                 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'.");
1600
1601         bind_it:
1602 #ifdef WITH_VMPS
1603                 if (strcmp(progname, "vmpsd") == 0) {
1604                         this = listen_alloc(RAD_LISTEN_VQP);
1605                         if (!auth_port) auth_port = 1589;
1606                 } else
1607 #endif
1608                         this = listen_alloc(RAD_LISTEN_AUTH);
1609
1610                 sock = this->data;
1611
1612                 sock->ipaddr = server_ipaddr;
1613                 sock->port = auth_port;
1614
1615                 sock->clients = clients_parse_section(config);
1616                 if (!sock->clients) {
1617                         cf_log_err(cf_sectiontoitem(config),
1618                                    "Failed to find any clients for this listen section");
1619                         listen_free(&this);
1620                         return -1;
1621                 }
1622
1623                 if (listen_bind(this) < 0) {
1624                         listen_free(head);
1625                         radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1626                         listen_free(&this);
1627                         return -1;
1628                 }
1629                 auth_port = sock->port; /* may have been updated in listen_bind */
1630                 if (override) {
1631                         cs = cf_section_sub_find_name2(config, "server",
1632                                                        mainconfig.name);
1633                         if (cs) this->server = mainconfig.name;
1634                 }
1635
1636                 *last = this;
1637                 last = &(this->next);
1638
1639 #ifdef WITH_VMPS
1640                 /*
1641                  *      No acct for vmpsd
1642                  */
1643                 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1644 #endif
1645
1646 #ifdef WITH_ACCOUNTING
1647                 /*
1648                  *      Open Accounting Socket.
1649                  *
1650                  *      If we haven't already gotten acct_port from
1651                  *      /etc/services, then make it auth_port + 1.
1652                  */
1653                 this = listen_alloc(RAD_LISTEN_ACCT);
1654                 sock = this->data;
1655
1656                 /*
1657                  *      Create the accounting socket.
1658                  *
1659                  *      The accounting port is always the
1660                  *      authentication port + 1
1661                  */
1662                 sock->ipaddr = server_ipaddr;
1663                 sock->port = auth_port + 1;
1664
1665                 sock->clients = clients_parse_section(config);
1666                 if (!sock->clients) {
1667                         cf_log_err(cf_sectiontoitem(config),
1668                                    "Failed to find any clients for this listen section");
1669                         return -1;
1670                 }
1671
1672                 if (listen_bind(this) < 0) {
1673                         listen_free(&this);
1674                         listen_free(head);
1675                         radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1676                         return -1;
1677                 }
1678
1679                 if (override) {
1680                         cs = cf_section_sub_find_name2(config, "server",
1681                                                        mainconfig.name);
1682                         if (cs) this->server = mainconfig.name;
1683                 }
1684
1685                 *last = this;
1686                 last = &(this->next);
1687 #endif
1688         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1689                 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1690                        mainconfig.port);
1691                 return -1;
1692         }
1693
1694         /*
1695          *      They specified an IP on the command-line, ignore
1696          *      all listen sections except the one in '-n'.
1697          */
1698         if (mainconfig.myip.af != AF_UNSPEC) {
1699                 CONF_SECTION *subcs;
1700                 const char *name2 = cf_section_name2(cs);
1701
1702                 cs = cf_section_sub_find_name2(config, "server",
1703                                                mainconfig.name);
1704                 if (!cs) goto do_proxy;
1705
1706                 /*
1707                  *      Should really abstract this code...
1708                  */
1709                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
1710                      subcs != NULL;
1711                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
1712                         this = listen_parse(subcs, name2);
1713                         if (!this) {
1714                                 listen_free(head);
1715                                 return -1;
1716                         }
1717
1718 #ifdef WITH_PROXY
1719                         if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
1720 #endif
1721                         
1722                         *last = this;
1723                         last = &(this->next);
1724                 } /* loop over "listen" directives in server <foo> */
1725
1726                 goto do_proxy;
1727         }
1728
1729         /*
1730          *      Walk through the "listen" sections, if they exist.
1731          */
1732         for (cs = cf_subsection_find_next(config, NULL, "listen");
1733              cs != NULL;
1734              cs = cf_subsection_find_next(config, cs, "listen")) {
1735                 this = listen_parse(cs, NULL);
1736                 if (!this) {
1737                         listen_free(head);
1738                         return -1;
1739                 }
1740
1741 #ifdef WITH_PROXY
1742                 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
1743 #endif
1744
1745                 *last = this;
1746                 last = &(this->next);
1747         }
1748
1749         /*
1750          *      Check virtual servers for "listen" sections, too.
1751          *
1752          *      FIXME: Move to virtual server init?
1753          */
1754         for (cs = cf_subsection_find_next(config, NULL, "server");
1755              cs != NULL;
1756              cs = cf_subsection_find_next(config, cs, "server")) {
1757                 CONF_SECTION *subcs;
1758                 const char *name2 = cf_section_name2(cs);
1759                 
1760                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
1761                      subcs != NULL;
1762                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
1763                         this = listen_parse(subcs, name2);
1764                         if (!this) {
1765                                 listen_free(head);
1766                                 return -1;
1767                         }
1768                         
1769 #ifdef WITH_PROXY
1770                         if (this->type == RAD_LISTEN_PROXY) {
1771                                 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
1772                                 listen_free(head);
1773                                 return -1;
1774                         }
1775 #endif
1776
1777                         *last = this;
1778                         last = &(this->next);
1779                 } /* loop over "listen" directives in virtual servers */
1780         } /* loop over virtual servers */
1781
1782         /*
1783          *      If we're proxying requests, open the proxy FD.
1784          *      Otherwise, don't do anything.
1785          */
1786  do_proxy:
1787 #ifdef WITH_PROXY
1788         if (mainconfig.proxy_requests == TRUE) {
1789                 int             port = -1;
1790                 listen_socket_t *sock = NULL;
1791
1792                 /*
1793                  *      No sockets to receive packets, therefore
1794                  *      proxying is pointless.
1795                  */
1796                 if (!*head) return -1;
1797
1798                 if (defined_proxy) goto done;
1799
1800                 /*
1801                  *      Find the first authentication port,
1802                  *      and use it
1803                  */
1804                 for (this = *head; this != NULL; this = this->next) {
1805                         if (this->type == RAD_LISTEN_AUTH) {
1806                                 sock = this->data;
1807                                 if (server_ipaddr.af == AF_UNSPEC) {
1808                                         server_ipaddr = sock->ipaddr;
1809                                 }
1810                                 port = sock->port + 2; /* skip acct port */
1811                                 break;
1812                         }
1813                         if (this->type == RAD_LISTEN_VQP) {
1814                                 sock = this->data;
1815                                 if (server_ipaddr.af == AF_UNSPEC) {
1816                                         server_ipaddr = sock->ipaddr;
1817                                 }
1818                                 port = sock->port + 1;
1819                                 break;
1820                         }
1821                 }
1822
1823                 if (port < 0) port = 1024 + (fr_rand() & 0x1ff);
1824
1825                 /*
1826                  *      Address is still unspecified, use IPv4.
1827                  */
1828                 if (server_ipaddr.af == AF_UNSPEC) {
1829                         server_ipaddr.af = AF_INET;
1830                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1831                 }
1832
1833                 this = listen_alloc(RAD_LISTEN_PROXY);
1834                 sock = this->data;
1835
1836                 /*
1837                  *      Create the first proxy socket.
1838                  */
1839                 sock->ipaddr = server_ipaddr;
1840
1841                 /*
1842                  *      Try to find a proxy port (value doesn't matter)
1843                  */
1844                 for (sock->port = port;
1845                      sock->port < 64000;
1846                      sock->port++) {
1847                         if (listen_bind(this) == 0) {
1848                                 *last = this;
1849                                 last = &(this->next); /* just in case */
1850                                 break;
1851                         }
1852                 }
1853
1854                 if (sock->port >= 64000) {
1855                         listen_free(head);
1856                         listen_free(&this);
1857                         radlog(L_ERR, "Failed to open socket for proxying");
1858                         return -1;
1859                 }
1860         }
1861
1862  done:                  /* used only in proxy code. */
1863 #endif
1864
1865         return 0;
1866 }
1867
1868 /*
1869  *      Free a linked list of listeners;
1870  */
1871 void listen_free(rad_listen_t **head)
1872 {
1873         rad_listen_t *this;
1874
1875         if (!head || !*head) return;
1876
1877         this = *head;
1878         while (this) {
1879                 rad_listen_t *next = this->next;
1880
1881                 /*
1882                  *      Other code may have eaten the FD.
1883                  */
1884                 if (this->fd >= 0) close(this->fd);
1885
1886                 if (master_listen[this->type].free) {
1887                         master_listen[this->type].free(this);
1888                 }
1889                 free(this->data);
1890                 free(this);
1891
1892                 this = next;
1893         }
1894
1895         *head = NULL;
1896 }
1897
1898 #ifdef WITH_STATS
1899 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
1900                                           int port)
1901 {
1902         rad_listen_t *this;
1903
1904         for (this = mainconfig.listen; this != NULL; this = this->next) {
1905                 listen_socket_t *sock;
1906
1907                 if ((this->type != RAD_LISTEN_AUTH) &&
1908                     (this->type != RAD_LISTEN_ACCT)) continue;
1909                 
1910                 sock = this->data;
1911
1912                 if ((sock->port == port) &&
1913                     (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
1914                         return sock->clients;
1915                 }
1916         }
1917
1918         return NULL;
1919 }
1920
1921 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
1922 {
1923         rad_listen_t *this;
1924
1925         for (this = mainconfig.listen; this != NULL; this = this->next) {
1926                 listen_socket_t *sock;
1927
1928                 if ((this->type != RAD_LISTEN_AUTH) &&
1929                     (this->type != RAD_LISTEN_ACCT)) continue;
1930                 
1931                 sock = this->data;
1932
1933                 if ((sock->port == port) &&
1934                     (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
1935                         return this;
1936                 }
1937         }
1938
1939         return NULL;
1940 }
1941 #endif