Clean up loopback / inaddr_any checks
[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 void print_packet(RADIUS_PACKET *packet)
54 {
55         char src[256], dst[256];
56
57         ip_ntoh(&packet->src_ipaddr, src, sizeof(src));
58         ip_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
59
60         fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
61                 src, packet->src_port, dst, packet->dst_port);
62
63 }
64
65
66 /*
67  *      We'll use this below.
68  */
69 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
70 typedef void (*rad_listen_free_t)(rad_listen_t *);
71
72 typedef struct rad_listen_master_t {
73         rad_listen_parse_t      parse;
74         rad_listen_free_t       free;
75         rad_listen_recv_t       recv;
76         rad_listen_send_t       send;
77         rad_listen_print_t      print;
78         rad_listen_encode_t     encode;
79         rad_listen_decode_t     decode;
80 } rad_listen_master_t;
81
82 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
83
84 /*
85  *      Find a per-socket client.
86  */
87 RADCLIENT *client_listener_find(const rad_listen_t *listener,
88                                 const fr_ipaddr_t *ipaddr, int src_port)
89 {
90 #ifdef WITH_DYNAMIC_CLIENTS
91         int rcode;
92         REQUEST *request;
93         RADCLIENT *created;
94 #endif
95         time_t now;
96         RADCLIENT *client;
97         RADCLIENT_LIST *clients;
98         listen_socket_t *sock;
99
100         rad_assert(listener != NULL);
101         rad_assert(ipaddr != NULL);
102
103         sock = listener->data;
104         clients = sock->clients;
105
106         /*
107          *      This HAS to have been initialized previously.
108          */
109         rad_assert(clients != NULL);
110
111         client = client_find(clients, ipaddr,sock->proto);
112         if (!client) {
113                 char name[256], buffer[128];
114                                         
115 #ifdef WITH_DYNAMIC_CLIENTS
116         unknown:                /* used only for dynamic clients */
117 #endif
118
119                 /*
120                  *      DoS attack quenching, but only in daemon mode.
121                  *      If they're running in debug mode, show them
122                  *      every packet.
123                  */
124                 if (debug_flag == 0) {
125                         static time_t last_printed = 0;
126
127                         now = time(NULL);
128                         if (last_printed == now) return NULL;
129                         
130                         last_printed = now;
131                 }
132
133                 listener->print(listener, name, sizeof(name));
134
135                 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
136 #ifdef WITH_TCP
137                        " proto %s"
138 #endif
139                        , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
140                                          buffer, sizeof(buffer)), src_port
141 #ifdef WITH_TCP
142                        , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
143 #endif
144                        );
145                 return NULL;
146         }
147
148 #ifndef WITH_DYNAMIC_CLIENTS
149         return client;          /* return the found client. */
150 #else
151
152         /*
153          *      No server defined, and it's not dynamic.  Return it.
154          */
155         if (!client->client_server && !client->dynamic) return client;
156
157         now = time(NULL);
158         
159         /*
160          *      It's a dynamically generated client, check it.
161          */
162         if (client->dynamic && (src_port != 0)) {
163                 /*
164                  *      Lives forever.  Return it.
165                  */
166                 if (client->lifetime == 0) return client;
167                 
168                 /*
169                  *      Rate-limit the deletion of known clients.
170                  *      This makes them last a little longer, but
171                  *      prevents the server from melting down if (say)
172                  *      10k clients all expire at once.
173                  */
174                 if (now == client->last_new_client) return client;
175
176                 /*
177                  *      It's not dead yet.  Return it.
178                  */
179                 if ((client->created + client->lifetime) > now) return client;
180                 
181                 /*
182                  *      This really puts them onto a queue for later
183                  *      deletion.
184                  */
185                 client_delete(clients, client);
186
187                 /*
188                  *      Go find the enclosing network again.
189                  */
190                 client = client_find(clients, ipaddr, sock->proto);
191
192                 /*
193                  *      WTF?
194                  */
195                 if (!client) goto unknown;
196                 if (!client->client_server) goto unknown;
197
198                 /*
199                  *      At this point, 'client' is the enclosing
200                  *      network that configures where dynamic clients
201                  *      can be defined.
202                  */
203                 rad_assert(client->dynamic == 0);
204
205         } else if (!client->dynamic && client->rate_limit) {
206                 /*
207                  *      The IP is unknown, so we've found an enclosing
208                  *      network.  Enable DoS protection.  We only
209                  *      allow one new client per second.  Known
210                  *      clients aren't subject to this restriction.
211                  */
212                 if (now == client->last_new_client) goto unknown;
213         }
214
215         client->last_new_client = now;
216
217         request = request_alloc();
218         if (!request) goto unknown;
219
220         request->listener = listener;
221         request->client = client;
222         request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
223         if (!request->packet) {                         /* badly formed, etc */
224                 request_free(&request);
225                 goto unknown;
226         }
227         request->reply = rad_alloc_reply(request->packet);
228         if (!request->reply) {
229                 request_free(&request);
230                 goto unknown;
231         }
232         request->packet->timestamp = request->timestamp;
233         request->number = 0;
234         request->priority = listener->type;
235         request->server = client->client_server;
236         request->root = &mainconfig;
237
238         /*
239          *      Run a fake request through the given virtual server.
240          *      Look for FreeRADIUS-Client-IP-Address
241          *               FreeRADIUS-Client-Secret
242          *              ...
243          *
244          *      and create the RADCLIENT structure from that.
245          */
246         DEBUG("server %s {", request->server);
247
248         rcode = module_authorize(0, request);
249
250         DEBUG("} # server %s", request->server);
251
252         if (rcode != RLM_MODULE_OK) {
253                 request_free(&request);
254                 goto unknown;
255         }
256
257         /*
258          *      If the client was updated by rlm_dynamic_clients,
259          *      don't create the client from attribute-value pairs.
260          */
261         if (request->client == client) {
262                 created = client_create(clients, request);
263         } else {
264                 created = request->client;
265
266                 /*
267                  *      This frees the client if it isn't valid.
268                  */
269                 if (!client_validate(clients, client, created)) goto unknown;
270         }
271         request_free(&request);
272
273         if (!created) goto unknown;
274
275         return created;
276 #endif
277 }
278
279 static int listen_bind(rad_listen_t *this);
280
281
282 /*
283  *      Process and reply to a server-status request.
284  *      Like rad_authenticate and rad_accounting this should
285  *      live in it's own file but it's so small we don't bother.
286  */
287 static int rad_status_server(REQUEST *request)
288 {
289         int rcode = RLM_MODULE_OK;
290         DICT_VALUE *dval;
291
292         switch (request->listener->type) {
293 #ifdef WITH_STATS
294         case RAD_LISTEN_NONE:
295 #endif
296         case RAD_LISTEN_AUTH:
297                 dval = dict_valbyname(PW_AUTZ_TYPE, 0, "Status-Server");
298                 if (dval) {
299                         rcode = module_authorize(dval->value, request);
300                 } else {
301                         rcode = RLM_MODULE_OK;
302                 }
303
304                 switch (rcode) {
305                 case RLM_MODULE_OK:
306                 case RLM_MODULE_UPDATED:
307                         request->reply->code = PW_AUTHENTICATION_ACK;
308                         break;
309
310                 case RLM_MODULE_FAIL:
311                 case RLM_MODULE_HANDLED:
312                         request->reply->code = 0; /* don't reply */
313                         break;
314
315                 default:
316                 case RLM_MODULE_REJECT:
317                         request->reply->code = PW_AUTHENTICATION_REJECT;
318                         break;
319                 }
320                 break;
321
322 #ifdef WITH_ACCOUNTING
323         case RAD_LISTEN_ACCT:
324                 dval = dict_valbyname(PW_ACCT_TYPE, 0, "Status-Server");
325                 if (dval) {
326                         rcode = module_accounting(dval->value, request);
327                 } else {
328                         rcode = RLM_MODULE_OK;
329                 }
330
331                 switch (rcode) {
332                 case RLM_MODULE_OK:
333                 case RLM_MODULE_UPDATED:
334                         request->reply->code = PW_ACCOUNTING_RESPONSE;
335                         break;
336
337                 default:
338                         request->reply->code = 0; /* don't reply */
339                         break;
340                 }
341                 break;
342 #endif
343
344 #ifdef WITH_COA
345                 /*
346                  *      This is a vendor extension.  Suggested by Glen
347                  *      Zorn in IETF 72, and rejected by the rest of
348                  *      the WG.  We like it, so it goes in here.
349                  */
350         case RAD_LISTEN_COA:
351                 dval = dict_valbyname(PW_RECV_COA_TYPE, 0, "Status-Server");
352                 if (dval) {
353                         rcode = module_recv_coa(dval->value, request);
354                 } else {
355                         rcode = RLM_MODULE_OK;
356                 }
357
358                 switch (rcode) {
359                 case RLM_MODULE_OK:
360                 case RLM_MODULE_UPDATED:
361                         request->reply->code = PW_COA_ACK;
362                         break;
363
364                 default:
365                         request->reply->code = 0; /* don't reply */
366                         break;
367                 }
368                 break;
369 #endif
370
371         default:
372                 return 0;
373         }
374
375 #ifdef WITH_STATS
376         /*
377          *      Full statistics are available only on a statistics
378          *      socket.
379          */
380         if (request->listener->type == RAD_LISTEN_NONE) {
381                 request_stats_reply(request);
382         }
383 #endif
384
385         return 0;
386 }
387
388 #ifdef WITH_TCP
389 static int auth_tcp_recv(rad_listen_t *listener,
390                          RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
391 {
392         int rcode;
393         RADIUS_PACKET   *packet;
394         RAD_REQUEST_FUNP fun = NULL;
395         listen_socket_t *sock = listener->data;
396         RADCLIENT       *client = sock->client;
397
398         /*
399          *      Allocate a packet for partial reads.
400          */
401         if (!sock->packet) {
402                 sock->packet = rad_alloc(0);
403                 if (!sock->packet) return 0;
404
405                 sock->packet->sockfd = listener->fd;
406                 sock->packet->src_ipaddr = sock->other_ipaddr;
407                 sock->packet->src_port = sock->other_port;
408                 sock->packet->dst_ipaddr = sock->my_ipaddr;
409                 sock->packet->dst_port = sock->my_port;
410         }
411         
412         /*
413          *      Grab the packet currently being processed.
414          */
415         packet = sock->packet;
416
417         rcode = fr_tcp_read_packet(packet, 0);
418
419         /*
420          *      Still only a partial packet.  Put it back, and return,
421          *      so that we'll read more data when it's ready.
422          */
423         if (rcode == 0) {
424                 return 0;
425         }
426
427         if (rcode == -1) {      /* error reading packet */
428                 char buffer[256];
429
430                 radlog(L_ERR, "Invalid packet from %s port %d: closing socket",
431                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
432                        packet->src_port);
433         }
434
435         if (rcode < 0) {        /* error or connection reset */
436                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
437
438                 /*
439                  *      Decrement the number of connections.
440                  */
441                 if (sock->parent->num_connections > 0) {
442                         sock->parent->num_connections--;
443                 }
444                 if (sock->client->num_connections > 0) {
445                         sock->client->num_connections--;
446                 }
447
448                 /*
449                  *      Tell the event handler that an FD has disappeared.
450                  */
451                 DEBUG("Client has closed connection");
452                 event_new_fd(listener);
453
454                 /*
455                  *      Do NOT free the listener here.  It's in use by
456                  *      a request, and will need to hang around until
457                  *      all of the requests are done.
458                  *
459                  *      It is instead free'd in remove_from_request_hash()
460                  */
461                 return 0;
462         }
463
464         RAD_STATS_TYPE_INC(listener, total_requests);
465
466         /*
467          *      Some sanity checks, based on the packet code.
468          */
469         switch(packet->code) {
470         case PW_AUTHENTICATION_REQUEST:
471                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
472                 fun = rad_authenticate;
473                 break;
474
475         case PW_STATUS_SERVER:
476                 if (!mainconfig.status_server) {
477                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
478                         RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
479                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
480                         rad_free(&sock->packet);
481                         return 0;
482                 }
483                 fun = rad_status_server;
484                 break;
485
486         default:
487                 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
488                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
489
490                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
491                       packet->code, client->shortname, packet->src_port);
492                 rad_free(&sock->packet);
493                 return 0;
494         } /* switch over packet types */
495
496         if (!received_request(listener, packet, prequest, sock->client)) {
497                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
498                 RAD_STATS_CLIENT_INC(listener, sock->client, total_packets_dropped);
499                 rad_free(&sock->packet);
500                 return 0;
501         }
502
503         *pfun = fun;
504         sock->packet = NULL;    /* we have no need for more partial reads */
505         return 1;
506 }
507
508 static int auth_tcp_accept(rad_listen_t *listener,
509                            UNUSED RAD_REQUEST_FUNP *pfun,
510                            UNUSED REQUEST **prequest)
511 {
512         int newfd, src_port;
513         rad_listen_t *this;
514         socklen_t salen;
515         struct sockaddr_storage src;
516         listen_socket_t *sock;
517         fr_ipaddr_t src_ipaddr;
518         RADCLIENT *client;
519         
520         salen = sizeof(src);
521
522         DEBUG2(" ... new connection request on TCP socket.");
523         
524         newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
525         if (newfd < 0) {
526                 /*
527                  *      Non-blocking sockets must handle this.
528                  */
529                 if (errno == EWOULDBLOCK) {
530                         return 0;
531                 }
532
533                 DEBUG2(" ... failed to accept connection.");
534                 return -1;
535         }
536
537         if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
538                 DEBUG2(" ... unknown address family.");
539                 return 0;
540         }
541
542         /*
543          *      Enforce client IP address checks on accept, not on
544          *      every packet.
545          */
546         if ((client = client_listener_find(listener,
547                                            &src_ipaddr, src_port)) == NULL) {
548                 close(newfd);
549                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
550                 return 0;
551         }
552
553         /*
554          *      Enforce max_connectionsx on client && listen section.
555          */
556         if ((client->max_connections != 0) &&
557             (client->max_connections == client->num_connections)) {
558                 /*
559                  *      FIXME: Print client IP/port, and server IP/port.
560                  */
561                 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->max_connections);
562                 close(newfd);
563                 return 0;
564         }
565
566         sock = listener->data;
567         if ((sock->max_connections != 0) &&
568             (sock->max_connections == sock->num_connections)) {
569                 /*
570                  *      FIXME: Print client IP/port, and server IP/port.
571                  */
572                 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
573                 close(newfd);
574                 return 0;
575         }
576         client->num_connections++;
577         sock->num_connections++;
578
579         /*
580          *      Add the new listener.
581          */
582         this = listen_alloc(listener->type);
583         if (!this) return -1;
584
585         /*
586          *      Copy everything, including the pointer to the socket
587          *      information.
588          */
589         sock = this->data;
590         memcpy(this->data, listener->data, sizeof(*sock));
591         memcpy(this, listener, sizeof(*this));
592         this->next = NULL;
593         this->data = sock;      /* fix it back */
594
595         sock->parent = listener->data;
596         sock->other_ipaddr = src_ipaddr;
597         sock->other_port = src_port;
598         sock->client = client;
599
600         this->fd = newfd;
601         this->status = RAD_LISTEN_STATUS_INIT;
602         this->recv = auth_tcp_recv;
603
604         /*
605          *      FIXME: set O_NONBLOCK on the accept'd fd.
606          *      See djb's portability rants for details.
607          */
608
609         /*
610          *      Tell the event loop that we have a new FD.
611          *      This can be called from a child thread...
612          */
613         event_new_fd(this);
614
615         return 0;
616 }
617 #endif
618
619
620 /*
621  *      This function is stupid and complicated.
622  */
623 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
624 {
625         size_t len;
626         listen_socket_t *sock = this->data;
627         const char *name;
628
629         switch (this->type) {
630 #ifdef WITH_STATS
631         case RAD_LISTEN_NONE:   /* what a hack... */
632                 name = "status";
633                 break;
634 #endif
635
636         case RAD_LISTEN_AUTH:
637                 name = "authentication";
638                 break;
639
640 #ifdef WITH_ACCOUNTING
641         case RAD_LISTEN_ACCT:
642                 name = "accounting";
643                 break;
644 #endif
645
646 #ifdef WITH_PROXY
647         case RAD_LISTEN_PROXY:
648                 name = "proxy";
649                 break;
650 #endif
651
652 #ifdef WITH_VMPS
653         case RAD_LISTEN_VQP:
654                 name = "vmps";
655                 break;
656 #endif
657
658 #ifdef WITH_DHCP
659         case RAD_LISTEN_DHCP:
660                 name = "dhcp";
661                 break;
662 #endif
663
664 #ifdef WITH_COA
665         case RAD_LISTEN_COA:
666                 name = "coa";
667                 break;
668 #endif
669
670         default:
671                 name = "??";
672                 break;
673         }
674
675 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
676 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
677
678         ADDSTRING(name);
679
680         if (sock->interface) {
681                 ADDSTRING(" interface ");
682                 ADDSTRING(sock->interface);
683         }
684
685 #ifdef WITH_TCP
686         if (this->recv == auth_tcp_accept) {
687                 ADDSTRING(" proto tcp");
688         }
689 #endif
690
691 #ifdef WITH_TCP
692         /*
693          *      TCP sockets get printed a little differently, to make
694          *      it clear what's going on.
695          */
696         if (sock->client) {
697                 ADDSTRING(" from client (");
698                 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
699                 FORWARD;
700
701                 ADDSTRING(", ");
702                 snprintf(buffer, bufsize, "%d", sock->other_port);
703                 FORWARD;
704                 ADDSTRING(") -> (");
705
706                 if ((sock->my_ipaddr.af == AF_INET) &&
707                     (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
708                         strlcpy(buffer, "*", bufsize);
709                 } else {
710                         ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
711                 }
712                 FORWARD;
713                 
714                 ADDSTRING(", ");
715                 snprintf(buffer, bufsize, "%d", sock->my_port);
716                 FORWARD;
717
718                 if (this->server) {
719                         ADDSTRING(", virtual-server=");
720                         ADDSTRING(this->server);
721                 }
722
723                 ADDSTRING(")");
724
725                 return 1;
726         }
727
728         /*
729          *      Maybe it's a socket that we opened to a home server.
730          */
731         if ((sock->proto == IPPROTO_TCP) &&
732             (this->type == RAD_LISTEN_PROXY)) {
733                 ADDSTRING(" (");
734                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
735                 FORWARD;
736
737                 ADDSTRING(", ");
738                 snprintf(buffer, bufsize, "%d", sock->my_port);
739                 FORWARD;
740                 ADDSTRING(") -> home_server (");
741
742                 if ((sock->other_ipaddr.af == AF_INET) &&
743                     (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
744                         strlcpy(buffer, "*", bufsize);
745                 } else {
746                         ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
747                 }
748                 FORWARD;
749                 
750                 ADDSTRING(", ");
751                 snprintf(buffer, bufsize, "%d", sock->other_port);
752                 FORWARD;
753
754                 ADDSTRING(")");
755
756                 return 1;
757         }
758 #endif
759
760         ADDSTRING(" address ");
761         
762         if ((sock->my_ipaddr.af == AF_INET) &&
763             (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
764                 strlcpy(buffer, "*", bufsize);
765         } else {
766                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
767         }
768         FORWARD;
769
770         ADDSTRING(" port ");
771         snprintf(buffer, bufsize, "%d", sock->my_port);
772         FORWARD;
773
774         if (this->server) {
775                 ADDSTRING(" as server ");
776                 ADDSTRING(this->server);
777         }
778
779 #undef ADDSTRING
780 #undef FORWARD
781
782         return 1;
783 }
784
785 extern int check_config;        /* radiusd.c */
786
787
788 /*
789  *      Parse an authentication or accounting socket.
790  */
791 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
792 {
793         int             rcode;
794         int             listen_port;
795         fr_ipaddr_t     ipaddr;
796         listen_socket_t *sock = this->data;
797         char            *section_name = NULL;
798         CONF_SECTION    *client_cs, *parentcs;
799
800         /*
801          *      Try IPv4 first
802          */
803         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
804         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
805                               &ipaddr.ipaddr.ip4addr, NULL);
806         if (rcode < 0) return -1;
807
808         if (rcode == 0) { /* successfully parsed IPv4 */
809                 ipaddr.af = AF_INET;
810
811         } else {        /* maybe IPv6? */
812                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
813                                       &ipaddr.ipaddr.ip6addr, NULL);
814                 if (rcode < 0) return -1;
815
816                 if (rcode == 1) {
817                         cf_log_err(cf_sectiontoitem(cs),
818                                    "No address specified in listen section");
819                         return -1;
820                 }
821                 ipaddr.af = AF_INET6;
822         }
823
824         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
825                               &listen_port, "0");
826         if (rcode < 0) return -1;
827
828         if ((listen_port < 0) || (listen_port > 65535)) {
829                         cf_log_err(cf_sectiontoitem(cs),
830                                    "Invalid value for \"port\"");
831                         return -1;
832         }
833
834         sock->proto = IPPROTO_UDP;
835
836         if (cf_pair_find(cs, "proto")) {
837 #ifndef WITH_TCP
838                 cf_log_err(cf_sectiontoitem(cs),
839                            "System does not support the TCP protocol.  Delete this line from the configuration file.");
840                 return -1;
841 #else
842                 char *proto = NULL;
843
844
845                 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
846                                       &proto, "udp");
847                 if (rcode < 0) return -1;
848
849                 if (strcmp(proto, "udp") == 0) {
850                         sock->proto = IPPROTO_UDP;
851
852                 } else if (strcmp(proto, "tcp") == 0) {
853                         sock->proto = IPPROTO_TCP;
854
855                         rcode = cf_item_parse(cs, "max_connections", PW_TYPE_INTEGER,
856                                               &sock->max_connections, "64");
857                         if (rcode < 0) return -1;
858
859                 } else {
860                         cf_log_err(cf_sectiontoitem(cs),
861                                    "Unknown proto name \"%s\"", proto);
862                         free(proto);
863                         return -1;
864                 }
865                 free(proto);
866
867                 /*
868                  *      TCP requires a destination IP for sockets.
869                  *      UDP doesn't, so it's allowed.
870                  */
871                 if ((this->type == RAD_LISTEN_PROXY) &&
872                     (sock->proto != IPPROTO_UDP)) {
873                         cf_log_err(cf_sectiontoitem(cs),
874                                    "Proxy listeners can only listen on proto = udp");
875                         return -1;
876                 }
877 #endif
878         }
879
880         sock->my_ipaddr = ipaddr;
881         sock->my_port = listen_port;
882
883         if (check_config) {
884                 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
885                                 char buffer[128];
886                                 
887                                 DEBUG("ERROR: We have been asked to listen on %s port %d, which is also listed as a home server.  This can create a proxy loop.",
888                                       ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
889                                       sock->my_port);
890                                 return -1;
891                 }
892
893                 return 0;       /* don't do anything */
894         }
895
896         /*
897          *      If we can bind to interfaces, do so,
898          *      else don't.
899          */
900         if (cf_pair_find(cs, "interface")) {
901                 const char *value;
902                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
903
904                 rad_assert(cp != NULL);
905                 value = cf_pair_value(cp);
906                 if (!value) {
907                         cf_log_err(cf_sectiontoitem(cs),
908                                    "No interface name given");
909                         return -1;
910                 }
911                 sock->interface = value;
912         }
913
914 #ifdef WITH_DHCP
915         /*
916          *      If we can do broadcasts..
917          */
918         if (cf_pair_find(cs, "broadcast")) {
919 #ifndef SO_BROADCAST
920                 cf_log_err(cf_sectiontoitem(cs),
921                            "System does not support broadcast sockets.  Delete this line from the configuration file.");
922                 return -1;
923 #else
924                 const char *value;
925                 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
926
927                 if (this->type != RAD_LISTEN_DHCP) {
928                         cf_log_err(cf_pairtoitem(cp),
929                                    "Broadcast can only be set for DHCP listeners.  Delete this line from the configuration file.");
930                         return -1;
931                 }
932                 
933                 rad_assert(cp != NULL);
934                 value = cf_pair_value(cp);
935                 if (!value) {
936                         cf_log_err(cf_sectiontoitem(cs),
937                                    "No broadcast value given");
938                         return -1;
939                 }
940
941                 /*
942                  *      Hack... whatever happened to cf_section_parse?
943                  */
944                 sock->broadcast = (strcmp(value, "yes") == 0);
945 #endif
946         }
947 #endif
948
949         /*
950          *      And bind it to the port.
951          */
952         if (listen_bind(this) < 0) {
953                 char buffer[128];
954                 cf_log_err(cf_sectiontoitem(cs),
955                            "Error binding to port for %s port %d",
956                            ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
957                            sock->my_port);
958                 return -1;
959         }
960
961 #ifdef WITH_PROXY
962         /*
963          *      Proxy sockets don't have clients.
964          */
965         if (this->type == RAD_LISTEN_PROXY) return 0;
966 #endif
967         
968         /*
969          *      The more specific configurations are preferred to more
970          *      generic ones.
971          */
972         client_cs = NULL;
973         parentcs = cf_top_section(cs);
974         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
975                               &section_name, NULL);
976         if (rcode < 0) return -1; /* bad string */
977         if (rcode == 0) {
978                 /*
979                  *      Explicit list given: use it.
980                  */
981                 client_cs = cf_section_sub_find_name2(parentcs,
982                                                       "clients",
983                                                       section_name);
984                 if (!client_cs) {
985                         client_cs = cf_section_find(section_name);
986                 }
987                 if (!client_cs) {
988                         cf_log_err(cf_sectiontoitem(cs),
989                                    "Failed to find clients %s {...}",
990                                    section_name);
991                         free(section_name);
992                         return -1;
993                 }
994                 free(section_name);
995         } /* else there was no "clients = " entry. */
996
997         if (!client_cs) {
998                 CONF_SECTION *server_cs;
999
1000                 server_cs = cf_section_sub_find_name2(parentcs,
1001                                                       "server",
1002                                                       this->server);
1003                 /*
1004                  *      Found a "server foo" section.  If there are clients
1005                  *      in it, use them.
1006                  */
1007                 if (server_cs &&
1008                     (cf_section_sub_find(server_cs, "client") != NULL)) {
1009                         client_cs = server_cs;
1010                 }
1011         }
1012
1013         /*
1014          *      Still nothing.  Look for global clients.
1015          */
1016         if (!client_cs) client_cs = parentcs;
1017
1018         sock->clients = clients_parse_section(client_cs);
1019         if (!sock->clients) {
1020                 cf_log_err(cf_sectiontoitem(cs),
1021                            "Failed to load clients for this listen section");
1022                 return -1;
1023         }
1024
1025 #ifdef WITH_TCP
1026         if (sock->proto == IPPROTO_TCP) {
1027                 /*
1028                  *      Re-write the listener receive function to
1029                  *      allow us to accept the socket.
1030                  */
1031                 this->recv = auth_tcp_accept;
1032         }
1033 #endif
1034
1035         return 0;
1036 }
1037
1038 /*
1039  *      Send an authentication response packet
1040  */
1041 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1042 {
1043         rad_assert(request->listener == listener);
1044         rad_assert(listener->send == auth_socket_send);
1045
1046         return rad_send(request->reply, request->packet,
1047                         request->client->secret);
1048 }
1049
1050
1051 #ifdef WITH_ACCOUNTING
1052 /*
1053  *      Send an accounting response packet (or not)
1054  */
1055 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1056 {
1057         rad_assert(request->listener == listener);
1058         rad_assert(listener->send == acct_socket_send);
1059
1060         /*
1061          *      Accounting reject's are silently dropped.
1062          *
1063          *      We do it here to avoid polluting the rest of the
1064          *      code with this knowledge
1065          */
1066         if (request->reply->code == 0) return 0;
1067
1068         return rad_send(request->reply, request->packet,
1069                         request->client->secret);
1070 }
1071 #endif
1072
1073 #ifdef WITH_PROXY
1074 /*
1075  *      Send a packet to a home server.
1076  *
1077  *      FIXME: have different code for proxy auth & acct!
1078  */
1079 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1080 {
1081         rad_assert(request->proxy_listener == listener);
1082         rad_assert(listener->send == proxy_socket_send);
1083
1084         return rad_send(request->proxy, request->packet,
1085                         request->home_server->secret);
1086 }
1087 #endif
1088
1089 #ifdef WITH_STATS
1090 /*
1091  *      Check if an incoming request is "ok"
1092  *
1093  *      It takes packets, not requests.  It sees if the packet looks
1094  *      OK.  If so, it does a number of sanity checks on it.
1095   */
1096 static int stats_socket_recv(rad_listen_t *listener,
1097                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1098 {
1099         ssize_t         rcode;
1100         int             code, src_port;
1101         RADIUS_PACKET   *packet;
1102         RADCLIENT       *client;
1103         fr_ipaddr_t     src_ipaddr;
1104
1105         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1106         if (rcode < 0) return 0;
1107
1108         RAD_STATS_TYPE_INC(listener, total_requests);
1109
1110         if (rcode < 20) {       /* AUTH_HDR_LEN */
1111                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1112                 return 0;
1113         }
1114
1115         if ((client = client_listener_find(listener,
1116                                            &src_ipaddr, src_port)) == NULL) {
1117                 rad_recv_discard(listener->fd);
1118                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1119                 return 0;
1120         }
1121
1122         /*
1123          *      We only understand Status-Server on this socket.
1124          */
1125         if (code != PW_STATUS_SERVER) {
1126                 DEBUG("Ignoring packet code %d sent to Status-Server port",
1127                       code);
1128                 rad_recv_discard(listener->fd);
1129                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
1130                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1131                 return 0;
1132         }
1133
1134         /*
1135          *      Now that we've sanity checked everything, receive the
1136          *      packet.
1137          */
1138         packet = rad_recv(listener->fd, 1); /* require message authenticator */
1139         if (!packet) {
1140                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1141                 DEBUG("%s", fr_strerror());
1142                 return 0;
1143         }
1144
1145         if (!received_request(listener, packet, prequest, client)) {
1146                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1147                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1148                 rad_free(&packet);
1149                 return 0;
1150         }
1151
1152         *pfun = rad_status_server;
1153         return 1;
1154 }
1155 #endif
1156
1157
1158 /*
1159  *      Check if an incoming request is "ok"
1160  *
1161  *      It takes packets, not requests.  It sees if the packet looks
1162  *      OK.  If so, it does a number of sanity checks on it.
1163   */
1164 static int auth_socket_recv(rad_listen_t *listener,
1165                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1166 {
1167         ssize_t         rcode;
1168         int             code, src_port;
1169         RADIUS_PACKET   *packet;
1170         RAD_REQUEST_FUNP fun = NULL;
1171         RADCLIENT       *client;
1172         fr_ipaddr_t     src_ipaddr;
1173
1174         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1175         if (rcode < 0) return 0;
1176
1177         RAD_STATS_TYPE_INC(listener, total_requests);
1178
1179         if (rcode < 20) {       /* AUTH_HDR_LEN */
1180                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1181                 return 0;
1182         }
1183
1184         if ((client = client_listener_find(listener,
1185                                            &src_ipaddr, src_port)) == NULL) {
1186                 rad_recv_discard(listener->fd);
1187                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1188                 return 0;
1189         }
1190
1191         /*
1192          *      Some sanity checks, based on the packet code.
1193          */
1194         switch(code) {
1195         case PW_AUTHENTICATION_REQUEST:
1196                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
1197                 fun = rad_authenticate;
1198                 break;
1199
1200         case PW_STATUS_SERVER:
1201                 if (!mainconfig.status_server) {
1202                         rad_recv_discard(listener->fd);
1203                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1204                         RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1205                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1206                         return 0;
1207                 }
1208                 fun = rad_status_server;
1209                 break;
1210
1211         default:
1212                 rad_recv_discard(listener->fd);
1213                 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
1214                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1215
1216                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1217                       code, client->shortname, src_port);
1218                 return 0;
1219                 break;
1220         } /* switch over packet types */
1221
1222         /*
1223          *      Now that we've sanity checked everything, receive the
1224          *      packet.
1225          */
1226         packet = rad_recv(listener->fd, client->message_authenticator);
1227         if (!packet) {
1228                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1229                 DEBUG("%s", fr_strerror());
1230                 return 0;
1231         }
1232
1233         if (!received_request(listener, packet, prequest, client)) {
1234                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1235                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1236                 rad_free(&packet);
1237                 return 0;
1238         }
1239
1240         *pfun = fun;
1241         return 1;
1242 }
1243
1244
1245 #ifdef WITH_ACCOUNTING
1246 /*
1247  *      Receive packets from an accounting socket
1248  */
1249 static int acct_socket_recv(rad_listen_t *listener,
1250                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1251 {
1252         ssize_t         rcode;
1253         int             code, src_port;
1254         RADIUS_PACKET   *packet;
1255         RAD_REQUEST_FUNP fun = NULL;
1256         RADCLIENT       *client;
1257         fr_ipaddr_t     src_ipaddr;
1258
1259         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1260         if (rcode < 0) return 0;
1261
1262         RAD_STATS_TYPE_INC(listener, total_requests);
1263
1264         if (rcode < 20) {       /* AUTH_HDR_LEN */
1265                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1266                 return 0;
1267         }
1268
1269         if ((client = client_listener_find(listener,
1270                                            &src_ipaddr, src_port)) == NULL) {
1271                 rad_recv_discard(listener->fd);
1272                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1273                 return 0;
1274         }
1275
1276         /*
1277          *      Some sanity checks, based on the packet code.
1278          */
1279         switch(code) {
1280         case PW_ACCOUNTING_REQUEST:
1281                 RAD_STATS_CLIENT_INC(listener, client, total_requests);
1282                 fun = rad_accounting;
1283                 break;
1284
1285         case PW_STATUS_SERVER:
1286                 if (!mainconfig.status_server) {
1287                         rad_recv_discard(listener->fd);
1288                         RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1289                         RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1290
1291                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1292                         return 0;
1293                 }
1294                 fun = rad_status_server;
1295                 break;
1296
1297         default:
1298                 rad_recv_discard(listener->fd);
1299                 RAD_STATS_TYPE_INC(listener, total_unknown_types);
1300                 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
1301
1302                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1303                       code, client->shortname, src_port);
1304                 return 0;
1305         } /* switch over packet types */
1306
1307         /*
1308          *      Now that we've sanity checked everything, receive the
1309          *      packet.
1310          */
1311         packet = rad_recv(listener->fd, 0);
1312         if (!packet) {
1313                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1314                 radlog(L_ERR, "%s", fr_strerror());
1315                 return 0;
1316         }
1317
1318         /*
1319          *      There can be no duplicate accounting packets.
1320          */
1321         if (!received_request(listener, packet, prequest, client)) {
1322                 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
1323                 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
1324                 rad_free(&packet);
1325                 return 0;
1326         }
1327
1328         *pfun = fun;
1329         return 1;
1330 }
1331 #endif
1332
1333
1334 #ifdef WITH_COA
1335 /*
1336  *      For now, all CoA requests are *only* originated, and not
1337  *      proxied.  So all of the necessary work is done in the
1338  *      post-proxy section, which is automatically handled by event.c.
1339  *      As a result, we don't have to do anything here.
1340  */
1341 static int rad_coa_reply(REQUEST *request)
1342 {
1343         VALUE_PAIR *s1, *s2;
1344
1345         /*
1346          *      Inform the user about RFC requirements.
1347          */
1348         s1 = pairfind(request->proxy->vps, PW_STATE, 0);
1349         if (s1) {
1350                 s2 = pairfind(request->proxy_reply->vps, PW_STATE, 0);
1351
1352                 if (!s2) {
1353                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
1354
1355                 } else if ((s1->length != s2->length) ||
1356                            (memcmp(s1->vp_octets, s2->vp_octets,
1357                                    s1->length) != 0)) {
1358                         DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
1359                 }
1360         }
1361
1362         return RLM_MODULE_OK;
1363 }
1364
1365 /*
1366  *      Receive a CoA packet.
1367  */
1368 static int rad_coa_recv(REQUEST *request)
1369 {
1370         int rcode = RLM_MODULE_OK;
1371         int ack, nak;
1372         VALUE_PAIR *vp;
1373
1374         /*
1375          *      Get the correct response
1376          */
1377         switch (request->packet->code) {
1378         case PW_COA_REQUEST:
1379                 ack = PW_COA_ACK;
1380                 nak = PW_COA_NAK;
1381                 break;
1382
1383         case PW_DISCONNECT_REQUEST:
1384                 ack = PW_DISCONNECT_ACK;
1385                 nak = PW_DISCONNECT_NAK;
1386                 break;
1387
1388         default:                /* shouldn't happen */
1389                 return RLM_MODULE_FAIL;
1390         }
1391
1392 #ifdef WITH_PROXY
1393 #define WAS_PROXIED (request->proxy)
1394 #else
1395 #define WAS_PROXIED (0)
1396 #endif
1397
1398         if (!WAS_PROXIED) {
1399                 /*
1400                  *      RFC 5176 Section 3.3.  If we have a CoA-Request
1401                  *      with Service-Type = Authorize-Only, it MUST
1402                  *      have a State attribute in it.
1403                  */
1404                 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0);
1405                 if (request->packet->code == PW_COA_REQUEST) {
1406                         if (vp && (vp->vp_integer == 17)) {
1407                                 vp = pairfind(request->packet->vps, PW_STATE, 0);
1408                                 if (!vp || (vp->length == 0)) {
1409                                         RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1410                                         request->reply->code = PW_COA_NAK;
1411                                         return RLM_MODULE_FAIL;
1412                                 }
1413                         }
1414                 } else if (vp) {
1415                         /*
1416                          *      RFC 5176, Section 3.2.
1417                          */
1418                         RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1419                         request->reply->code = PW_DISCONNECT_NAK;
1420                         return RLM_MODULE_FAIL;
1421                 }
1422
1423                 rcode = module_recv_coa(0, request);
1424                 switch (rcode) {
1425                 case RLM_MODULE_FAIL:
1426                 case RLM_MODULE_INVALID:
1427                 case RLM_MODULE_REJECT:
1428                 case RLM_MODULE_USERLOCK:
1429                 default:
1430                         request->reply->code = nak;
1431                         break;
1432                         
1433                 case RLM_MODULE_HANDLED:
1434                         return rcode;
1435                         
1436                 case RLM_MODULE_NOOP:
1437                 case RLM_MODULE_NOTFOUND:
1438                 case RLM_MODULE_OK:
1439                 case RLM_MODULE_UPDATED:
1440                         request->reply->code = ack;
1441                         break;
1442                 }
1443         } else {
1444                 /*
1445                  *      Start the reply code with the proxy reply
1446                  *      code.
1447                  */
1448                 request->reply->code = request->proxy_reply->code;
1449         }
1450
1451         /*
1452          *      Copy State from the request to the reply.
1453          *      See RFC 5176 Section 3.3.
1454          */
1455         vp = paircopy2(request->packet->vps, PW_STATE, 0);
1456         if (vp) pairadd(&request->reply->vps, vp);
1457
1458         /*
1459          *      We may want to over-ride the reply.
1460          */
1461         rcode = module_send_coa(0, request);
1462         switch (rcode) {
1463                 /*
1464                  *      We need to send CoA-NAK back if Service-Type
1465                  *      is Authorize-Only.  Rely on the user's policy
1466                  *      to do that.  We're not a real NAS, so this
1467                  *      restriction doesn't (ahem) apply to us.
1468                  */
1469                 case RLM_MODULE_FAIL:
1470                 case RLM_MODULE_INVALID:
1471                 case RLM_MODULE_REJECT:
1472                 case RLM_MODULE_USERLOCK:
1473                 default:
1474                         /*
1475                          *      Over-ride an ACK with a NAK
1476                          */
1477                         request->reply->code = nak;
1478                         break;
1479                         
1480                 case RLM_MODULE_HANDLED:
1481                         return rcode;
1482                         
1483                 case RLM_MODULE_NOOP:
1484                 case RLM_MODULE_NOTFOUND:
1485                 case RLM_MODULE_OK:
1486                 case RLM_MODULE_UPDATED:
1487                         /*
1488                          *      Do NOT over-ride a previously set value.
1489                          *      Otherwise an "ok" here will re-write a
1490                          *      NAK to an ACK.
1491                          */
1492                         if (request->reply->code == 0) {
1493                                 request->reply->code = ack;
1494                         }
1495                         break;
1496
1497         }
1498
1499         return RLM_MODULE_OK;
1500 }
1501
1502
1503 /*
1504  *      Check if an incoming request is "ok"
1505  *
1506  *      It takes packets, not requests.  It sees if the packet looks
1507  *      OK.  If so, it does a number of sanity checks on it.
1508   */
1509 static int coa_socket_recv(rad_listen_t *listener,
1510                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1511 {
1512         ssize_t         rcode;
1513         int             code, src_port;
1514         RADIUS_PACKET   *packet;
1515         RAD_REQUEST_FUNP fun = NULL;
1516         RADCLIENT       *client;
1517         fr_ipaddr_t     src_ipaddr;
1518
1519         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1520         if (rcode < 0) return 0;
1521
1522         RAD_STATS_TYPE_INC(listener, total_requests);
1523
1524         if (rcode < 20) {       /* AUTH_HDR_LEN */
1525                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1526                 return 0;
1527         }
1528
1529         if ((client = client_listener_find(listener,
1530                                            &src_ipaddr, src_port)) == NULL) {
1531                 rad_recv_discard(listener->fd);
1532                 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1533                 return 0;
1534         }
1535
1536         /*
1537          *      Some sanity checks, based on the packet code.
1538          */
1539         switch(code) {
1540         case PW_COA_REQUEST:
1541         case PW_DISCONNECT_REQUEST:
1542                 fun = rad_coa_recv;
1543                 break;
1544
1545         default:
1546                 rad_recv_discard(listener->fd);
1547                 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1548                       code, client->shortname, src_port);
1549                 return 0;
1550                 break;
1551         } /* switch over packet types */
1552
1553         /*
1554          *      Now that we've sanity checked everything, receive the
1555          *      packet.
1556          */
1557         packet = rad_recv(listener->fd, client->message_authenticator);
1558         if (!packet) {
1559                 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1560                 DEBUG("%s", fr_strerror());
1561                 return 0;
1562         }
1563
1564         if (!received_request(listener, packet, prequest, client)) {
1565                 rad_free(&packet);
1566                 return 0;
1567         }
1568
1569         *pfun = fun;
1570         return 1;
1571 }
1572 #endif
1573
1574 #ifdef WITH_PROXY
1575 /*
1576  *      Recieve packets from a proxy socket.
1577  */
1578 static int proxy_socket_recv(rad_listen_t *listener,
1579                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1580 {
1581         REQUEST         *request;
1582         RADIUS_PACKET   *packet;
1583         RAD_REQUEST_FUNP fun = NULL;
1584         char            buffer[128];
1585
1586         packet = rad_recv(listener->fd, 0);
1587         if (!packet) {
1588                 radlog(L_ERR, "%s", fr_strerror());
1589                 return 0;
1590         }
1591
1592         /*
1593          *      FIXME: Client MIB updates?
1594          */
1595         switch(packet->code) {
1596         case PW_AUTHENTICATION_ACK:
1597         case PW_ACCESS_CHALLENGE:
1598         case PW_AUTHENTICATION_REJECT:
1599                 fun = rad_authenticate;
1600                 break;
1601
1602 #ifdef WITH_ACCOUNTING
1603         case PW_ACCOUNTING_RESPONSE:
1604                 fun = rad_accounting;
1605                 break;
1606 #endif
1607
1608 #ifdef WITH_COA
1609         case PW_DISCONNECT_ACK:
1610         case PW_DISCONNECT_NAK:
1611         case PW_COA_ACK:
1612         case PW_COA_NAK:
1613                 fun = rad_coa_reply;
1614                 break;
1615 #endif
1616
1617         default:
1618                 /*
1619                  *      FIXME: Update MIB for packet types?
1620                  */
1621                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1622                        "from home server %s port %d - ID %d : IGNORED",
1623                        packet->code,
1624                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1625                        packet->src_port, packet->id);
1626                 rad_free(&packet);
1627                 return 0;
1628         }
1629
1630         request = received_proxy_response(packet);
1631         if (!request) {
1632                 rad_free(&packet);
1633                 return 0;
1634         }
1635
1636 #ifdef WITH_COA
1637         /*
1638          *      Distinguish proxied CoA requests from ones we
1639          *      originate.
1640          */
1641         if ((fun == rad_coa_reply) &&
1642             (request->packet->code == request->proxy->code)) {
1643                 fun = rad_coa_recv;
1644         }
1645 #endif
1646
1647         rad_assert(fun != NULL);
1648         *pfun = fun;
1649         *prequest = request;
1650
1651         return 1;
1652 }
1653
1654 #ifdef WITH_TCP
1655 /*
1656  *      Recieve packets from a proxy socket.
1657  */
1658 static int proxy_socket_tcp_recv(rad_listen_t *listener,
1659                                  RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1660 {
1661         REQUEST         *request;
1662         RADIUS_PACKET   *packet;
1663         RAD_REQUEST_FUNP fun = NULL;
1664         listen_socket_t *sock = listener->data;
1665         char            buffer[128];
1666
1667         packet = fr_tcp_recv(listener->fd, 0);
1668         if (!packet) {
1669                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1670                 event_new_fd(listener);
1671                 return 0;
1672         }
1673
1674         /*
1675          *      FIXME: Client MIB updates?
1676          */
1677         switch(packet->code) {
1678         case PW_AUTHENTICATION_ACK:
1679         case PW_ACCESS_CHALLENGE:
1680         case PW_AUTHENTICATION_REJECT:
1681                 fun = rad_authenticate;
1682                 break;
1683
1684 #ifdef WITH_ACCOUNTING
1685         case PW_ACCOUNTING_RESPONSE:
1686                 fun = rad_accounting;
1687                 break;
1688 #endif
1689
1690         default:
1691                 /*
1692                  *      FIXME: Update MIB for packet types?
1693                  */
1694                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1695                        "from home server %s port %d - ID %d : IGNORED",
1696                        packet->code,
1697                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1698                        packet->src_port, packet->id);
1699                 rad_free(&packet);
1700                 return 0;
1701         }
1702
1703         packet->src_ipaddr = sock->other_ipaddr;
1704         packet->src_port = sock->other_port;
1705         packet->dst_ipaddr = sock->my_ipaddr;
1706         packet->dst_port = sock->my_port;
1707
1708         /*
1709          *      FIXME: Have it return an indication of packets that
1710          *      are OK to ignore (dups, too late), versus ones that
1711          *      aren't OK to ignore (unknown response, spoofed, etc.)
1712          *
1713          *      Close the socket on bad packets...
1714          */
1715         request = received_proxy_response(packet);
1716         if (!request) {
1717                 return 0;
1718         }
1719
1720         rad_assert(fun != NULL);
1721         sock->opened = sock->last_packet = request->timestamp;
1722
1723         *pfun = fun;
1724         *prequest = request;
1725
1726         return 1;
1727 }
1728 #endif
1729 #endif
1730
1731
1732 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1733 {
1734         if (!request->reply->code) return 0;
1735
1736         rad_encode(request->reply, request->packet,
1737                    request->client->secret);
1738         rad_sign(request->reply, request->packet,
1739                  request->client->secret);
1740
1741         return 0;
1742 }
1743
1744
1745 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1746 {
1747         if (rad_verify(request->packet, NULL,
1748                        request->client->secret) < 0) {
1749                 return -1;
1750         }
1751
1752         return rad_decode(request->packet, NULL,
1753                           request->client->secret);
1754 }
1755
1756 #ifdef WITH_PROXY
1757 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1758 {
1759         rad_encode(request->proxy, NULL, request->home_server->secret);
1760         rad_sign(request->proxy, NULL, request->home_server->secret);
1761
1762         return 0;
1763 }
1764
1765
1766 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1767 {
1768         /*
1769          *      rad_verify is run in event.c, received_proxy_response()
1770          */
1771
1772         return rad_decode(request->proxy_reply, request->proxy,
1773                            request->home_server->secret);
1774 }
1775 #endif
1776
1777 #include "dhcpd.c"
1778
1779 #include "command.c"
1780
1781 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1782 #ifdef WITH_STATS
1783         { common_socket_parse, NULL,
1784           stats_socket_recv, auth_socket_send,
1785           socket_print, client_socket_encode, client_socket_decode },
1786 #else
1787         /*
1788          *      This always gets defined.
1789          */
1790         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1791 #endif
1792
1793 #ifdef WITH_PROXY
1794         /* proxying */
1795         { common_socket_parse, NULL,
1796           proxy_socket_recv, proxy_socket_send,
1797           socket_print, proxy_socket_encode, proxy_socket_decode },
1798 #endif
1799
1800         /* authentication */
1801         { common_socket_parse, NULL,
1802           auth_socket_recv, auth_socket_send,
1803           socket_print, client_socket_encode, client_socket_decode },
1804
1805 #ifdef WITH_ACCOUNTING
1806         /* accounting */
1807         { common_socket_parse, NULL,
1808           acct_socket_recv, acct_socket_send,
1809           socket_print, client_socket_encode, client_socket_decode},
1810 #endif
1811
1812 #ifdef WITH_DETAIL
1813         /* detail */
1814         { detail_parse, detail_free,
1815           detail_recv, detail_send,
1816           detail_print, detail_encode, detail_decode },
1817 #endif
1818
1819 #ifdef WITH_VMPS
1820         /* vlan query protocol */
1821         { common_socket_parse, NULL,
1822           vqp_socket_recv, vqp_socket_send,
1823           socket_print, vqp_socket_encode, vqp_socket_decode },
1824 #endif
1825
1826 #ifdef WITH_DHCP
1827         /* dhcp query protocol */
1828         { dhcp_socket_parse, NULL,
1829           dhcp_socket_recv, dhcp_socket_send,
1830           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1831 #endif
1832
1833 #ifdef WITH_COMMAND_SOCKET
1834         /* TCP command socket */
1835         { command_socket_parse, command_socket_free,
1836           command_domain_accept, command_domain_send,
1837           command_socket_print, command_socket_encode, command_socket_decode },
1838 #endif
1839
1840 #ifdef WITH_COA
1841         /* Change of Authorization */
1842         { common_socket_parse, NULL,
1843           coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1844           socket_print, client_socket_encode, client_socket_decode },
1845 #endif
1846
1847 };
1848
1849
1850
1851 /*
1852  *      Binds a listener to a socket.
1853  */
1854 static int listen_bind(rad_listen_t *this)
1855 {
1856         int rcode;
1857         struct sockaddr_storage salocal;
1858         socklen_t       salen;
1859         listen_socket_t *sock = this->data;
1860 #ifndef WITH_TCP
1861 #define proto_for_port "udp"
1862 #define sock_type SOCK_DGRAM
1863 #else
1864         const char *proto_for_port = "udp";
1865         int sock_type = SOCK_DGRAM;
1866         
1867         if (sock->proto == IPPROTO_TCP) {
1868 #ifdef WITH_VMPS
1869                 if (this->type == RAD_LISTEN_VQP) {
1870                         radlog(L_ERR, "VQP does not support TCP transport");
1871                         return -1;
1872                 }
1873 #endif
1874
1875                 proto_for_port = "tcp";
1876                 sock_type = SOCK_STREAM;        
1877         }
1878 #endif
1879
1880         /*
1881          *      If the port is zero, then it means the appropriate
1882          *      thing from /etc/services.
1883          */
1884         if (sock->my_port == 0) {
1885                 struct servent  *svp;
1886
1887                 switch (this->type) {
1888                 case RAD_LISTEN_AUTH:
1889                         svp = getservbyname ("radius", proto_for_port);
1890                         if (svp != NULL) {
1891                                 sock->my_port = ntohs(svp->s_port);
1892                         } else {
1893                                 sock->my_port = PW_AUTH_UDP_PORT;
1894                         }
1895                         break;
1896
1897 #ifdef WITH_ACCOUNTING
1898                 case RAD_LISTEN_ACCT:
1899                         svp = getservbyname ("radacct", proto_for_port);
1900                         if (svp != NULL) {
1901                                 sock->my_port = ntohs(svp->s_port);
1902                         } else {
1903                                 sock->my_port = PW_ACCT_UDP_PORT;
1904                         }
1905                         break;
1906 #endif
1907
1908 #ifdef WITH_PROXY
1909                 case RAD_LISTEN_PROXY:
1910                         /* leave it at zero */
1911                         break;
1912 #endif
1913
1914 #ifdef WITH_VMPS
1915                 case RAD_LISTEN_VQP:
1916                         sock->my_port = 1589;
1917                         break;
1918 #endif
1919
1920 #ifdef WITH_COA
1921                 case RAD_LISTEN_COA:
1922                         svp = getservbyname ("radius-dynauth", "udp");
1923                         if (svp != NULL) {
1924                                 sock->my_port = ntohs(svp->s_port);
1925                         } else {
1926                                 sock->my_port = PW_COA_UDP_PORT;
1927                         }
1928                         break;
1929 #endif
1930
1931                 default:
1932                         DEBUG("WARNING: Internal sanity check failed in binding to socket.  Ignoring problem.");
1933                         return -1;
1934                 }
1935         }
1936
1937         /*
1938          *      Copy fr_socket() here, as we may need to bind to a device.
1939          */
1940         this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
1941         if (this->fd < 0) {
1942                 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1943                 return -1;
1944         }
1945                 
1946         /*
1947          *      Bind to a device BEFORE touching IP addresses.
1948          */
1949         if (sock->interface) {
1950 #ifdef SO_BINDTODEVICE
1951                 struct ifreq ifreq;
1952                 strcpy(ifreq.ifr_name, sock->interface);
1953
1954                 fr_suid_up();
1955                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1956                                    (char *)&ifreq, sizeof(ifreq));
1957                 fr_suid_down();
1958                 if (rcode < 0) {
1959                         close(this->fd);
1960                         radlog(L_ERR, "Failed binding to interface %s: %s",
1961                                sock->interface, strerror(errno));
1962                         return -1;
1963                 } /* else it worked. */
1964 #else
1965 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1966 #ifdef HAVE_NET_IF_H
1967                 /*
1968                  *      Odds are that any system supporting "bind to
1969                  *      device" also supports IPv6, so this next bit
1970                  *      isn't necessary.  But it's here for
1971                  *      completeness.
1972                  *
1973                  *      If we're doing IPv6, and the scope hasn't yet
1974                  *      been defined, set the scope to the scope of
1975                  *      the interface.
1976                  */
1977                 if (sock->my_ipaddr.af == AF_INET6) {
1978                         if (sock->my_ipaddr.scope == 0) {
1979                                 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
1980                                 if (sock->my_ipaddr.scope == 0) {
1981                                         close(this->fd);
1982                                         radlog(L_ERR, "Failed finding interface %s: %s",
1983                                                sock->interface, strerror(errno));
1984                                         return -1;
1985                                 }
1986                         } /* else scope was defined: we're OK. */
1987                 } else
1988 #endif
1989 #endif
1990                                 /*
1991                                  *      IPv4: no link local addresses,
1992                                  *      and no bind to device.
1993                                  */
1994                 {
1995                         close(this->fd);
1996                         radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
1997                         return -1;
1998                 }
1999 #endif
2000         }
2001
2002 #ifdef WITH_TCP
2003         if (sock->proto == IPPROTO_TCP) {
2004                 int on = 1;
2005
2006                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2007                         close(this->fd);
2008                         radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2009                         return -1;
2010                 }
2011         }
2012 #endif
2013
2014 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2015         else                    /* UDP sockets get UDPfromto */
2016 #endif
2017
2018 #ifdef WITH_UDPFROMTO
2019         /*
2020          *      Initialize udpfromto for all sockets.
2021          */
2022         if (udpfromto_init(this->fd) != 0) {
2023                 close(this->fd);
2024                 return -1;
2025         }
2026 #endif
2027
2028         /*
2029          *      Set up sockaddr stuff.
2030          */
2031         if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2032                 close(this->fd);
2033                 return -1;
2034         }
2035                 
2036 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2037         if (sock->my_ipaddr.af == AF_INET6) {
2038                 /*
2039                  *      Listening on '::' does NOT get you IPv4 to
2040                  *      IPv6 mapping.  You've got to listen on an IPv4
2041                  *      address, too.  This makes the rest of the server
2042                  *      design a little simpler.
2043                  */
2044 #ifdef IPV6_V6ONLY
2045                 
2046                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2047                         int on = 1;
2048                         
2049                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2050                                    (char *)&on, sizeof(on));
2051                 }
2052 #endif /* IPV6_V6ONLY */
2053         }
2054 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2055
2056         if (sock->my_ipaddr.af == AF_INET) {
2057                 UNUSED int flag;
2058                 
2059 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2060                 /*
2061                  *      Disable PMTU discovery.  On Linux, this
2062                  *      also makes sure that the "don't fragment"
2063                  *      flag is zero.
2064                  */
2065                 flag = IP_PMTUDISC_DONT;
2066                 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2067                            &flag, sizeof(flag));
2068 #endif
2069
2070 #if defined(IP_DONTFRAG)
2071                 /*
2072                  *      Ensure that the "don't fragment" flag is zero.
2073                  */
2074                 flag = 0;
2075                 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2076                            &flag, sizeof(flag));
2077 #endif
2078         }
2079
2080 #ifdef WITH_DHCP
2081 #ifdef SO_BROADCAST
2082         if (sock->broadcast) {
2083                 int on = 1;
2084                 
2085                 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2086                         radlog(L_ERR, "Can't set broadcast option: %s\n",
2087                                strerror(errno));
2088                         return -1;
2089                 }
2090         }
2091 #endif
2092 #endif
2093
2094         /*
2095          *      May be binding to priviledged ports.
2096          */
2097         if (sock->my_port != 0) {
2098 #ifdef SO_REUSEADDR
2099                 int on = 1;
2100
2101                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2102                         radlog(L_ERR, "Can't set re-use address option: %s\n",
2103                                strerror(errno));
2104                         return -1;
2105                 }
2106 #endif
2107
2108                 fr_suid_up();
2109                 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2110                 fr_suid_down();
2111                 if (rcode < 0) {
2112                         char buffer[256];
2113                         close(this->fd);
2114                         
2115                         this->print(this, buffer, sizeof(buffer));
2116                         radlog(L_ERR, "Failed binding to %s: %s\n",
2117                                buffer, strerror(errno));
2118                         return -1;
2119                 }
2120         
2121                 /*
2122                  *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
2123                  *      kernel instead binds us to a 1.2.3.4.  If this
2124                  *      happens, notice, and remember our real IP.
2125                  */
2126                 {
2127                         struct sockaddr_storage src;
2128                         socklen_t               sizeof_src = sizeof(src);
2129                         
2130                         memset(&src, 0, sizeof_src);
2131                         if (getsockname(this->fd, (struct sockaddr *) &src,
2132                                         &sizeof_src) < 0) {
2133                                 radlog(L_ERR, "Failed getting socket name: %s",
2134                                        strerror(errno));
2135                                 return -1;
2136                         }
2137                         
2138                         if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2139                                                 &sock->my_ipaddr, &sock->my_port)) {
2140                                 radlog(L_ERR, "Socket has unsupported address family");
2141                                 return -1;
2142                         }
2143                 }
2144         }
2145
2146 #ifdef WITH_TCP
2147         if (sock->proto == IPPROTO_TCP) {
2148                 if (listen(this->fd, 8) < 0) {
2149                         close(this->fd);
2150                         radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2151                         return -1;
2152                 }
2153         } else
2154 #endif
2155
2156           if (fr_nonblock(this->fd) < 0) {
2157                   close(this->fd);
2158                   radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2159                          strerror(errno));
2160                   return -1;
2161           }
2162
2163         /*
2164          *      Mostly for proxy sockets.
2165          */
2166         sock->other_ipaddr.af = sock->my_ipaddr.af;
2167
2168 /*
2169  *      Don't screw up other people.
2170  */
2171 #undef proto_for_port
2172 #undef sock_type
2173
2174         return 0;
2175 }
2176
2177
2178 /*
2179  *      Allocate & initialize a new listener.
2180  */
2181 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2182 {
2183         rad_listen_t *this;
2184
2185         this = rad_malloc(sizeof(*this));
2186         memset(this, 0, sizeof(*this));
2187
2188         this->type = type;
2189         this->recv = master_listen[this->type].recv;
2190         this->send = master_listen[this->type].send;
2191         this->print = master_listen[this->type].print;
2192         this->encode = master_listen[this->type].encode;
2193         this->decode = master_listen[this->type].decode;
2194
2195         switch (type) {
2196 #ifdef WITH_STATS
2197         case RAD_LISTEN_NONE:
2198 #endif
2199         case RAD_LISTEN_AUTH:
2200 #ifdef WITH_ACCOUNTING
2201         case RAD_LISTEN_ACCT:
2202 #endif
2203 #ifdef WITH_PROXY
2204         case RAD_LISTEN_PROXY:
2205 #endif
2206 #ifdef WITH_VMPS
2207         case RAD_LISTEN_VQP:
2208 #endif
2209 #ifdef WITH_COA
2210         case RAD_LISTEN_COA:
2211 #endif
2212                 this->data = rad_malloc(sizeof(listen_socket_t));
2213                 memset(this->data, 0, sizeof(listen_socket_t));
2214                 break;
2215
2216 #ifdef WITH_DHCP
2217         case RAD_LISTEN_DHCP:
2218                 this->data = rad_malloc(sizeof(dhcp_socket_t));
2219                 memset(this->data, 0, sizeof(dhcp_socket_t));
2220                 break;
2221 #endif
2222
2223 #ifdef WITH_DETAIL
2224         case RAD_LISTEN_DETAIL:
2225                 this->data = NULL;
2226                 break;
2227 #endif
2228
2229 #ifdef WITH_COMMAND_SOCKET
2230         case RAD_LISTEN_COMMAND:
2231                 this->data = rad_malloc(sizeof(fr_command_socket_t));
2232                 memset(this->data, 0, sizeof(fr_command_socket_t));
2233                 break;
2234 #endif
2235
2236         default:
2237                 rad_assert("Unsupported option!" == NULL);
2238                 break;
2239         }
2240
2241         return this;
2242 }
2243
2244 #ifdef WITH_PROXY
2245 /*
2246  *      Externally visible function for creating a new proxy LISTENER.
2247  *
2248  *      Not thread-safe, but all calls to it are protected by the
2249  *      proxy mutex in event.c
2250  */
2251 int proxy_new_listener(home_server *home, int src_port)
2252 {
2253         rad_listen_t *this;
2254         listen_socket_t *sock;
2255
2256         if (!home) return 0;
2257
2258         if ((home->max_connections > 0) &&
2259             (home->num_connections >= home->max_connections)) {
2260                 DEBUG("WARNING: Home server has too many open connections (%d)",
2261                       home->max_connections);
2262                 return 0;
2263         }
2264
2265         this = listen_alloc(RAD_LISTEN_PROXY);
2266
2267         sock = this->data;
2268         sock->other_ipaddr = home->ipaddr;
2269         sock->other_port = home->port;
2270         sock->home = home;
2271
2272         sock->my_ipaddr = home->src_ipaddr;
2273         sock->my_port = src_port;
2274         sock->proto = home->proto;
2275
2276 #ifdef WITH_TCP
2277         sock->last_packet = time(NULL);
2278
2279         if (home->proto == IPPROTO_TCP) {
2280                 this->recv = proxy_socket_tcp_recv;
2281
2282                 /*
2283                  *      FIXME: connect() is blocking!
2284                  *      We do this with the proxy mutex locked, which may
2285                  *      cause large delays!
2286                  *
2287                  *      http://www.developerweb.net/forum/showthread.php?p=13486
2288                  */
2289                 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2290                                                 &home->ipaddr, home->port);
2291         } else
2292 #endif
2293                 this->fd = fr_socket(&home->src_ipaddr, src_port);
2294
2295         if (this->fd < 0) {
2296                 DEBUG("Failed opening client socket: %s", fr_strerror());
2297                 listen_free(&this);
2298                 return 0;
2299         }
2300
2301         /*
2302          *      Figure out which port we were bound to.
2303          */
2304         if (sock->my_port == 0) {
2305                 struct sockaddr_storage src;
2306                 socklen_t               sizeof_src = sizeof(src);
2307                 
2308                 memset(&src, 0, sizeof_src);
2309                 if (getsockname(this->fd, (struct sockaddr *) &src,
2310                                 &sizeof_src) < 0) {
2311                         radlog(L_ERR, "Failed getting socket name: %s",
2312                                strerror(errno));
2313                         listen_free(&this);
2314                         return 0;
2315                 }
2316                 
2317                 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2318                                         &sock->my_ipaddr, &sock->my_port)) {
2319                         radlog(L_ERR, "Socket has unsupported address family");
2320                         listen_free(&this);
2321                         return 0;
2322                 }
2323         }
2324
2325         /*
2326          *      Tell the event loop that we have a new FD
2327          */
2328         if (!event_new_fd(this)) {
2329                 listen_free(&this);
2330                 return 0;
2331         }
2332         
2333         return 1;
2334 }
2335 #endif
2336
2337
2338 static const FR_NAME_NUMBER listen_compare[] = {
2339 #ifdef WITH_STATS
2340         { "status",     RAD_LISTEN_NONE },
2341 #endif
2342         { "auth",       RAD_LISTEN_AUTH },
2343 #ifdef WITH_ACCOUNTING
2344         { "acct",       RAD_LISTEN_ACCT },
2345 #endif
2346 #ifdef WITH_DETAIL
2347         { "detail",     RAD_LISTEN_DETAIL },
2348 #endif
2349 #ifdef WITH_PROXY
2350         { "proxy",      RAD_LISTEN_PROXY },
2351 #endif
2352 #ifdef WITH_VMPS
2353         { "vmps",       RAD_LISTEN_VQP },
2354 #endif
2355 #ifdef WITH_DHCP
2356         { "dhcp",       RAD_LISTEN_DHCP },
2357 #endif
2358 #ifdef WITH_COMMAND_SOCKET
2359         { "control",    RAD_LISTEN_COMMAND },
2360 #endif
2361 #ifdef WITH_COA
2362         { "coa",        RAD_LISTEN_COA },
2363 #endif
2364         { NULL, 0 },
2365 };
2366
2367
2368 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2369 {
2370         int             type, rcode;
2371         char            *listen_type;
2372         rad_listen_t    *this;
2373
2374         listen_type = NULL;
2375         
2376         cf_log_info(cs, "listen {");
2377
2378         rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2379                               &listen_type, "");
2380         if (rcode < 0) return NULL;
2381         if (rcode == 1) {
2382                 free(listen_type);
2383                 cf_log_err(cf_sectiontoitem(cs),
2384                            "No type specified in listen section");
2385                 return NULL;
2386         }
2387
2388         type = fr_str2int(listen_compare, listen_type, -1);
2389         if (type < 0) {
2390                 cf_log_err(cf_sectiontoitem(cs),
2391                            "Invalid type \"%s\" in listen section.",
2392                            listen_type);
2393                 free(listen_type);
2394                 return NULL;
2395         }
2396         free(listen_type);
2397
2398         /*
2399          *      Allow listen sections in the default config to
2400          *      refer to a server.
2401          */
2402         if (!server) {
2403                 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2404                                       &server, NULL);
2405                 if (rcode == 1) { /* compatiblity with 2.0-pre */
2406                         rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2407                                               &server, NULL);
2408                 }
2409                 if (rcode < 0) return NULL;
2410         }
2411
2412 #ifdef WITH_PROXY
2413         /*
2414          *      We were passed a virtual server, so the caller is
2415          *      defining a proxy listener inside of a virtual server.
2416          *      This isn't allowed right now.
2417          */
2418         else if (type == RAD_LISTEN_PROXY) {
2419                 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2420                 return NULL;
2421         }
2422 #endif
2423
2424         /*
2425          *      Set up cross-type data.
2426          */
2427         this = listen_alloc(type);
2428         this->server = server;
2429         this->fd = -1;
2430
2431         /*
2432          *      Call per-type parser.
2433          */
2434         if (master_listen[type].parse(cs, this) < 0) {
2435                 listen_free(&this);
2436                 return NULL;
2437         }
2438
2439         cf_log_info(cs, "}");
2440
2441         return this;
2442 }
2443
2444 static int is_loopback(const fr_ipaddr_t *ipaddr)
2445 {
2446         /*
2447          *      We shouldn't proxy on loopback.
2448          */
2449         if ((ipaddr->af == AF_INET) &&
2450             (ipaddr->ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) {
2451                 return 1;
2452         }
2453         
2454 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2455         if ((ipaddr->af == AF_INET6) &&
2456             (IN6_IS_ADDR_LINKLOCAL(&ipaddr->ipaddr.ip6addr))) {
2457                 return 1;
2458         }
2459 #endif
2460
2461         return 0;
2462 }
2463
2464 /*
2465  *      Generate a list of listeners.  Takes an input list of
2466  *      listeners, too, so we don't close sockets with waiting packets.
2467  */
2468 int listen_init(CONF_SECTION *config, rad_listen_t **head)
2469 {
2470         int             override = FALSE;
2471         int             rcode;
2472         CONF_SECTION    *cs = NULL;
2473         rad_listen_t    **last;
2474         rad_listen_t    *this;
2475         fr_ipaddr_t     server_ipaddr;
2476         int             auth_port = 0;
2477 #ifdef WITH_PROXY
2478         int             defined_proxy = 0;
2479 #endif
2480
2481         /*
2482          *      We shouldn't be called with a pre-existing list.
2483          */
2484         rad_assert(head && (*head == NULL));
2485
2486         last = head;
2487         server_ipaddr.af = AF_UNSPEC;
2488
2489         /*
2490          *      If the port is specified on the command-line,
2491          *      it over-rides the configuration file.
2492          *
2493          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2494          */
2495         if (mainconfig.port >= 0) auth_port = mainconfig.port;
2496
2497         /*
2498          *      If the IP address was configured on the command-line,
2499          *      use that as the "bind_address"
2500          */
2501         if (mainconfig.myip.af != AF_UNSPEC) {
2502                 memcpy(&server_ipaddr, &mainconfig.myip,
2503                        sizeof(server_ipaddr));
2504                 override = TRUE;
2505                 goto bind_it;
2506         }
2507
2508         /*
2509          *      Else look for bind_address and/or listen sections.
2510          */
2511         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
2512         rcode = cf_item_parse(config, "bind_address",
2513                               PW_TYPE_IPADDR,
2514                               &server_ipaddr.ipaddr.ip4addr, NULL);
2515         if (rcode < 0) return -1; /* error parsing it */
2516
2517         if (rcode == 0) { /* successfully parsed IPv4 */
2518                 listen_socket_t *sock;
2519                 server_ipaddr.af = AF_INET;
2520
2521                 radlog(L_INFO, "WARNING: The directive 'bind_address' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
2522
2523         bind_it:
2524 #ifdef WITH_VMPS
2525                 if (strcmp(progname, "vmpsd") == 0) {
2526                         this = listen_alloc(RAD_LISTEN_VQP);
2527                         if (!auth_port) auth_port = 1589;
2528                 } else
2529 #endif
2530                         this = listen_alloc(RAD_LISTEN_AUTH);
2531
2532                 sock = this->data;
2533
2534                 sock->my_ipaddr = server_ipaddr;
2535                 sock->my_port = auth_port;
2536
2537                 sock->clients = clients_parse_section(config);
2538                 if (!sock->clients) {
2539                         cf_log_err(cf_sectiontoitem(config),
2540                                    "Failed to find any clients for this listen section");
2541                         listen_free(&this);
2542                         return -1;
2543                 }
2544
2545                 if (listen_bind(this) < 0) {
2546                         listen_free(head);
2547                         radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2548                         listen_free(&this);
2549                         return -1;
2550                 }
2551                 auth_port = sock->my_port;      /* may have been updated in listen_bind */
2552                 if (override) {
2553                         cs = cf_section_sub_find_name2(config, "server",
2554                                                        mainconfig.name);
2555                         if (cs) this->server = mainconfig.name;
2556                 }
2557
2558                 *last = this;
2559                 last = &(this->next);
2560
2561 #ifdef WITH_VMPS
2562                 /*
2563                  *      No acct for vmpsd
2564                  */
2565                 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2566 #endif
2567
2568 #ifdef WITH_ACCOUNTING
2569                 /*
2570                  *      Open Accounting Socket.
2571                  *
2572                  *      If we haven't already gotten acct_port from
2573                  *      /etc/services, then make it auth_port + 1.
2574                  */
2575                 this = listen_alloc(RAD_LISTEN_ACCT);
2576                 sock = this->data;
2577
2578                 /*
2579                  *      Create the accounting socket.
2580                  *
2581                  *      The accounting port is always the
2582                  *      authentication port + 1
2583                  */
2584                 sock->my_ipaddr = server_ipaddr;
2585                 sock->my_port = auth_port + 1;
2586
2587                 sock->clients = clients_parse_section(config);
2588                 if (!sock->clients) {
2589                         cf_log_err(cf_sectiontoitem(config),
2590                                    "Failed to find any clients for this listen section");
2591                         return -1;
2592                 }
2593
2594                 if (listen_bind(this) < 0) {
2595                         listen_free(&this);
2596                         listen_free(head);
2597                         radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2598                         return -1;
2599                 }
2600
2601                 if (override) {
2602                         cs = cf_section_sub_find_name2(config, "server",
2603                                                        mainconfig.name);
2604                         if (cs) this->server = mainconfig.name;
2605                 }
2606
2607                 *last = this;
2608                 last = &(this->next);
2609 #endif
2610         } else if (mainconfig.port > 0) { /* no bind address, but a port */
2611                 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2612                        mainconfig.port);
2613                 return -1;
2614         }
2615
2616         /*
2617          *      They specified an IP on the command-line, ignore
2618          *      all listen sections except the one in '-n'.
2619          */
2620         if (mainconfig.myip.af != AF_UNSPEC) {
2621                 CONF_SECTION *subcs;
2622                 const char *name2 = cf_section_name2(cs);
2623
2624                 cs = cf_section_sub_find_name2(config, "server",
2625                                                mainconfig.name);
2626                 if (!cs) goto add_sockets;
2627
2628                 /*
2629                  *      Should really abstract this code...
2630                  */
2631                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2632                      subcs != NULL;
2633                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2634                         this = listen_parse(subcs, name2);
2635                         if (!this) {
2636                                 listen_free(head);
2637                                 return -1;
2638                         }
2639
2640                         *last = this;
2641                         last = &(this->next);
2642                 } /* loop over "listen" directives in server <foo> */
2643
2644                 goto add_sockets;
2645         }
2646
2647         /*
2648          *      Walk through the "listen" sections, if they exist.
2649          */
2650         for (cs = cf_subsection_find_next(config, NULL, "listen");
2651              cs != NULL;
2652              cs = cf_subsection_find_next(config, cs, "listen")) {
2653                 this = listen_parse(cs, NULL);
2654                 if (!this) {
2655                         listen_free(head);
2656                         return -1;
2657                 }
2658
2659                 *last = this;
2660                 last = &(this->next);
2661         }
2662
2663         /*
2664          *      Check virtual servers for "listen" sections, too.
2665          *
2666          *      FIXME: Move to virtual server init?
2667          */
2668         for (cs = cf_subsection_find_next(config, NULL, "server");
2669              cs != NULL;
2670              cs = cf_subsection_find_next(config, cs, "server")) {
2671                 CONF_SECTION *subcs;
2672                 const char *name2 = cf_section_name2(cs);
2673                 
2674                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2675                      subcs != NULL;
2676                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2677                         this = listen_parse(subcs, name2);
2678                         if (!this) {
2679                                 listen_free(head);
2680                                 return -1;
2681                         }
2682                         
2683                         *last = this;
2684                         last = &(this->next);
2685                 } /* loop over "listen" directives in virtual servers */
2686         } /* loop over virtual servers */
2687
2688 add_sockets:
2689         /*
2690          *      No sockets to receive packets, this is an error.
2691          *      proxying is pointless.
2692          */
2693         if (!*head) {
2694                 radlog(L_ERR, "The server is not configured to listen on any ports.  Cannot start.");
2695                 return -1;
2696         }
2697
2698         /*
2699          *      Print out which sockets we're listening on, and
2700          *      add them to the event list.
2701          */
2702         for (this = *head; this != NULL; this = this->next) {
2703 #ifdef WITH_PROXY
2704                 if (this->type == RAD_LISTEN_PROXY) {
2705                         defined_proxy = 1;
2706                 }
2707
2708 #endif
2709                 event_new_fd(this);
2710         }
2711
2712         /*
2713          *      If we're proxying requests, open the proxy FD.
2714          *      Otherwise, don't do anything.
2715          */
2716 #ifdef WITH_PROXY
2717         if ((mainconfig.proxy_requests == TRUE) &&
2718             (*head != NULL) && !defined_proxy) {
2719                 listen_socket_t *sock = NULL;
2720                 int             port = 0;
2721                 home_server     home;
2722
2723                 memset(&home, 0, sizeof(home));
2724
2725                 /*
2726                  *      
2727                  */
2728                 home.proto = IPPROTO_UDP;
2729                 home.src_ipaddr = server_ipaddr;
2730
2731                 /*
2732                  *      Find the first authentication port,
2733                  *      and use it
2734                  */
2735                 for (this = *head; this != NULL; this = this->next) {
2736                         if (this->type == RAD_LISTEN_AUTH) {
2737                                 sock = this->data;
2738
2739                                 if (is_loopback(&sock->my_ipaddr)) continue;
2740
2741                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2742                                         home.src_ipaddr = sock->my_ipaddr;
2743                                 }
2744                                 port = sock->my_port + 2;
2745                                 break;
2746                         }
2747 #ifdef WITH_ACCT
2748                         if (this->type == RAD_LISTEN_ACCT) {
2749                                 sock = this->data;
2750
2751                                 if (is_loopback(&sock->my_ipaddr)) continue;
2752
2753                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2754                                         home.src_ipaddr = sock->my_ipaddr;
2755                                 }
2756                                 port = sock->my_port + 1;
2757                                 break;
2758                         }
2759 #endif
2760                 }
2761
2762                 /*
2763                  *      Address is still unspecified, use IPv4.
2764                  */
2765                 if (home.src_ipaddr.af == AF_UNSPEC) {
2766                         home.src_ipaddr.af = AF_INET;
2767                         /* everything else is already set to zero */
2768                 }
2769
2770                 home.ipaddr.af = home.src_ipaddr.af;
2771                 /* everything else is already set to zero */
2772
2773                 if (!proxy_new_listener(&home, port)) {
2774                         listen_free(head);
2775                         return -1;
2776                 }
2777         }
2778 #endif
2779
2780         /*
2781          *      Haven't defined any sockets.  Die.
2782          */
2783         if (!*head) return -1;
2784
2785
2786         return 0;
2787 }
2788
2789 /*
2790  *      Free a linked list of listeners;
2791  */
2792 void listen_free(rad_listen_t **head)
2793 {
2794         rad_listen_t *this;
2795
2796         if (!head || !*head) return;
2797
2798         this = *head;
2799         while (this) {
2800                 rad_listen_t *next = this->next;
2801
2802                 /*
2803                  *      Other code may have eaten the FD.
2804                  */
2805                 if (this->fd >= 0) close(this->fd);
2806
2807                 if (master_listen[this->type].free) {
2808                         master_listen[this->type].free(this);
2809                 }
2810
2811 #ifdef WITH_TCP
2812                 if ((this->type == RAD_LISTEN_AUTH) ||
2813 #ifdef WITH_ACCT
2814                     (this->type == RAD_LISTEN_ACCT) ||
2815 #endif
2816 #ifdef WITH_PROXY
2817                     (this->type == RAD_LISTEN_PROXY)
2818 #endif
2819                         ) {
2820                         listen_socket_t *sock = this->data;
2821                         rad_free(&sock->packet);
2822                 }
2823 #endif
2824
2825                 free(this->data);
2826                 free(this);
2827
2828                 this = next;
2829         }
2830
2831         *head = NULL;
2832 }
2833
2834 #ifdef WITH_STATS
2835 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2836                                           int port)
2837 {
2838         rad_listen_t *this;
2839
2840         for (this = mainconfig.listen; this != NULL; this = this->next) {
2841                 listen_socket_t *sock;
2842
2843                 if ((this->type != RAD_LISTEN_AUTH) &&
2844                     (this->type != RAD_LISTEN_ACCT)) continue;
2845                 
2846                 sock = this->data;
2847
2848                 if ((sock->my_port == port) &&
2849                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
2850                         return sock->clients;
2851                 }
2852         }
2853
2854         return NULL;
2855 }
2856 #endif
2857
2858 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2859 {
2860         rad_listen_t *this;
2861
2862         for (this = mainconfig.listen; this != NULL; this = this->next) {
2863                 listen_socket_t *sock;
2864
2865                 /*
2866                  *      FIXME: For TCP, ignore the *secondary*
2867                  *      listeners associated with the main socket.
2868                  */
2869                 if ((this->type != RAD_LISTEN_AUTH) &&
2870                     (this->type != RAD_LISTEN_ACCT)) continue;
2871                 
2872                 sock = this->data;
2873
2874                 if ((sock->my_port == port) &&
2875                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
2876                         return this;
2877                 }
2878
2879                 if ((sock->my_port == port) &&
2880                     fr_inaddr_any(&sock->my_ipaddr)) {
2881                         return this;
2882                 }
2883         }
2884
2885         return NULL;
2886 }