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