All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
listen.c
Go to the documentation of this file.
1 /*
2  * listen.c Handle socket stuff
3  *
4  * Version: $Id: 26f9eafb631df2439ca2c9fcd322afabca535c37 $
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 RCSID("$Id: 26f9eafb631df2439ca2c9fcd322afabca535c37 $")
25 
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/rad_assert.h>
29 #include <freeradius-devel/process.h>
30 #include <freeradius-devel/protocol.h>
31 #include <freeradius-devel/modpriv.h>
32 #include <freeradius-devel/net.h>
33 
34 #include <freeradius-devel/detail.h>
35 
36 #include <freeradius-devel/udp.h>
37 
38 #ifdef HAVE_SYS_RESOURCE_H
39 # include <sys/resource.h>
40 #endif
41 
42 #ifdef HAVE_NET_IF_H
43 # include <net/if.h>
44 #endif
45 
46 #ifdef HAVE_FCNTL_H
47  #include <fcntl.h>
48 #endif
49 
50 #ifdef HAVE_SYS_STAT_H
51 # include <sys/stat.h>
52 #endif
53 
54 #ifdef DEBUG_PRINT_PACKET
55 static void print_packet(RADIUS_PACKET *packet)
56 {
57  char src[256], dst[256];
58 
59  fr_inet_ntoh(&packet->src_ipaddr, src, sizeof(src));
60  fr_inet_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
61 
62  fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
63  src, packet->src_port, dst, packet->dst_port);
64 
65 }
66 #endif
67 
68 /*
69  * This is a structure which holds all of the listeners. The
70  * listeners may appear in multiple places, so we want to be able
71  * to know where they are, without trolling through all of the configuration.
72  */
73 typedef struct listen_config_t {
74  struct listen_config_t *next; //!< the next listener
75  CONF_SECTION *server; //!< encapsulating server configuratiuon
76  CONF_SECTION *cs; //!< configuration for this listener
77  char const *server_name; //!< name of the virtual server (if any)
78  lt_dlhandle *handle; //!< to dynamically loaded library (if any)
79  RAD_LISTEN_TYPE type; //! same as Listen-Socket-Type
80  fr_protocol_t *proto; //!< pointer to the protocol handler.
81 
82  rad_listen_t *listener; //!< created from this configuration
84 
85 static TALLOC_CTX *listen_ctx = NULL;
87 
90 
91 #ifdef WITH_COMMAND_SOCKET
93 static int command_tcp_send(rad_listen_t *listener, REQUEST *request);
94 static int command_write_magic(int newfd, listen_socket_t *sock);
95 #endif
96 
98 
100 {
101  dlclose(lc->handle);
102  return 0;
103 }
104 
105 /*
106  * Bootstrap a listener. Do basic sanity checking, load plugins,
107  * define types.
108  */
110 {
111  listen_config_t **last = &listen_config;
112  listen_config_t *lc;
113  CONF_PAIR *cp;
114  CONF_SECTION *tls;
115  int transports;
116  char const *value;
117  fr_dict_enum_t const *dv;
118  lt_dlhandle *handle = NULL;
119  fr_protocol_t *proto = NULL;
120 
121  if (!listen_ctx) listen_ctx = talloc_init("listen_config_t");
122 
123  while (*last != NULL) last = &(*last)->next;
124 
125  cp = cf_pair_find(cs, "type");
126  if (!cp) {
127  cf_log_err_cs(cs, "No 'type' specified in listen section");
128  return -1;
129  }
130 
131  value = cf_pair_value(cp);
132  if (!value) {
133  cf_log_err_cs(cs, "Invalid 'type' specified in listen section");
134  return -1;
135  }
136 
137 #ifdef WITH_PROXY
138  /*
139  * Only control sockets and proxy sockets are global for now.
140  */
141  if (!server_name) {
142  if ((strcmp(value, "control") != 0) &&
143  (strcmp(value, "proxy") != 0)) {
144  cf_log_err_cs(cs, "Listeners of type '%s' MUST be defined in a server.", value);
145  return -1;
146  }
147 
148  } else {
149  if ((strcmp(value, "control") == 0) ||
150  (strcmp(value, "proxy") == 0)) {
151  cf_log_err_cs(cs, "Listeners of type '%s' MUST NOT be defined in a server.", value);
152  return -1;
153  }
154  }
155 #endif
156 
157  /*
158  * Anything NOT these types are plugins.
159  *
160  * At some point, we'll move all of these to plugins.
161  */
162  if (!((strcmp(value, "control") == 0) ||
163  (strcmp(value, "status") == 0) ||
164  (strcmp(value, "coa") == 0) ||
165  (strcmp(value, "detail") == 0) ||
166  (strcmp(value, "auth") == 0) ||
167  (strcmp(value, "acct") == 0) ||
168  (strcmp(value, "auth+acct") == 0))) {
169  char buffer[256];
170  static int max_listener = 256;
171 
172  /*
173  * Load the library.
174  */
175  snprintf(buffer, sizeof(buffer), "proto_%s", value);
176  handle = lt_dlopenext(buffer);
177  if (!handle) {
178  cf_log_err_cs(cs, "Failed loading dynamic protocol %s", value);
179  return -1;
180  }
181 
182  /*
183  * Find the main symbol, which is the same as the
184  * library name.
185  */
186  proto = dlsym(handle, buffer);
187  if (!proto) {
188  cf_log_err_cs(cs,
189  "Failed linking to protocol %s : %s\n",
190  value, dlerror());
191  dlclose(handle);
192  return -1;
193  }
194 
195  if (proto->magic != RLM_MODULE_INIT) {
196  ERROR("Failed to load protocol '%s', it has the wrong version.", value);
197  dlclose(handle);
198  return -1;
199  }
200 
201  /*
202  * We need numbers for internal use.
203  */
204  dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), value);
205  if (!dv) {
206  if (fr_dict_enum_add(NULL, "Listen-Socket-Type", value, max_listener++) < 0) {
207  cf_log_err_cs(cs,
208  "Failed adding dictionary entry for protocol %s: %s",
209  value, fr_strerror());
210  dlclose(handle);
211  return -1;
212  }
213  }
214  }
215 
216  /*
217  * The type MUST now be defined in the dictionaries.
218  */
219  dv = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_LISTEN_SOCKET_TYPE), value);
220  if (!dv) {
221  cf_log_err_cs(cs, "Failed finding dictionary entry for protocol %s",
222  value);
223  if (handle) lt_dlclose(handle);
224  return -1;
225  }
226 
227  if (!proto) proto = &master_listen[dv->value];
228 
229  /*
230  * Check the allowed transport protocols. For most
231  * sockets, it's a UDP and/or TCP.
232  */
233  transports = 0;
234 
235  if (proto->transports != 0) {
236  cp = cf_pair_find(cs, "proto");
237  if (!cp) {
238  transports = TRANSPORT_UDP;
239  value = "udp";
240 
241  } else {
242  value = cf_pair_value(cp);
243  if (!value) {
244  cf_log_err_cs(cs, "No value for 'proto'");
245  return -1;
246  }
247 
248  if (strcmp(value, "udp") == 0) {
249  transports = TRANSPORT_UDP;
250 
251  } else if (strcmp(value, "tcp") == 0) {
252  transports = TRANSPORT_TCP;
253 
254  } else {
255  cf_log_err_cs(cs, "Unknown transport protocol 'proto = %s'", value);
256  return -1;
257  }
258  }
259 
260  /*
261  * Asked for UDP and required TCP, or require UDP and asked for TCP.
262  */
263  if ((transports & proto->transports) == 0) {
264  cf_log_err_cs(cs, "Invalid transport 'proto = %s' for listeners of 'type = %s'",
265  value, proto->name);
266  return -1;
267  }
268 
269 #ifdef WITH_PROXY
270  /*
271  * We can open UDP sockets on particular IPs, as
272  * they're not connected to any destination. We
273  * cannot open an outbound TCP socket on an IP
274  * address unless we know the destination.
275  */
276  if ((strcmp(proto->name, "proxy") == 0) && (transports == TRANSPORT_TCP)) {
277  cf_log_err_cs(cs, "Invalid transport 'proto = %s' for listeners of 'type = %s'",
278  value, proto->name);
279  return -1;
280  }
281 #endif
282  } /* else we let the socket parse routine figure out what to do */
283 
284  /*
285  * Check the TLS configuration. For now, we only allow
286  * TLS over TCP. And even then, only sometimes.
287  *
288  * If there's no "tls" section, that's fine, too.
289  */
290  tls = cf_section_sub_find(cs, "tls");
291 #ifndef WITH_TCP
292  if (tls) {
293  cf_log_err_cs(cs, "TLS transport is not available in this executable");
294  return -1;
295  }
296 
297 #else
298  if (tls) {
299  if (!proto->tls) {
300  cf_log_err_cs(cs, "TLS transport is not available for listeners with 'type = %s",
301  proto->name);
302  return -1;
303  }
304 
305  if (transports == TRANSPORT_UDP) {
306  cf_log_err_cs(cs, "TLS transport is not available for listeners with 'proto = udp'");
307  return -1;
308  }
309  }
310 #endif
311 
312  /*
313  * We allocate listeners from a new context, so that we can
314  * re-use them on HUP.
315  */
316  lc = talloc_zero(listen_ctx, listen_config_t);
317  if (!lc) return -1;
318 
319  *last = lc;
320 
321  lc->server = server;
322  lc->cs = cs;
323  lc->server_name = server_name;
324  lc->handle = handle;
325  lc->type = dv->value;
326  lc->proto = proto;
327 
328  lc->listener = listen_parse(lc);
329  if (!lc->listener) {
330  talloc_free(lc);
331  return -1;
332  }
333 
334  if (handle) talloc_set_destructor(lc, _listen_config_free);
335 
336 
337  return 0;
338 }
339 
340 
341 /*
342  * Find a per-socket client.
343  */
345  fr_ipaddr_t const *ipaddr, uint16_t src_port)
346 {
347 #ifdef WITH_DYNAMIC_CLIENTS
348  int rcode;
349  REQUEST *request;
350  RADCLIENT *created;
351 #endif
352  time_t now;
353  RADCLIENT *client;
354  RADCLIENT_LIST *clients;
355  listen_socket_t *sock;
356 
357  rad_assert(listener != NULL);
358  rad_assert(ipaddr != NULL);
359 
360  sock = listener->data;
361  clients = sock->clients;
362 
363  /*
364  * This HAS to have been initialized previously.
365  */
366  rad_assert(clients != NULL);
367 
368  client = client_find(clients, ipaddr, sock->proto);
369  if (!client) {
370  char name[256], buffer[INET6_ADDRSTRLEN];
371 
372 #ifdef WITH_DYNAMIC_CLIENTS
373  unknown: /* used only for dynamic clients */
374 #endif
375 
376  /*
377  * DoS attack quenching, but only in daemon mode.
378  * If they're running in debug mode, show them
379  * every packet.
380  */
381  if (rad_debug_lvl == 0) {
382  static time_t last_printed = 0;
383 
384  now = time(NULL);
385  if (last_printed == now) return NULL;
386 
387  last_printed = now;
388  }
389 
390  listener->print(listener, name, sizeof(name));
391 
392  radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
393 #ifdef WITH_TCP
394  " proto %s"
395 #endif
396  , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
397  buffer, sizeof(buffer)), src_port
398 #ifdef WITH_TCP
399  , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
400 #endif
401  );
402  return NULL;
403  }
404 
405 #ifndef WITH_DYNAMIC_CLIENTS
406  return client; /* return the found client. */
407 #else
408 
409  /*
410  * No server defined, and it's not dynamic. Return it.
411  */
412  if (!client->client_server && !client->dynamic) return client;
413 
414  now = time(NULL);
415 
416  /*
417  * It's a dynamically generated client, check it.
418  */
419  if (client->dynamic && (src_port != 0)) {
420 # ifdef HAVE_SYS_STAT_H
421  char const *filename;
422 # endif
423 
424  /*
425  * Lives forever. Return it.
426  */
427  if (client->lifetime == 0) return client;
428 
429  /*
430  * Rate-limit the deletion of known clients.
431  * This makes them last a little longer, but
432  * prevents the server from melting down if (say)
433  * 10k clients all expire at once.
434  */
435  if (now == client->last_new_client) return client;
436 
437  /*
438  * It's not dead yet. Return it.
439  */
440  if ((client->created + client->lifetime) > now) return client;
441 
442 # ifdef HAVE_SYS_STAT_H
443  /*
444  * The client was read from a file, and the file
445  * hasn't changed since the client was created.
446  * Just renew the creation time, and continue.
447  * We don't need to re-load the same information.
448  */
449  if (client->cs &&
450  (filename = cf_section_filename(client->cs)) != NULL) {
451  struct stat buf;
452 
453  if ((stat(filename, &buf) >= 0) &&
454  (buf.st_mtime < client->created)) {
455  client->created = now;
456  return client;
457  }
458  }
459 # endif
460 
461 
462  /*
463  * This really puts them onto a queue for later
464  * deletion.
465  */
466  client_delete(clients, client);
467 
468  /*
469  * Go find the enclosing network again.
470  */
471  client = client_find(clients, ipaddr, sock->proto);
472 
473  /*
474  * WTF?
475  */
476  if (!client) goto unknown;
477  if (!client->client_server) goto unknown;
478 
479  /*
480  * At this point, 'client' is the enclosing
481  * network that configures where dynamic clients
482  * can be defined.
483  */
484  rad_assert(client->dynamic == 0);
485 
486  } else if (!client->dynamic && client->rate_limit) {
487  /*
488  * The IP is unknown, so we've found an enclosing
489  * network. Enable DoS protection. We only
490  * allow one new client per second. Known
491  * clients aren't subject to this restriction.
492  */
493  if (now == client->last_new_client) goto unknown;
494  }
495 
496  client->last_new_client = now;
497 
498  request = request_alloc(NULL);
499  if (!request) goto unknown;
500 
501  request->listener = listener;
502  request->client = client;
503  request->packet = fr_radius_recv(NULL, listener->fd, UDP_FLAGS_PEEK);
504  if (!request->packet) { /* badly formed, etc */
505  talloc_free(request);
506  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
507  goto unknown;
508  }
509  (void) talloc_steal(request, request->packet);
510  request->reply = fr_radius_alloc_reply(request, request->packet);
511  if (!request->reply) {
512  talloc_free(request);
513  goto unknown;
514  }
515  request->number = 0;
516  request->priority = listener->type;
517  request->server = client->client_server;
518  request->root = &main_config;
519 
520  /*
521  * Run a fake request through the given virtual server.
522  * Look for FreeRADIUS-Client-IP-Address
523  * FreeRADIUS-Client-Secret
524  * ...
525  *
526  * and create the RADCLIENT structure from that.
527  */
528  RDEBUG("server %s {", request->server);
529 
530  rcode = process_authorize(0, request);
531 
532  RDEBUG("} # server %s", request->server);
533 
534  switch (rcode) {
535  case RLM_MODULE_OK:
536  case RLM_MODULE_UPDATED:
537  break;
538 
539  /*
540  * Likely a fatal error we want to warn the user about
541  */
542  case RLM_MODULE_INVALID:
543  case RLM_MODULE_FAIL:
544  ERROR("Virtual-Server %s returned %s, creating dynamic client failed", request->server,
545  fr_int2str(mod_rcode_table, rcode, "<INVALID>"));
546  talloc_free(request);
547  goto unknown;
548 
549  /*
550  * Probably the result of policy, or the client not existing.
551  */
552  default:
553  DEBUG("Virtual-Server %s returned %s, ignoring client", request->server,
554  fr_int2str(mod_rcode_table, rcode, "<INVALID>"));
555  talloc_free(request);
556  goto unknown;
557  }
558 
559  /*
560  * If the client was updated by rlm_dynamic_clients,
561  * don't create the client from attribute-value pairs.
562  */
563  if (request->client == client) {
564  created = client_afrom_request(clients, request);
565  } else {
566  created = request->client;
567 
568  /*
569  * This frees the client if it isn't valid.
570  */
571  if (!client_add_dynamic(clients, client, created)) goto unknown;
572  }
573 
574  request->server = client->server;
575  exec_trigger(request, NULL, "server.client.add", false);
576 
577  talloc_free(request);
578 
579  if (!created) goto unknown;
580 
581  return created;
582 #endif
583 }
584 
585 static int listen_bind(rad_listen_t *this);
586 
587 #ifdef HAVE_LIBPCAP
588 static int init_pcap(rad_listen_t *this);
589 #endif
590 
591 /*
592  * Process and reply to a server-status request.
593  * Like rad_authenticate and rad_accounting this should
594  * live in it's own file but it's so small we don't bother.
595  */
597 {
598  int rcode = RLM_MODULE_OK;
599  fr_dict_enum_t *dval;
600 
601  switch (request->listener->type) {
602 #ifdef WITH_STATS
603  case RAD_LISTEN_NONE:
604 #endif
605  case RAD_LISTEN_AUTH:
606  dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_AUTZ_TYPE), "Status-Server");
607  if (dval) {
608  rcode = process_authorize(dval->value, request);
609  } else {
610  rcode = RLM_MODULE_OK;
611  }
612 
613  switch (rcode) {
614  case RLM_MODULE_OK:
615  case RLM_MODULE_UPDATED:
616  request->reply->code = PW_CODE_ACCESS_ACCEPT;
617  break;
618 
619  case RLM_MODULE_FAIL:
620  case RLM_MODULE_HANDLED:
621  request->reply->code = 0; /* don't reply */
622  break;
623 
624  default:
625  case RLM_MODULE_REJECT:
626  request->reply->code = PW_CODE_ACCESS_REJECT;
627  break;
628  }
629  break;
630 
631 #ifdef WITH_ACCOUNTING
632  case RAD_LISTEN_ACCT:
633  dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_ACCT_TYPE), "Status-Server");
634  if (dval) {
635  rcode = process_accounting(dval->value, request);
636  } else {
637  rcode = RLM_MODULE_OK;
638  }
639 
640  switch (rcode) {
641  case RLM_MODULE_OK:
642  case RLM_MODULE_UPDATED:
644  break;
645 
646  default:
647  request->reply->code = 0; /* don't reply */
648  break;
649  }
650  break;
651 #endif
652 
653 #ifdef WITH_COA
654  /*
655  * This is a vendor extension. Suggested by Glen
656  * Zorn in IETF 72, and rejected by the rest of
657  * the WG. We like it, so it goes in here.
658  */
659  case RAD_LISTEN_COA:
660  dval = fr_dict_enum_by_name(NULL, fr_dict_attr_by_num(NULL, 0, PW_RECV_COA_TYPE), "Status-Server");
661  if (dval) {
662  rcode = process_recv_coa(dval->value, request);
663  } else {
664  rcode = RLM_MODULE_OK;
665  }
666 
667  switch (rcode) {
668  case RLM_MODULE_OK:
669  case RLM_MODULE_UPDATED:
670  request->reply->code = PW_CODE_COA_ACK;
671  break;
672 
673  default:
674  request->reply->code = 0; /* don't reply */
675  break;
676  }
677  break;
678 #endif
679 
680  default:
681  return 0;
682  }
683 
684 #ifdef WITH_STATS
685  /*
686  * Full statistics are available only on a statistics
687  * socket.
688  */
689  if (request->listener->type == RAD_LISTEN_NONE) {
690  request_stats_reply(request);
691  }
692 #endif
693 
694  return 0;
695 }
696 
697 #ifdef WITH_TCP
698 static int dual_tcp_recv(rad_listen_t *listener)
699 {
700  int rcode;
701  RADIUS_PACKET *packet;
702  RAD_REQUEST_FUNP fun = NULL;
703  listen_socket_t *sock = listener->data;
704  RADCLIENT *client = sock->client;
705 
706  rad_assert(client != NULL);
707 
708  if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
709 
710  /*
711  * Allocate a packet for partial reads.
712  */
713  if (!sock->packet) {
714  sock->packet = fr_radius_alloc(sock, false);
715  if (!sock->packet) return 0;
716 
717  sock->packet->sockfd = listener->fd;
718  sock->packet->src_ipaddr = sock->other_ipaddr;
719  sock->packet->src_port = sock->other_port;
720  sock->packet->dst_ipaddr = sock->my_ipaddr;
721  sock->packet->dst_port = sock->my_port;
722  sock->packet->proto = sock->proto;
723  }
724 
725  /*
726  * Grab the packet currently being processed.
727  */
728  packet = sock->packet;
729 
730  rcode = fr_tcp_read_packet(packet, 0);
731 
732  /*
733  * Still only a partial packet. Put it back, and return,
734  * so that we'll read more data when it's ready.
735  */
736  if (rcode == 0) {
737  return 0;
738  }
739 
740  if (rcode == -1) { /* error reading packet */
741  char buffer[256];
742 
743  ERROR("Invalid packet from %s port %d, closing socket: %s",
744  fr_inet_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
745  packet->src_port, fr_strerror());
746  }
747 
748  if (rcode < 0) { /* error or connection reset */
749  listener->status = RAD_LISTEN_STATUS_EOL;
750 
751  /*
752  * Tell the event handler that an FD has disappeared.
753  */
754  DEBUG("Client has closed connection");
755  radius_update_listener(listener);
756 
757  /*
758  * Do NOT free the listener here. It's in use by
759  * a request, and will need to hang around until
760  * all of the requests are done.
761  *
762  * It is instead free'd in remove_from_request_hash()
763  */
764  return 0;
765  }
766 
767  /*
768  * Some sanity checks, based on the packet code.
769  */
770  switch (packet->code) {
772  if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
773  FR_STATS_INC(auth, total_requests);
774  fun = rad_authenticate;
775  break;
776 
777 # ifdef WITH_ACCOUNTING
779  if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
780  FR_STATS_INC(acct, total_requests);
781  fun = rad_accounting;
782  break;
783 # endif
784 
786  if (!main_config.status_server) {
787  FR_STATS_INC(auth, total_unknown_types);
788  WARN("Ignoring Status-Server request due to security configuration");
789  fr_radius_free(&sock->packet);
790  return 0;
791  }
792  fun = rad_status_server;
793  break;
794 
795  default:
796  bad_packet:
797  FR_STATS_INC(auth, total_unknown_types);
798 
799  DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
800  packet->code, client->shortname, packet->src_port);
801  fr_radius_free(&sock->packet);
802  return 0;
803  } /* switch over packet types */
804 
805  if (!request_receive(NULL, listener, packet, client, fun)) {
806  FR_STATS_INC(auth, total_packets_dropped);
807  fr_radius_free(&sock->packet);
808  return 0;
809  }
810 
811  sock->packet = NULL; /* we have no need for more partial reads */
812  return 1;
813 }
814 
815 
816 static int dual_tcp_accept(rad_listen_t *listener)
817 {
818  int newfd;
819  uint16_t src_port;
820  rad_listen_t *this;
821  socklen_t salen;
822  struct sockaddr_storage src;
823  listen_socket_t *sock;
824  fr_ipaddr_t src_ipaddr;
825  RADCLIENT *client = NULL;
826 
827  salen = sizeof(src);
828 
829  DEBUG2(" ... new connection request on TCP socket");
830 
831  newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
832  if (newfd < 0) {
833  /*
834  * Non-blocking sockets must handle this.
835  */
836 # ifdef EWOULDBLOCK
837  if (errno == EWOULDBLOCK) {
838  return 0;
839  }
840 # endif
841 
842  DEBUG2(" ... failed to accept connection");
843  return -1;
844  }
845 
846  if (!fr_ipaddr_from_sockaddr(&src, salen, &src_ipaddr, &src_port)) {
847  close(newfd);
848  DEBUG2(" ... unknown address family");
849  return 0;
850  }
851 
852  /*
853  * Enforce client IP address checks on accept, not on
854  * every packet.
855  */
856  if ((client = client_listener_find(listener,
857  &src_ipaddr, src_port)) == NULL) {
858  close(newfd);
859  FR_STATS_INC(auth, total_invalid_requests);
860  return 0;
861  }
862 
863 # ifdef WITH_TLS
864  /*
865  * Enforce security restrictions.
866  *
867  * This shouldn't be necessary in practice. However, it
868  * serves as a double-check on configurations. Marking a
869  * client as "tls required" means that any accidental
870  * exposure of the client to non-TLS traffic is
871  * prevented.
872  */
873  if (client->tls_required && !listener->tls) {
874  INFO("Ignoring connection to TLS socket from non-TLS client");
875  close(newfd);
876  return 0;
877  }
878 # endif
879 
880  /*
881  * Enforce max_connections on client && listen section.
882  */
883  if ((client->limit.max_connections != 0) &&
884  (client->limit.max_connections == client->limit.num_connections)) {
885  /*
886  * FIXME: Print client IP/port, and server IP/port.
887  */
888  INFO("Ignoring new connection due to client max_connections (%d)", client->limit.max_connections);
889  close(newfd);
890  return 0;
891  }
892 
893  sock = listener->data;
894  if ((sock->limit.max_connections != 0) &&
895  (sock->limit.max_connections == sock->limit.num_connections)) {
896  /*
897  * FIXME: Print client IP/port, and server IP/port.
898  */
899  INFO("Ignoring new connection due to socket max_connections");
900  close(newfd);
901  return 0;
902  }
903  client->limit.num_connections++;
904  sock->limit.num_connections++;
905 
906  /*
907  * Add the new listener. We require a new context here,
908  * because the allocations for the packet, etc. in the
909  * child listener will be done in a child thread.
910  */
911  this = listen_alloc(NULL, listener->type, listener->proto);
912  if (!this) return -1;
913 
914  /*
915  * Copy everything, including the pointer to the socket
916  * information.
917  */
918  sock = this->data;
919  memcpy(this->data, listener->data, sizeof(*sock));
920  memcpy(this, listener, sizeof(*this));
921  this->next = NULL;
922  this->data = sock; /* fix it back */
923 
924  sock->parent = listener->data;
925  sock->other_ipaddr = src_ipaddr;
926  sock->other_port = src_port;
927  sock->client = client;
928  sock->opened = sock->last_packet = time(NULL);
929 
930  /*
931  * Set the limits. The defaults are the parent limits.
932  * Client limits on max_connections are enforced dynamically.
933  * Set the MINIMUM of client/socket idle timeout or lifetime.
934  */
935  memcpy(&sock->limit, &sock->parent->limit, sizeof(sock->limit));
936 
937  if (client->limit.idle_timeout &&
938  ((sock->limit.idle_timeout == 0) ||
939  (client->limit.idle_timeout < sock->limit.idle_timeout))) {
940  sock->limit.idle_timeout = client->limit.idle_timeout;
941  }
942 
943  if (client->limit.lifetime &&
944  ((sock->limit.lifetime == 0) ||
945  (client->limit.lifetime < sock->limit.lifetime))) {
946  sock->limit.lifetime = client->limit.lifetime;
947  }
948 
949  this->fd = newfd;
950  this->status = RAD_LISTEN_STATUS_INIT;
951 
952  this->parent = listener;
953  if (!rbtree_insert(listener->children, this)) {
954  ERROR("Failed inserting TCP socket into parent list.");
955  }
956 
957 # ifdef WITH_COMMAND_SOCKET
958  if (this->type == RAD_LISTEN_COMMAND) {
959  this->recv = command_tcp_recv;
960  this->send = command_tcp_send;
961  command_write_magic(this->fd, sock);
962  } else
963 # endif
964  {
965 
966  this->recv = dual_tcp_recv;
967 
968 # ifdef WITH_TLS
969  if (this->tls) {
970  this->recv = dual_tls_recv;
971  this->send = dual_tls_send;
972  }
973 # endif
974  }
975 
976  /*
977  * FIXME: set O_NONBLOCK on the accept'd fd.
978  * See djb's portability rants for details.
979  */
980 
981  /*
982  * Tell the event loop that we have a new FD.
983  * This can be called from a child thread...
984  */
986 
987  return 0;
988 }
989 #endif
990 
991 /*
992  * Ensure that we always keep the correct counters.
993  */
994 #ifdef WITH_TCP
996 {
997  listen_socket_t *sock = this->data;
998 
999  if (sock->proto != IPPROTO_TCP) return;
1000 
1001  /*
1002  * Decrement the number of connections.
1003  */
1004  if (sock->parent && (sock->parent->limit.num_connections > 0)) {
1005  sock->parent->limit.num_connections--;
1006  }
1007  if (sock->client && sock->client->limit.num_connections > 0) {
1008  sock->client->limit.num_connections--;
1009  }
1010  if (sock->home && sock->home->limit.num_connections > 0) {
1011  sock->home->limit.num_connections--;
1012  }
1013 }
1014 #else
1015 # define common_socket_free NULL
1016 #endif
1017 
1018 /*
1019  * This function is stupid and complicated.
1020  */
1021 int common_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize)
1022 {
1023  size_t len;
1024  listen_socket_t *sock = this->data;
1025  char const *name = this->proto->name;
1026 
1027 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
1028 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
1029 
1030  ADDSTRING(name);
1031 
1032  if (this->dual) {
1033  ADDSTRING("+acct");
1034  }
1035 
1036  if (sock->interface) {
1037  ADDSTRING(" interface ");
1038  ADDSTRING(sock->interface);
1039  }
1040 
1041 #ifdef WITH_TCP
1042  if (this->recv == dual_tcp_accept) {
1043  ADDSTRING(" proto tcp");
1044  }
1045 #endif
1046 
1047 #ifdef WITH_TCP
1048  /*
1049  * TCP sockets get printed a little differently, to make
1050  * it clear what's going on.
1051  */
1052  if (sock->client) {
1053  ADDSTRING(" from client (");
1054  fr_inet_ntoh(&sock->other_ipaddr, buffer, bufsize);
1055  FORWARD;
1056 
1057  ADDSTRING(", ");
1058  snprintf(buffer, bufsize, "%d", sock->other_port);
1059  FORWARD;
1060  ADDSTRING(") -> (");
1061 
1062  if ((sock->my_ipaddr.af == AF_INET) &&
1063  (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
1064  strlcpy(buffer, "*", bufsize);
1065  } else {
1066  fr_inet_ntoh(&sock->my_ipaddr, buffer, bufsize);
1067  }
1068  FORWARD;
1069 
1070  ADDSTRING(", ");
1071  snprintf(buffer, bufsize, "%d", sock->my_port);
1072  FORWARD;
1073 
1074  if (this->server) {
1075  ADDSTRING(", virtual-server=");
1076  ADDSTRING(this->server);
1077  }
1078 
1079  ADDSTRING(")");
1080 
1081  return 1;
1082  }
1083 
1084 #ifdef WITH_PROXY
1085  /*
1086  * Maybe it's a socket that we opened to a home server.
1087  */
1088  if ((sock->proto == IPPROTO_TCP) &&
1089  (this->type == RAD_LISTEN_PROXY)) {
1090  ADDSTRING(" (");
1091  fr_inet_ntoh(&sock->my_ipaddr, buffer, bufsize);
1092  FORWARD;
1093 
1094  ADDSTRING(", ");
1095  snprintf(buffer, bufsize, "%d", sock->my_port);
1096  FORWARD;
1097  ADDSTRING(") -> home_server (");
1098 
1099  if ((sock->other_ipaddr.af == AF_INET) &&
1100  (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
1101  strlcpy(buffer, "*", bufsize);
1102  } else {
1103  fr_inet_ntoh(&sock->other_ipaddr, buffer, bufsize);
1104  }
1105  FORWARD;
1106 
1107  ADDSTRING(", ");
1108  snprintf(buffer, bufsize, "%d", sock->other_port);
1109  FORWARD;
1110 
1111  ADDSTRING(")");
1112 
1113  return 1;
1114  }
1115 #endif /* WITH_PROXY */
1116 #endif /* WITH_TCP */
1117 
1118  ADDSTRING(" address ");
1119 
1120  if ((sock->my_ipaddr.af == AF_INET) &&
1121  (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
1122  strlcpy(buffer, "*", bufsize);
1123  } else {
1124  fr_inet_ntoh(&sock->my_ipaddr, buffer, bufsize);
1125  }
1126  FORWARD;
1127 
1128  ADDSTRING(" port ");
1129  snprintf(buffer, bufsize, "%d", sock->my_port);
1130  FORWARD;
1131 
1132 #ifdef WITH_TLS
1133  if (this->tls) {
1134  ADDSTRING(" (TLS)");
1135  FORWARD;
1136  }
1137 #endif
1138 
1139  if (this->server) {
1140  ADDSTRING(" bound to server ");
1141  strlcpy(buffer, this->server, bufsize);
1142  }
1143 
1144 #undef ADDSTRING
1145 #undef FORWARD
1146 
1147  return 1;
1148 }
1149 
1150 /*
1151  * Debug the packet if requested.
1152  */
1153 void common_packet_debug(REQUEST *request, RADIUS_PACKET *packet, bool received)
1154 {
1155  char src_ipaddr[FR_IPADDR_STRLEN];
1156  char dst_ipaddr[FR_IPADDR_STRLEN];
1157 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1158  char if_name[IFNAMSIZ];
1159 #endif
1160 
1161  if (!packet) return;
1162  if (!RDEBUG_ENABLED) return;
1163 
1164  /*
1165  * Client-specific debugging re-prints the input
1166  * packet into the client log.
1167  *
1168  * This really belongs in a utility library
1169  */
1170  if (is_radius_code(packet->code)) {
1171  radlog_request(L_DBG, L_DBG_LVL_1, request, "%s %s Id %i from %s%s%s:%i to %s%s%s:%i "
1172 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1173  "%s%s%s"
1174 #endif
1175  "length %zu",
1176  received ? "Received" : "Sent",
1177  fr_packet_codes[packet->code],
1178  packet->id,
1179  packet->src_ipaddr.af == AF_INET6 ? "[" : "",
1180  fr_inet_ntop(src_ipaddr, sizeof(src_ipaddr), &packet->src_ipaddr),
1181  packet->src_ipaddr.af == AF_INET6 ? "]" : "",
1182  packet->src_port,
1183  packet->dst_ipaddr.af == AF_INET6 ? "[" : "",
1184  fr_inet_ntop(dst_ipaddr, sizeof(dst_ipaddr), &packet->dst_ipaddr),
1185  packet->dst_ipaddr.af == AF_INET6 ? "]" : "",
1186  packet->dst_port,
1187 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1188  packet->if_index ? "via " : "",
1189  packet->if_index ? fr_ifname_from_ifindex(if_name, packet->if_index) : "",
1190  packet->if_index ? " " : "",
1191 #endif
1192  packet->data_len);
1193  } else {
1194  radlog_request(L_DBG, L_DBG_LVL_1, request, "%s code %u Id %i from %s%s%s:%i to %s%s%s:%i "
1195 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1196  "%s%s%s"
1197 #endif
1198  "length %zu",
1199  received ? "Received" : "Sent",
1200  packet->code,
1201  packet->id,
1202  packet->src_ipaddr.af == AF_INET6 ? "[" : "",
1203  fr_inet_ntop(src_ipaddr, sizeof(src_ipaddr), &packet->src_ipaddr),
1204  packet->src_ipaddr.af == AF_INET6 ? "]" : "",
1205  packet->src_port,
1206  packet->dst_ipaddr.af == AF_INET6 ? "[" : "",
1207  fr_inet_ntop(dst_ipaddr, sizeof(dst_ipaddr), &packet->dst_ipaddr),
1208  packet->dst_ipaddr.af == AF_INET6 ? "]" : "",
1209  packet->dst_port,
1210 #if defined(WITH_UDPFROMTO) && defined(WITH_IFINDEX_NAME_RESOLUTION)
1211  packet->if_index ? "via " : "",
1212  packet->if_index ? fr_ifname_from_ifindex(if_name, packet->if_index) : "",
1213  packet->if_index ? " " : "",
1214 #endif
1215  packet->data_len);
1216  }
1217 
1218  if (received) {
1219  rdebug_pair_list(L_DBG_LVL_1, request, packet->vps, "");
1220  } else {
1221  rdebug_proto_pair_list(L_DBG_LVL_1, request, packet->vps, "");
1222  }
1223 }
1225  { FR_CONF_OFFSET("skip_duplicate_checks", PW_TYPE_BOOLEAN, rad_listen_t, nodup) },
1226 
1227  { FR_CONF_OFFSET("synchronous", PW_TYPE_BOOLEAN, rad_listen_t, synchronous) },
1228 
1229  { FR_CONF_OFFSET("workers", PW_TYPE_INTEGER, rad_listen_t, workers) },
1231 };
1232 
1233 
1235  { FR_CONF_OFFSET("max_pps", PW_TYPE_INTEGER, listen_socket_t, max_rate) },
1236 
1237 #ifdef WITH_TCP
1238  { FR_CONF_OFFSET("max_connections", PW_TYPE_INTEGER, listen_socket_t, limit.max_connections), .dflt = "16" },
1239  { FR_CONF_OFFSET("lifetime", PW_TYPE_INTEGER, listen_socket_t, limit.lifetime), .dflt = "0" },
1240  { FR_CONF_OFFSET("idle_timeout", PW_TYPE_INTEGER, listen_socket_t, limit.idle_timeout), .dflt = STRINGIFY(30) },
1241 #endif
1243 };
1244 
1245 
1246 #ifdef WITH_TCP
1247 /*
1248  * TLS requires child threads to handle the listeners. Which
1249  * means that we need a separate talloc context per child thread.
1250  * Which means that we need to manually clean up the child
1251  * listeners. Which means we need to manually track them.
1252  *
1253  * All child thread linking/unlinking is done in the master
1254  * thread. If we care, we can later add a mutex for the parent
1255  * listener.
1256  */
1257 static int listener_cmp(void const *one, void const *two)
1258 {
1259  if (one < two) return -1;
1260  if (one > two) return +1;
1261  return 0;
1262 }
1263 
1264 static int listener_unlink(UNUSED void *ctx, UNUSED void *data)
1265 {
1266  return 2; /* unlink this node from the tree */
1267 }
1268 #endif
1269 
1270 
1271 /*
1272  * Parse an authentication or accounting socket.
1273  */
1275 {
1276  int rcode;
1277  uint16_t listen_port;
1278  uint32_t recv_buff;
1279  fr_ipaddr_t ipaddr;
1280  listen_socket_t *sock = this->data;
1281  char const *section_name = NULL;
1282  CONF_SECTION *client_cs, *parentcs;
1283  CONF_SECTION *subcs;
1284  CONF_PAIR *cp;
1285 
1286  /*
1287  * Try IPv4 first
1288  */
1289  memset(&ipaddr, 0, sizeof(ipaddr));
1290  ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1291 
1292  rcode = cf_pair_parse(cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_COMBO_IP_ADDR, &ipaddr), NULL, T_INVALID);
1293  if (rcode < 0) return -1;
1294  if (rcode != 0) rcode = cf_pair_parse(cs, "ipv4addr",
1295  FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, &ipaddr), NULL, T_INVALID);
1296  if (rcode < 0) return -1;
1297  if (rcode != 0) rcode = cf_pair_parse(cs, "ipv6addr",
1298  FR_ITEM_POINTER(PW_TYPE_IPV6_ADDR, &ipaddr), NULL, T_INVALID);
1299  if (rcode < 0) return -1;
1300  /*
1301  * Default to IPv4 INADDR_ANY
1302  */
1303  if (rcode != 0) {
1304  memset(&ipaddr, 0, sizeof(ipaddr));
1305  ipaddr.af = INADDR_ANY;
1306  ipaddr.prefix = 32;
1307  ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1308  }
1309 
1310  rcode = cf_pair_parse(cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, &listen_port), "0", T_BARE_WORD);
1311  if (rcode < 0) return -1;
1312 
1313  rcode = cf_pair_parse(cs, "recv_buff", FR_ITEM_POINTER(PW_TYPE_INTEGER, &recv_buff), "0", T_BARE_WORD);
1314  if (rcode < 0) return -1;
1315  if (recv_buff) {
1316  FR_INTEGER_BOUND_CHECK("recv_buff", recv_buff, >=, 32);
1317  FR_INTEGER_BOUND_CHECK("recv_buff", recv_buff, <=, INT_MAX);
1318  }
1319 
1320  sock->proto = IPPROTO_UDP;
1321 
1322  if (cf_pair_find(cs, "proto")) {
1323 #ifndef WITH_TCP
1324  cf_log_err_cs(cs, "System does not support the TCP protocol. "
1325  "Delete this line from the configuration file");
1326  return -1;
1327 #else
1328  char const *proto = NULL;
1329 # ifdef WITH_TLS
1330  CONF_SECTION *tls;
1331 # endif
1332 
1333  rcode = cf_pair_parse(cs, "proto", FR_ITEM_POINTER(PW_TYPE_STRING, &proto),
1334  "udp", T_DOUBLE_QUOTED_STRING);
1335  if (rcode < 0) return -1;
1336 
1337  if (!proto || strcmp(proto, "udp") == 0) {
1338  sock->proto = IPPROTO_UDP;
1339 
1340  } else if (strcmp(proto, "tcp") == 0) {
1341  sock->proto = IPPROTO_TCP;
1342 
1343  } else {
1344  cf_log_err_cs(cs, "Unknown proto name \"%s\"", proto);
1345  return -1;
1346  }
1347 
1348 # ifdef WITH_TLS
1349  tls = cf_section_sub_find(cs, "tls");
1350  if (tls) {
1351  /*
1352  * If unset, set to default.
1353  */
1354  if (listen_port == 0) listen_port = PW_RADIUS_TLS_PORT;
1355 
1356  this->tls = tls_server_conf_parse(tls);
1357  if (!this->tls) {
1358  return -1;
1359  }
1360 
1361 # ifdef HAVE_PTRHEAD_H
1362  if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
1363  rad_assert(0 == 1);
1364  listen_free(&this);
1365  return 0;
1366  }
1367 # endif
1368 
1369  }
1370 # endif /* WITH_TLS */
1371 #endif /* WITH_TCP */
1372  } /* else there as no "proto" field. */
1373 
1374  /*
1375  * Magical tuning methods!
1376  */
1377  subcs = cf_section_sub_find(cs, "performance");
1378  if (subcs) {
1379  rcode = cf_section_parse(subcs, this,
1380  performance_config);
1381  if (rcode < 0) return -1;
1382 
1383  if (this->synchronous && sock->max_rate) {
1384  WARN("Setting 'max_pps' is incompatible with 'synchronous'. Disabling 'max_pps'");
1385  sock->max_rate = 0;
1386  }
1387 
1388  if (!this->synchronous && this->workers) {
1389  WARN("Setting 'workers' requires 'synchronous'. Disabling 'workers'");
1390  this->workers = 0;
1391  }
1392  }
1393 
1394  subcs = cf_section_sub_find(cs, "limit");
1395  if (subcs) {
1396  rcode = cf_section_parse(subcs, sock,
1397  limit_config);
1398  if (rcode < 0) return -1;
1399 
1400  if (sock->max_rate && ((sock->max_rate < 10) || (sock->max_rate > 1000000))) {
1401  cf_log_err_cs(cs,
1402  "Invalid value for \"max_pps\"");
1403  return -1;
1404  }
1405 
1406 #ifdef WITH_TCP
1407  if ((sock->limit.idle_timeout > 0) && (sock->limit.idle_timeout < 5)) {
1408  WARN("Setting idle_timeout to 5");
1409  sock->limit.idle_timeout = 5;
1410  }
1411 
1412  if ((sock->limit.lifetime > 0) && (sock->limit.lifetime < 5)) {
1413  WARN("Setting lifetime to 5");
1414  sock->limit.lifetime = 5;
1415  }
1416 
1417  if ((sock->limit.lifetime > 0) && (sock->limit.idle_timeout > sock->limit.lifetime)) {
1418  WARN("Setting idle_timeout to 0");
1419  sock->limit.idle_timeout = 0;
1420  }
1421 
1422  /*
1423  * Force no duplicate detection for TCP sockets.
1424  */
1425  if (sock->proto == IPPROTO_TCP) {
1426  this->nodup = true;
1427  }
1428 
1429  } else {
1430  sock->limit.max_connections = 60;
1431  sock->limit.idle_timeout = 30;
1432  sock->limit.lifetime = 0;
1433 #endif
1434  }
1435 
1436  sock->my_ipaddr = ipaddr;
1437  sock->my_port = listen_port;
1438  sock->recv_buff = recv_buff;
1439 
1440 #ifdef WITH_PROXY
1441  if (check_config) {
1442  /*
1443  * Until there is a side effects free way of forwarding a
1444  * request to another virtual server, this check is invalid,
1445  * and should be left disabled.
1446  */
1447 # if 0
1448  if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
1449  char buffer[128];
1450 
1451  ERROR("We have been asked to listen on %s port %d, which is also listed as a "
1452  "home server. This can create a proxy loop",
1453  fr_inet_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)), sock->my_port);
1454  return -1;
1455  }
1456 # endif
1457  return 0; /* don't do anything */
1458  }
1459 #endif
1460 
1461  /*
1462  * If we can bind to interfaces, do so,
1463  * else don't.
1464  */
1465  cp = cf_pair_find(cs, "interface");
1466  if (cp) {
1467  char const *value = cf_pair_value(cp);
1468  if (!value) {
1469  cf_log_err_cs(cs,
1470  "No interface name given");
1471  return -1;
1472  }
1473  sock->interface = value;
1474  }
1475 
1476 #ifdef WITH_DHCP
1477  /*
1478  * If we can do broadcasts..
1479  */
1480  cp = cf_pair_find(cs, "broadcast");
1481  if (cp) {
1482 
1483  /*
1484  * Testing SO_BROADCAST only makes sence if using sockets
1485  * (i.e. if SO_BINDTODEVICE is available).
1486  */
1487 # if defined(SO_BINDTODEVICE) && !defined(SO_BROADCAST)
1488  cf_log_err_cs(cs,
1489  "System does not support broadcast sockets. Delete this line from the configuration file");
1490  return -1;
1491 # else
1492  if (this->type != RAD_LISTEN_DHCP) {
1493  cf_log_err_cp(cp,
1494  "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file");
1495  return -1;
1496  }
1497 
1498  char const *value = cf_pair_value(cp);
1499  if (!value) {
1500  cf_log_err_cs(cs,
1501  "No broadcast value given");
1502  return -1;
1503  }
1504 
1505  /*
1506  * Hack... whatever happened to cf_section_parse?
1507  */
1508  sock->broadcast = (strcmp(value, "yes") == 0);
1509 # endif
1510  }
1511 #endif
1512 
1513 #ifdef WITH_PROXY
1514  /*
1515  * Proxy sockets don't have clients.
1516  */
1517  if (this->type == RAD_LISTEN_PROXY) return 0;
1518 #endif
1519 
1520  /*
1521  * The more specific configurations are preferred to more
1522  * generic ones.
1523  */
1524  client_cs = NULL;
1525  parentcs = cf_top_section(cs);
1526  rcode = cf_pair_parse(cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, &section_name), NULL, T_INVALID);
1527  if (rcode < 0) return -1; /* bad string */
1528  if (rcode == 0) {
1529  /*
1530  * Explicit list given: use it.
1531  */
1532  client_cs = cf_section_sub_find_name2(parentcs, "clients", section_name);
1533  if (!client_cs) {
1534  client_cs = cf_section_sub_find(main_config.config, section_name);
1535  }
1536  if (!client_cs) {
1537  cf_log_err_cs(cs,
1538  "Failed to find clients %s {...}",
1539  section_name);
1540  return -1;
1541  }
1542  } /* else there was no "clients = " entry. */
1543 
1544  if (!client_cs) {
1545  CONF_SECTION *server_cs;
1546 
1547  server_cs = cf_section_sub_find_name2(parentcs,
1548  "server",
1549  this->server);
1550  /*
1551  * Found a "server foo" section. If there are clients
1552  * in it, use them.
1553  */
1554  if (server_cs &&
1555  (cf_section_sub_find(server_cs, "client") != NULL)) {
1556  client_cs = server_cs;
1557  }
1558  }
1559 
1560  /*
1561  * Still nothing. Look for global clients.
1562  */
1563  if (!client_cs) client_cs = parentcs;
1564 
1565 #ifdef WITH_TLS
1566  sock->clients = client_list_parse_section(client_cs, (this->tls != NULL));
1567 #else
1568  sock->clients = client_list_parse_section(client_cs, false);
1569 #endif
1570  if (!sock->clients) {
1571  cf_log_err_cs(cs,
1572  "Failed to load clients for this listen section");
1573  return -1;
1574  }
1575 
1576 #ifdef WITH_TCP
1577  if (sock->proto == IPPROTO_TCP) {
1578  /*
1579  * Re-write the listener receive function to
1580  * allow us to accept the socket.
1581  */
1582  this->recv = dual_tcp_accept;
1583 
1584  this->children = rbtree_create(this, listener_cmp, NULL, 0);
1585  if (!this->children) {
1586  cf_log_err_cs(cs, "Failed to create child list for TCP socket.");
1587  return -1;
1588  }
1589  }
1590 #endif
1591 
1592  return 0;
1593 }
1594 
1595 
1596 /*
1597  * Open a socket using a previously parsed listener.
1598  */
1600 {
1601  listen_socket_t *sock = this->data;
1602 
1603 #ifdef HAVE_LIBPCAP
1604  /* Only use libpcap if pcap_type has a value. Otherwise, use socket with SO_BINDTODEVICE */
1605  if (sock->interface && sock->pcap_type) {
1606  if (init_pcap(this) < 0) {
1607  cf_log_err_cs(cs,
1608  "Error initializing pcap.");
1609  return -1;
1610  }
1611 
1612  return 0;
1613  }
1614 #endif
1615 
1616  /*
1617  * Bind the socket to an IP / port / interface
1618  */
1619  if (listen_bind(this) < 0) {
1620  char buffer[128];
1621  cf_log_err_cs(cs,
1622  "Error binding to port for %s port %d",
1623  fr_inet_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1624  sock->my_port);
1625  return -1;
1626  }
1627 
1628  return 0;
1629 }
1630 
1631 /*
1632  * Send an authentication response packet
1633  */
1634 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1635 {
1636  rad_assert(request->listener == listener);
1637  rad_assert(listener->send == auth_socket_send);
1638 
1639  if (request->reply->code == 0) return 0;
1640 
1641 #ifdef WITH_UDPFROMTO
1642  /*
1643  * Overwrite the src ip address on the outbound packet
1644  * with the one specified by the client.
1645  * This is useful to work around broken DSR implementations
1646  * and other routing issues.
1647  */
1648  if (request->client->src_ipaddr.af != AF_UNSPEC) {
1649  request->reply->src_ipaddr = request->client->src_ipaddr;
1650  }
1651 #endif
1652 
1653  if (fr_radius_send(request->reply, request->packet,
1654  request->client->secret) < 0) {
1655  RERROR("Failed sending reply: %s",
1656  fr_strerror());
1657  return -1;
1658  }
1659 
1660  return 0;
1661 }
1662 
1663 
1664 #ifdef WITH_ACCOUNTING
1665 /*
1666  * Send an accounting response packet (or not)
1667  */
1668 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1669 {
1670  rad_assert(request->listener == listener);
1671  rad_assert(listener->send == acct_socket_send);
1672 
1673  /*
1674  * Accounting reject's are silently dropped.
1675  *
1676  * We do it here to avoid polluting the rest of the
1677  * code with this knowledge
1678  */
1679  if (request->reply->code == 0) return 0;
1680 
1681 # ifdef WITH_UDPFROMTO
1682  /*
1683  * Overwrite the src ip address on the outbound packet
1684  * with the one specified by the client.
1685  * This is useful to work around broken DSR implementations
1686  * and other routing issues.
1687  */
1688  if (request->client->src_ipaddr.af != AF_UNSPEC) {
1689  request->reply->src_ipaddr = request->client->src_ipaddr;
1690  }
1691 # endif
1692 
1693  if (fr_radius_send(request->reply, request->packet,
1694  request->client->secret) < 0) {
1695  RERROR("Failed sending reply: %s",
1696  fr_strerror());
1697  return -1;
1698  }
1699 
1700  return 0;
1701 }
1702 #endif
1703 
1704 #ifdef WITH_PROXY
1705 /*
1706  * Send a packet to a home server.
1707  *
1708  * FIXME: have different code for proxy auth & acct!
1709  */
1710 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1711 {
1712  rad_assert(request->proxy_listener == listener);
1713  rad_assert(listener->send == proxy_socket_send);
1714 
1715  if (fr_radius_send(request->proxy, NULL,
1716  request->home_server->secret) < 0) {
1717  RERROR("Failed sending proxied request: %s",
1718  fr_strerror());
1719  return -1;
1720  }
1721 
1722  return 0;
1723 }
1724 #endif
1725 
1726 #ifdef WITH_STATS
1727 /*
1728  * Check if an incoming request is "ok"
1729  *
1730  * It takes packets, not requests. It sees if the packet looks
1731  * OK. If so, it does a number of sanity checks on it.
1732  */
1733 static int stats_socket_recv(rad_listen_t *listener)
1734 {
1735  ssize_t rcode;
1736  unsigned int code;
1737  uint16_t src_port;
1738  RADIUS_PACKET *packet;
1739  RADCLIENT *client = NULL;
1740  fr_ipaddr_t src_ipaddr;
1741 
1742  rcode = fr_radius_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1743  if (rcode < 0) return 0;
1744 
1745  FR_STATS_INC(auth, total_requests);
1746 
1747  if (rcode < 20) { /* RADIUS_HDR_LEN */
1748  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1749  FR_STATS_INC(auth, total_malformed_requests);
1750  return 0;
1751  }
1752 
1753  client = client_listener_find(listener, &src_ipaddr, src_port);
1754  if (!client) {
1755  udp_recv_discard(listener->fd);
1756  FR_STATS_INC(auth, total_invalid_requests);
1757  return 0;
1758  }
1759 
1761 
1762  /*
1763  * We only understand Status-Server on this socket.
1764  */
1765  if (code != PW_CODE_STATUS_SERVER) {
1766  DEBUG("Ignoring packet code %d sent to Status-Server port",
1767  code);
1768  udp_recv_discard(listener->fd);
1769  FR_STATS_INC(auth, total_unknown_types);
1770  return 0;
1771  }
1772 
1773  /*
1774  * Now that we've sanity checked everything, receive the
1775  * packet.
1776  */
1777  packet = fr_radius_recv(NULL, listener->fd, 1); /* require message authenticator */
1778  if (!packet) {
1779  FR_STATS_INC(auth, total_malformed_requests);
1780  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1781  return 0;
1782  }
1783 
1784  if (!request_receive(NULL, listener, packet, client, rad_status_server)) {
1785  FR_STATS_INC(auth, total_packets_dropped);
1786  fr_radius_free(&packet);
1787  return 0;
1788  }
1789 
1790  return 1;
1791 }
1792 #endif
1793 
1794 
1795 /*
1796  * Check if an incoming request is "ok"
1797  *
1798  * It takes packets, not requests. It sees if the packet looks
1799  * OK. If so, it does a number of sanity checks on it.
1800  */
1801 static int auth_socket_recv(rad_listen_t *listener)
1802 {
1803  ssize_t rcode;
1804  unsigned int code;
1805  uint16_t src_port;
1806  RADIUS_PACKET *packet;
1807  RAD_REQUEST_FUNP fun = NULL;
1808  RADCLIENT *client = NULL;
1809  fr_ipaddr_t src_ipaddr;
1810  TALLOC_CTX *ctx;
1811 
1812  rcode = fr_radius_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1813  if (rcode < 0) return 0;
1814 
1815  FR_STATS_INC(auth, total_requests);
1816 
1817  if (rcode < 20) { /* RADIUS_HDR_LEN */
1818  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1819  FR_STATS_INC(auth, total_malformed_requests);
1820  return 0;
1821  }
1822 
1823  client = client_listener_find(listener, &src_ipaddr, src_port);
1824  if (!client) {
1825  udp_recv_discard(listener->fd);
1826  FR_STATS_INC(auth, total_invalid_requests);
1827  return 0;
1828  }
1829 
1831 
1832  /*
1833  * Some sanity checks, based on the packet code.
1834  */
1835  switch (code) {
1837  fun = rad_authenticate;
1838  break;
1839 
1840  case PW_CODE_STATUS_SERVER:
1841  if (!main_config.status_server) {
1842  udp_recv_discard(listener->fd);
1843  FR_STATS_INC(auth, total_unknown_types);
1844  WARN("Ignoring Status-Server request due to security configuration");
1845  return 0;
1846  }
1847  fun = rad_status_server;
1848  break;
1849 
1850  default:
1851  udp_recv_discard(listener->fd);
1852  FR_STATS_INC(auth, total_unknown_types);
1853 
1854  if (DEBUG_ENABLED) ERROR("Receive - Invalid packet code %d sent to authentication port from "
1855  "client %s port %d", code, client->shortname, src_port);
1856  return 0;
1857  } /* switch over packet types */
1858 
1859  ctx = talloc_pool(NULL, main_config.talloc_pool_size);
1860  if (!ctx) {
1861  udp_recv_discard(listener->fd);
1862  FR_STATS_INC(auth, total_packets_dropped);
1863  return 0;
1864  }
1865  talloc_set_name_const(ctx, "auth_listener_pool");
1866 
1867  /*
1868  * Now that we've sanity checked everything, receive the
1869  * packet.
1870  */
1871  packet = fr_radius_recv(ctx, listener->fd, client->message_authenticator);
1872  if (!packet) {
1873  FR_STATS_INC(auth, total_malformed_requests);
1874  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1875  talloc_free(ctx);
1876  return 0;
1877  }
1878 
1879 #if defined(__APPLE__) && defined(WITH_UDPFROMTO)
1880  /*
1881  * This is a NICE Mac OSX bug. Create an interface with
1882  * two IP address, and then configure one listener for
1883  * each IP address. Send thousands of packets to one
1884  * address, and some will show up on the OTHER socket.
1885  *
1886  * This hack works ONLY if the clients are global. If
1887  * each listener has the same client IP, but with
1888  * different secrets, then it will fail the fr_radius_recv()
1889  * check above, and there's nothing you can do.
1890  */
1891  {
1892  listen_socket_t *sock = listener->data;
1893  rad_listen_t *other;
1894 
1895  other = listener_find_byipaddr(&packet->dst_ipaddr,
1896  packet->dst_port, sock->proto);
1897  if (other) listener = other;
1898  }
1899 #endif
1900 
1901  if (!request_receive(ctx, listener, packet, client, fun)) {
1902  FR_STATS_INC(auth, total_packets_dropped);
1903  talloc_free(ctx);
1904  return 0;
1905  }
1906 
1907  return 1;
1908 }
1909 
1910 
1911 #ifdef WITH_ACCOUNTING
1912 /*
1913  * Receive packets from an accounting socket
1914  */
1915 static int acct_socket_recv(rad_listen_t *listener)
1916 {
1917  ssize_t rcode;
1918  unsigned int code;
1919  uint16_t src_port;
1920  RADIUS_PACKET *packet;
1921  RAD_REQUEST_FUNP fun = NULL;
1922  RADCLIENT *client = NULL;
1923  fr_ipaddr_t src_ipaddr;
1924  TALLOC_CTX *ctx;
1925 
1926  rcode = fr_radius_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1927  if (rcode < 0) return 0;
1928 
1929  FR_STATS_INC(acct, total_requests);
1930 
1931  if (rcode < 20) { /* RADIUS_HDR_LEN */
1932  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1933  FR_STATS_INC(acct, total_malformed_requests);
1934  return 0;
1935  }
1936 
1937  if ((client = client_listener_find(listener,
1938  &src_ipaddr, src_port)) == NULL) {
1939  udp_recv_discard(listener->fd);
1940  FR_STATS_INC(acct, total_invalid_requests);
1941  return 0;
1942  }
1943 
1945 
1946  /*
1947  * Some sanity checks, based on the packet code.
1948  */
1949  switch (code) {
1951  fun = rad_accounting;
1952  break;
1953 
1954  case PW_CODE_STATUS_SERVER:
1955  if (!main_config.status_server) {
1956  udp_recv_discard(listener->fd);
1957  FR_STATS_INC(acct, total_unknown_types);
1958 
1959  WARN("Ignoring Status-Server request due to security configuration");
1960  return 0;
1961  }
1962  fun = rad_status_server;
1963  break;
1964 
1965  default:
1966  udp_recv_discard(listener->fd);
1967  FR_STATS_INC(acct, total_unknown_types);
1968 
1969  DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1970  code, client->shortname, src_port);
1971  return 0;
1972  } /* switch over packet types */
1973 
1974  ctx = talloc_pool(NULL, main_config.talloc_pool_size);
1975  if (!ctx) {
1976  udp_recv_discard(listener->fd);
1977  FR_STATS_INC(acct, total_packets_dropped);
1978  return 0;
1979  }
1980  talloc_set_name_const(ctx, "acct_listener_pool");
1981 
1982  /*
1983  * Now that we've sanity checked everything, receive the
1984  * packet.
1985  */
1986  packet = fr_radius_recv(ctx, listener->fd, 0);
1987  if (!packet) {
1988  FR_STATS_INC(acct, total_malformed_requests);
1989  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
1990  talloc_free(ctx);
1991  return 0;
1992  }
1993 
1994  /*
1995  * There can be no duplicate accounting packets.
1996  */
1997  if (!request_receive(ctx, listener, packet, client, fun)) {
1998  FR_STATS_INC(acct, total_packets_dropped);
1999  fr_radius_free(&packet);
2000  talloc_free(ctx);
2001  return 0;
2002  }
2003 
2004  return 1;
2005 }
2006 #endif
2007 
2008 
2009 #ifdef WITH_COA
2010 static int do_proxy(REQUEST *request)
2011 {
2012  VALUE_PAIR *vp;
2013 
2014  if (request->in_proxy_hash ||
2015  (request->proxy_reply && (request->proxy_reply->code != 0))) {
2016  return 0;
2017  }
2018 
2019  vp = fr_pair_find_by_num(request->config, 0, PW_HOME_SERVER_POOL, TAG_ANY);
2020 
2021  if (vp) {
2022  if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
2023  REDEBUG2("Cannot proxy to unknown pool %s",
2024  vp->vp_strvalue);
2025  return -1;
2026  }
2027 
2028  return 1;
2029  }
2030 
2031  /*
2032  * We have a destination IP address. It will (later) proxied.
2033  */
2034  vp = fr_pair_find_by_num(request->config, 0, PW_PACKET_DST_IP_ADDRESS, TAG_ANY);
2035  if (!vp) vp = fr_pair_find_by_num(request->config, 0, PW_PACKET_DST_IPV6_ADDRESS, TAG_ANY);
2036 
2037  if (!vp) return 0;
2038 
2039  return 1;
2040 }
2041 
2042 /*
2043  * Receive a CoA packet.
2044  */
2045 int rad_coa_recv(REQUEST *request)
2046 {
2047  int rcode = RLM_MODULE_OK;
2048  int ack, nak;
2049  int proxy_status;
2050  VALUE_PAIR *vp;
2051 
2052  /*
2053  * Get the correct response
2054  */
2055  switch (request->packet->code) {
2056  case PW_CODE_COA_REQUEST:
2057  ack = PW_CODE_COA_ACK;
2058  nak = PW_CODE_COA_NAK;
2059  break;
2060 
2062  ack = PW_CODE_DISCONNECT_ACK;
2063  nak = PW_CODE_DISCONNECT_NAK;
2064  break;
2065 
2066  default: /* shouldn't happen */
2067  return RLM_MODULE_FAIL;
2068  }
2069 
2070 # ifdef WITH_PROXY
2071 # define WAS_PROXIED (request->proxy)
2072 # else
2073 # define WAS_PROXIED (0)
2074 # endif
2075 
2076  if (!WAS_PROXIED) {
2077  /*
2078  * RFC 5176 Section 3.3. If we have a CoA-Request
2079  * with Service-Type = Authorize-Only, it MUST
2080  * have a State attribute in it.
2081  */
2082  vp = fr_pair_find_by_num(request->packet->vps, 0, PW_SERVICE_TYPE, TAG_ANY);
2083  if (request->packet->code == PW_CODE_COA_REQUEST) {
2084  if (vp && (vp->vp_integer == PW_AUTHORIZE_ONLY)) {
2085  vp = fr_pair_find_by_num(request->packet->vps, 0, PW_STATE, TAG_ANY);
2086  if (!vp || (vp->vp_length == 0)) {
2087  REDEBUG("CoA-Request with Service-Type = Authorize-Only MUST "
2088  "contain a State attribute");
2089  request->reply->code = PW_CODE_COA_NAK;
2090  return RLM_MODULE_FAIL;
2091  }
2092  }
2093  } else if (vp) {
2094  /*
2095  * RFC 5176, Section 3.2.
2096  */
2097  REDEBUG("Disconnect-Request MUST NOT contain a Service-Type attribute");
2098  request->reply->code = PW_CODE_DISCONNECT_NAK;
2099  return RLM_MODULE_FAIL;
2100  }
2101 
2102  rcode = process_recv_coa(0, request);
2103  switch (rcode) {
2104  case RLM_MODULE_FAIL:
2105  case RLM_MODULE_INVALID:
2106  case RLM_MODULE_REJECT:
2107  case RLM_MODULE_USERLOCK:
2108  default:
2109  request->reply->code = nak;
2110  break;
2111 
2112  case RLM_MODULE_HANDLED:
2113  return rcode;
2114 
2115  case RLM_MODULE_NOOP:
2116  case RLM_MODULE_NOTFOUND:
2117  case RLM_MODULE_OK:
2118  case RLM_MODULE_UPDATED:
2119  proxy_status = do_proxy(request);
2120  if (proxy_status == 1) return RLM_MODULE_OK;
2121 
2122  if (proxy_status < 0) {
2123  request->reply->code = nak;
2124  } else {
2125  request->reply->code = ack;
2126  }
2127  break;
2128  }
2129 
2130  }
2131 
2132 # ifdef WITH_PROXY
2133  else if (request->proxy_reply) {
2134  /*
2135  * Start the reply code with the proxy reply
2136  * code.
2137  */
2138  request->reply->code = request->proxy_reply->code;
2139  }
2140 # endif
2141 
2142  /*
2143  * Copy State from the request to the reply.
2144  * See RFC 5176 Section 3.3.
2145  */
2146  vp = fr_pair_list_copy_by_num(request->reply, request->packet->vps, 0, PW_STATE, TAG_ANY);
2147  if (vp) fr_pair_add(&request->reply->vps, vp);
2148 
2149  /*
2150  * We may want to over-ride the reply.
2151  */
2152  if (request->reply->code) {
2153  rcode = process_send_coa(0, request);
2154  switch (rcode) {
2155  /*
2156  * We need to send CoA-NAK back if Service-Type
2157  * is Authorize-Only. Rely on the user's policy
2158  * to do that. We're not a real NAS, so this
2159  * restriction doesn't (ahem) apply to us.
2160  */
2161  case RLM_MODULE_FAIL:
2162  case RLM_MODULE_INVALID:
2163  case RLM_MODULE_REJECT:
2164  case RLM_MODULE_USERLOCK:
2165  default:
2166  /*
2167  * Over-ride an ACK with a NAK
2168  */
2169  request->reply->code = nak;
2170  break;
2171 
2172  case RLM_MODULE_HANDLED:
2173  return rcode;
2174 
2175  case RLM_MODULE_NOOP:
2176  case RLM_MODULE_NOTFOUND:
2177  case RLM_MODULE_OK:
2178  case RLM_MODULE_UPDATED:
2179  /*
2180  * Do NOT over-ride a previously set value.
2181  * Otherwise an "ok" here will re-write a
2182  * NAK to an ACK.
2183  */
2184  if (request->reply->code == 0) {
2185  request->reply->code = ack;
2186  }
2187  break;
2188  }
2189  }
2190 
2191  return RLM_MODULE_OK;
2192 }
2193 
2194 
2195 /*
2196  * Check if an incoming request is "ok"
2197  *
2198  * It takes packets, not requests. It sees if the packet looks
2199  * OK. If so, it does a number of sanity checks on it.
2200  */
2201 static int coa_socket_recv(rad_listen_t *listener)
2202 {
2203  ssize_t rcode;
2204  unsigned int code;
2205  uint16_t src_port;
2206  RADIUS_PACKET *packet;
2207  RAD_REQUEST_FUNP fun = NULL;
2208  RADCLIENT *client = NULL;
2209  fr_ipaddr_t src_ipaddr;
2210  TALLOC_CTX *ctx;
2211 
2212  rcode = fr_radius_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
2213  if (rcode < 0) return 0;
2214 
2215  if (rcode < 20) { /* RADIUS_HDR_LEN */
2216  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
2217  FR_STATS_INC(coa, total_malformed_requests);
2218  return 0;
2219  }
2220 
2221  if ((client = client_listener_find(listener,
2222  &src_ipaddr, src_port)) == NULL) {
2223  udp_recv_discard(listener->fd);
2224  FR_STATS_INC(coa, total_requests);
2225  FR_STATS_INC(coa, total_invalid_requests);
2226  return 0;
2227  }
2228 
2229  /*
2230  * Some sanity checks, based on the packet code.
2231  */
2232  switch (code) {
2233  case PW_CODE_COA_REQUEST:
2234  FR_STATS_INC(coa, total_requests);
2235  fun = rad_coa_recv;
2236  break;
2237 
2239  FR_STATS_INC(dsc, total_requests);
2240  fun = rad_coa_recv;
2241  break;
2242 
2243  default:
2244  udp_recv_discard(listener->fd);
2245  FR_STATS_INC(coa, total_unknown_types);
2246  DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
2247  code, client->shortname, src_port);
2248  return 0;
2249  } /* switch over packet types */
2250 
2251  ctx = talloc_pool(NULL, main_config.talloc_pool_size);
2252  if (!ctx) {
2253  udp_recv_discard(listener->fd);
2254  FR_STATS_INC(coa, total_packets_dropped);
2255  return 0;
2256  }
2257  talloc_set_name_const(ctx, "coa_socket_recv_pool");
2258 
2259  /*
2260  * Now that we've sanity checked everything, receive the
2261  * packet.
2262  */
2263  packet = fr_radius_recv(ctx, listener->fd, client->message_authenticator);
2264  if (!packet) {
2265  FR_STATS_INC(coa, total_malformed_requests);
2266  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
2267  talloc_free(ctx);
2268  return 0;
2269  }
2270 
2271  if (!request_receive(ctx, listener, packet, client, fun)) {
2272  FR_STATS_INC(coa, total_packets_dropped);
2273  fr_radius_free(&packet);
2274  talloc_free(ctx);
2275  return 0;
2276  }
2277 
2278  return 1;
2279 }
2280 #endif
2281 
2282 #ifdef WITH_PROXY
2283 /*
2284  * Recieve packets from a proxy socket.
2285  */
2286 static int proxy_socket_recv(rad_listen_t *listener)
2287 {
2288  RADIUS_PACKET *packet;
2289 # ifdef WITH_TCP
2290  listen_socket_t *sock;
2291 # endif
2292  char buffer[128];
2293 
2294  packet = fr_radius_recv(NULL, listener->fd, 0);
2295  if (!packet) {
2296  if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
2297  return 0;
2298  }
2299 
2300  switch (packet->code) {
2301  case PW_CODE_ACCESS_ACCEPT:
2303  case PW_CODE_ACCESS_REJECT:
2304  break;
2305 
2306 # ifdef WITH_ACCOUNTING
2308  break;
2309 # endif
2310 
2311 # ifdef WITH_COA
2314  case PW_CODE_COA_ACK:
2315  case PW_CODE_COA_NAK:
2316  break;
2317 # endif
2318 
2319  default:
2320  /*
2321  * FIXME: Update MIB for packet types?
2322  */
2323  ERROR("Invalid packet code %d sent to a proxy port from home server %s port %d - ID %d : IGNORED",
2324  packet->code,
2325  fr_inet_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
2326  packet->src_port, packet->id);
2327 # ifdef WITH_STATS
2328  listener->stats.total_unknown_types++;
2329 # endif
2330  fr_radius_free(&packet);
2331  return 0;
2332  }
2333 
2334 # ifdef WITH_TCP
2335  sock = listener->data;
2336  packet->proto = sock->proto;
2337 # endif
2338 
2339  if (!request_proxy_reply(packet)) {
2340 # ifdef WITH_STATS
2341  listener->stats.total_packets_dropped++;
2342 # endif
2343  fr_radius_free(&packet);
2344  return 0;
2345  }
2346 
2347  return 1;
2348 }
2349 
2350 # ifdef WITH_TCP
2351 /*
2352  * Recieve packets from a proxy socket.
2353  */
2355 {
2356  RADIUS_PACKET *packet;
2357  listen_socket_t *sock = listener->data;
2358  char buffer[128];
2359 
2360  if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;
2361 
2362  packet = fr_tcp_recv(listener->fd, 0);
2363  if (!packet) {
2364  listener->status = RAD_LISTEN_STATUS_EOL;
2365  radius_update_listener(listener);
2366  return 0;
2367  }
2368 
2369  /*
2370  * FIXME: Client MIB updates?
2371  */
2372  switch (packet->code) {
2373  case PW_CODE_ACCESS_ACCEPT:
2375  case PW_CODE_ACCESS_REJECT:
2376  break;
2377 
2378 # ifdef WITH_ACCOUNTING
2380  break;
2381 # endif
2382 
2383  default:
2384  /*
2385  * FIXME: Update MIB for packet types?
2386  */
2387  ERROR("Invalid packet code %d sent to a proxy port "
2388  "from home server %s port %d - ID %d : IGNORED",
2389  packet->code,
2390  fr_inet_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
2391  packet->src_port, packet->id);
2392  fr_radius_free(&packet);
2393  return 0;
2394  }
2395 
2396  packet->src_ipaddr = sock->other_ipaddr;
2397  packet->src_port = sock->other_port;
2398  packet->dst_ipaddr = sock->my_ipaddr;
2399  packet->dst_port = sock->my_port;
2400 
2401  /*
2402  * FIXME: Have it return an indication of packets that
2403  * are OK to ignore (dups, too late), versus ones that
2404  * aren't OK to ignore (unknown response, spoofed, etc.)
2405  *
2406  * Close the socket on bad packets...
2407  */
2408  if (!request_proxy_reply(packet)) {
2409  fr_radius_free(&packet);
2410  return 0;
2411  }
2412 
2413  sock->opened = sock->last_packet = time(NULL);
2414 
2415  return 1;
2416 }
2417 # endif
2418 #endif
2419 
2420 
2421 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
2422 {
2423  if (!request->reply->code) return 0;
2424 
2425  if (fr_radius_encode(request->reply, request->packet, request->client->secret) < 0) {
2426  RERROR("Failed encoding packet: %s", fr_strerror());
2427 
2428  return -1;
2429  }
2430 
2431  if (fr_radius_sign(request->reply, request->packet, request->client->secret) < 0) {
2432  RERROR("Failed signing packet: %s", fr_strerror());
2433 
2434  return -1;
2435  }
2436 
2437  return 0;
2438 }
2439 
2440 
2441 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
2442 {
2443 #ifdef WITH_TLS
2444  listen_socket_t *sock;
2445 #endif
2446 
2447  if (fr_radius_verify(request->packet, NULL,
2448  request->client->secret) < 0) {
2449  return -1;
2450  }
2451 
2452 #ifdef WITH_TLS
2453  sock = request->listener->data;
2454  rad_assert(sock != NULL);
2455 
2456  /*
2457  * FIXME: Add the rest of the TLS parameters, too? But
2458  * how do we separate EAP-TLS parameters from RADIUS/TLS
2459  * parameters?
2460  */
2461  if (sock->tls_session && sock->tls_session->ssl) {
2462 # ifdef PSK_MAX_IDENTITY_LEN
2463  const char *identity = SSL_get_psk_identity(sock->tls_session->ssl);
2464  if (identity) {
2465  RDEBUG("Retrieved psk identity: %s", identity);
2466  pair_make_request("TLS-PSK-Identity", identity, T_OP_SET);
2467  }
2468 # endif
2469  }
2470 #endif
2471 
2472  return fr_radius_decode(request->packet, NULL,
2473  request->client->secret);
2474 }
2475 
2476 #ifdef WITH_PROXY
2477 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
2478 {
2479  if (fr_radius_encode(request->proxy, NULL, request->home_server->secret) < 0) {
2480  RERROR("Failed encoding proxied packet: %s", fr_strerror());
2481 
2482  return -1;
2483  }
2484 
2485  if (fr_radius_sign(request->proxy, NULL, request->home_server->secret) < 0) {
2486  RERROR("Failed signing proxied packet: %s", fr_strerror());
2487 
2488  return -1;
2489  }
2490 
2491  return 0;
2492 }
2493 
2494 
2495 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
2496 {
2497  /*
2498  * fr_radius_verify is run in event.c, received_proxy_response()
2499  */
2500 
2501  return fr_radius_decode(request->proxy_reply, request->proxy,
2502  request->home_server->secret);
2503 }
2504 #endif
2505 
2506 #include "command.c"
2507 
2508 #define NO_LISTENER { .name = "undefined", }
2509 
2510 /*
2511  * Handle up to 256 different protocols.
2512  */
2513 static fr_protocol_t master_listen[] = {
2514 #ifdef WITH_STATS
2515  { RLM_MODULE_INIT, "status", sizeof(listen_socket_t), NULL,
2516  TRANSPORT_DUAL, true, NULL,
2520 #else
2521  NO_LISTENER,
2522 #endif
2523 
2524 #ifdef WITH_PROXY
2525  /* proxying */
2526  { RLM_MODULE_INIT, "proxy", sizeof(listen_socket_t), NULL,
2531 #else
2532  NO_LISTENER,
2533 #endif
2534 
2535  /* authentication */
2536  { RLM_MODULE_INIT, "auth", sizeof(listen_socket_t), NULL,
2541 
2542 #ifdef WITH_ACCOUNTING
2543  /* accounting */
2544  { RLM_MODULE_INIT, "acct", sizeof(listen_socket_t), NULL,
2549 #else
2550  NO_LISTENER,
2551 #endif
2552 
2553 #ifdef WITH_DETAIL
2554  /* detail */
2555  { RLM_MODULE_INIT, "detail", sizeof(listen_detail_t), NULL,
2556  0, false, NULL,
2560 #else
2561  NO_LISTENER,
2562 #endif
2563 
2564  NO_LISTENER, /* vmps */
2565 
2566  NO_LISTENER, /* dhcp */
2567 
2568 #ifdef WITH_COMMAND_SOCKET
2569  /* TCP command socket */
2570  { RLM_MODULE_INIT, "control", sizeof(fr_command_socket_t), NULL,
2571  0, false, NULL,
2575 #else
2576  NO_LISTENER,
2577 #endif
2578 
2579 #ifdef WITH_COA
2580  /* Change of Authorization */
2581  { RLM_MODULE_INIT, "coa", sizeof(listen_socket_t), NULL,
2584  coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
2586 #else
2587  NO_LISTENER,
2588 #endif
2589 
2590  NO_LISTENER /* bfd */
2591 };
2592 
2593 
2594 #ifdef HAVE_LIBPCAP
2595 /** Initialize PCAP library based on listen section
2596  *
2597  * @param this listen section
2598  * @return
2599  * - 0 if successful
2600  * - -1 if failed
2601  */
2602 static int init_pcap(rad_listen_t *this)
2603 {
2604  listen_socket_t *sock = this->data;
2605  char const * pcap_filter;
2606 
2607  sock->pcap = fr_pcap_init(this, sock->interface, sock->pcap_type);
2608 
2609  if (!sock->pcap) {
2610  ERROR("Failed creating pcap for interface %s", sock->interface);
2611  return -1;
2612  }
2613 
2614  if (check_config) return 0;
2615 
2616  rad_suid_up();
2617  if (fr_pcap_open(sock->pcap) < 0) {
2618  ERROR("Failed opening interface %s: %s", sock->interface, fr_strerror());
2619  return -1;
2620  }
2621  rad_suid_down();
2622 
2623  pcap_filter = sock->pcap_filter_builder(this);
2624 
2625  if (!pcap_filter) {
2626  ERROR("Failed building filter for interface %s: %s",
2627  sock->interface, fr_strerror());
2628  return -1;
2629  }
2630 
2631  if (fr_pcap_apply_filter(sock->pcap, pcap_filter) < 0) {
2632  ERROR("Failed setting filter for interface %s: %s",
2633  sock->interface, fr_strerror());
2634  return -1;
2635  } else {
2636  DEBUG("Using PCAP filter '%s'", pcap_filter);
2637  }
2638 
2639  this->fd = sock->pcap->fd;
2640 
2641  return 0;
2642 }
2643 #endif
2644 
2645 
2646 /*
2647  * Binds a listener to a socket.
2648  */
2649 static int listen_bind(rad_listen_t *this)
2650 {
2651  int rcode, port;
2652  listen_socket_t *sock = this->data;
2653  char const *port_name = NULL;
2654  bool async = true;
2655 
2656  /*
2657  * If the configuration didn't specify a port, get one
2658  * from /etc/services.
2659  */
2660  if (sock->my_port == 0) {
2661  switch (this->type) {
2662  case RAD_LISTEN_AUTH:
2663  port_name = "radius";
2664  break;
2665 
2666 #ifdef WITH_ACCOUNTING
2667  case RAD_LISTEN_ACCT:
2668  port_name = "radius-acct";
2669  break;
2670 #endif
2671 
2672 #ifdef WITH_PROXY
2673  case RAD_LISTEN_PROXY:
2674  /* leave it at zero */
2675  break;
2676 #endif
2677 
2678 #ifdef WITH_VMPS
2679  case RAD_LISTEN_VQP:
2680  sock->my_port = 1589;
2681  break;
2682 #endif
2683 
2684 #ifdef WITH_COMMAND_SOCKET
2685  case RAD_LISTEN_COMMAND:
2686  sock->my_port = PW_RADMIN_PORT;
2687  break;
2688 #endif
2689 
2690 #ifdef WITH_COA
2691  case RAD_LISTEN_COA:
2692  port_name = "radius-dynauth";
2693  break;
2694 #endif
2695 
2696 #ifdef WITH_DHCP
2697  case RAD_LISTEN_DHCP:
2698  port_name = "bootps";
2699  break;
2700 #endif
2701 
2702  default:
2703  WARN("Internal sanity check failed in binding to socket. Ignoring problem");
2704  return -1;
2705  }
2706  }
2707 
2708 #ifdef WITH_TCP
2709 #ifdef WITH_PROXY
2710  /*
2711  * You CANNOT specify a source port for outbound proxy sockets
2712  * over TCP.
2713  */
2714  if (sock->my_port &&
2715  (sock->proto == IPPROTO_TCP) &&
2716  (this->type == RAD_LISTEN_PROXY)) {
2717  cf_log_err_cs(this->cs, "You must not specify a port for proxy sockets over TCP");
2718  return -1;
2719  }
2720 #endif
2721 #endif
2722 
2723  /*
2724  * Don't open sockets if we're checking the config.
2725  */
2726  if (check_config) {
2727  this->fd = -1;
2728  return 0;
2729  }
2730 
2731  rad_assert(sock->my_ipaddr.af);
2732 
2733 #ifdef WITH_TCP
2734  /*
2735  * Check if we're async or not.
2736  */
2737  if (sock->proto == IPPROTO_TCP) {
2738  /*
2739  * If there are hard-coded worker threads, OR
2740  * it's a TLS connection, it's blocking.
2741  *
2742  * Otherwise, they're non-blocking.
2743  */
2744  if (this->workers
2745 # if defined(WITH_PROXY) && defined(WITH_TLS)
2746  || ((this->type == RAD_LISTEN_PROXY) && this->tls)
2747 # endif
2748  ) {
2749  async = false;
2750  }
2751  }
2752 #endif
2753 
2754  DEBUG4("[FD XX] Opening socket -- socket(%s, %s, 0)",
2755  fr_int2str(fr_net_af_table, sock->my_ipaddr.af, "<UNKNOWN>"),
2756  fr_int2str(fr_net_ip_proto_table, sock->proto, "<UNKNOWN>"));
2757 
2758  /*
2759  * Open the socket and set a whack of flags.
2760  */
2761  port = sock->my_port;
2762  this->fd = fr_socket_server_base(sock->proto, &sock->my_ipaddr, &port, port_name, async);
2763  if (this->fd < 0) {
2764  char buffer[256];
2765 
2766  this->print(this, buffer, sizeof(buffer));
2767 
2768  ERROR("Failed opening %s: %s", buffer, fr_syserror(errno));
2769  return -1;
2770  }
2771  if (!sock->my_port) sock->my_port = port;
2772 
2773  /*
2774  * Set the receive buffer size
2775  */
2776  if (sock->recv_buff) {
2777  DEBUG4("[FD %i] Setting recv_buff -- setsockopt(%i, SOL_SOCKET, SO_RCVBUF, %i, %zu)", this->fd,
2778  this->fd, sock->recv_buff, sizeof(int));
2779  if (setsockopt(this->fd, SOL_SOCKET, SO_RCVBUF, (int *)&sock->recv_buff, sizeof(int)) < 0) {
2780  close(this->fd);
2781  ERROR("Failed setting receive buffer size: %s", fr_syserror(errno));
2782  return -1;
2783  }
2784  }
2785 
2786  /*
2787  * Bind to the interface, IP address, and port.
2788  */
2789  port = sock->my_port;
2790  rad_suid_up();
2791  rcode = fr_socket_server_bind(this->fd, &sock->my_ipaddr, &port, sock->interface);
2792  rad_suid_down();
2793  sock->my_port = port;
2794 
2795  if (rcode < 0) {
2796  char buffer[256];
2797 
2798  close(this->fd);
2799  this->print(this, buffer, sizeof(buffer));
2800  ERROR("Failed binding to %s: %s", buffer, fr_syserror(errno));
2801  return -1;
2802  }
2803 
2804 #ifdef WITH_TCP
2805  /*
2806  * Allow a backlog of 8 listeners, but only for incoming interfaces.
2807  */
2808  if ((sock->proto == IPPROTO_TCP)
2809 # ifdef WITH_PROXY
2810  && (this->type != RAD_LISTEN_PROXY)
2811 # endif
2812  ) {
2813  DEBUG4("[FD %i] Listening -- listen(%i, 8)", this->fd, this->fd);
2814  if (listen(this->fd, 8) < 0) {
2815  close(this->fd);
2816  ERROR("Failed in listen(): %s", fr_syserror(errno));
2817  return -1;
2818  }
2819  }
2820 #endif
2821 
2822  /*
2823  * Mostly for proxy sockets.
2824  */
2825  sock->other_ipaddr.af = sock->my_ipaddr.af;
2826 
2827  return 0;
2828 }
2829 
2830 
2831 static int _listener_free(rad_listen_t *this)
2832 {
2833  /*
2834  * Other code may have eaten the FD.
2835  */
2836  if (this->fd >= 0) close(this->fd);
2837 
2838  if (this->proto->free) {
2839  this->proto->free(this);
2840  }
2841 
2842 #ifdef WITH_TCP
2843  if ((this->type == RAD_LISTEN_AUTH)
2844 #ifdef WITH_ACCT
2845  || (this->type == RAD_LISTEN_ACCT)
2846 #endif
2847 #ifdef WITH_PROXY
2848  || (this->type == RAD_LISTEN_PROXY)
2849 #endif
2850 #ifdef WITH_COMMAND_SOCKET
2851  || ((this->type == RAD_LISTEN_COMMAND) &&
2852  (((fr_command_socket_t *) this->data)->magic != COMMAND_SOCKET_MAGIC))
2853 #endif
2854  ) {
2855  listen_socket_t *sock = this->data;
2856 
2857  rad_assert(talloc_parent(sock) == this);
2858  rad_assert(sock->ev == NULL);
2859 
2860  /*
2861  * Remove the child from the parent tree.
2862  */
2863  if (this->parent) {
2864  rbtree_deletebydata(this->parent->children, this);
2865  }
2866 
2867  /*
2868  * Delete / close all of the children, too!
2869  */
2870  if (this->children) {
2871  rbtree_walk(this->children, RBTREE_DELETE_ORDER, listener_unlink, this);
2872  }
2873 
2874 #ifdef WITH_TLS
2875  /*
2876  * Note that we do NOT free this->tls, as the
2877  * pointer is parented by its CONF_SECTION. It
2878  * may be used by multiple listeners.
2879  */
2880  if (this->tls) {
2881  rad_assert(!sock->tls_session || (talloc_parent(sock->tls_session) == sock));
2882  rad_assert(!sock->request || (talloc_parent(sock->request) == sock));
2883 #ifdef HAVE_PTHREAD_H
2884  pthread_mutex_destroy(&(sock->mutex));
2885 #endif
2886  }
2887 #endif /* WITH_TLS */
2888  }
2889 #endif /* WITH_TCP */
2890 
2891  return 0;
2892 }
2893 
2894 
2895 /*
2896  * Allocate & initialize a new listener.
2897  */
2899 {
2900  rad_listen_t *this;
2901 
2902  this = talloc_zero(ctx, rad_listen_t);
2903 
2904  this->type = type;
2905  this->proto = proto;
2906  this->recv = proto->recv;
2907  this->send = proto->send;
2908  this->print = proto->print;
2909  this->debug = proto->debug;
2910  this->encode = proto->encode;
2911  this->decode = proto->decode;
2912 
2913  talloc_set_destructor(this, _listener_free);
2914 
2915  this->data = talloc_zero_array(this, uint8_t, proto->inst_size);
2916 
2917  return this;
2918 }
2919 
2920 #ifdef WITH_PROXY
2921 /*
2922  * Externally visible function for creating a new proxy LISTENER.
2923  *
2924  * Not thread-safe, but all calls to it are protected by the
2925  * proxy mutex in event.c
2926  */
2927 rad_listen_t *proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t src_port)
2928 {
2929  time_t now;
2930  rad_listen_t *this;
2931  listen_socket_t *sock;
2932  char buffer[256];
2933 
2934  if (!home) return NULL;
2935 
2936  rad_assert(home->server == NULL); /* we only open real sockets */
2937 
2938  if ((home->limit.max_connections > 0) &&
2939  (home->limit.num_connections >= home->limit.max_connections)) {
2940  RATE_LIMIT(INFO("Home server %s has too many open connections (%d)",
2941  home->log_name, home->limit.max_connections));
2942  return NULL;
2943  }
2944 
2945  now = time(NULL);
2946  if (home->last_failed_open == now) {
2947  WARN("Suppressing attempt to open socket to 'down' home server");
2948  return NULL;
2949  }
2950 
2951  this = listen_alloc(ctx, RAD_LISTEN_PROXY, &master_listen[RAD_LISTEN_PROXY]);
2952 
2953  sock = this->data;
2954  sock->other_ipaddr = home->ipaddr;
2955  sock->other_port = home->port;
2956  sock->home = home;
2957 
2958  sock->my_ipaddr = home->src_ipaddr;
2959  sock->my_port = src_port;
2960  sock->proto = home->proto;
2961 
2962  /*
2963  * For error messages.
2964  */
2965  this->print(this, buffer, sizeof(buffer));
2966 
2967 #ifdef WITH_TCP
2968  sock->opened = sock->last_packet = now;
2969 
2970  if (home->proto == IPPROTO_TCP) {
2971  this->recv = proxy_socket_tcp_recv;
2972 
2973  /*
2974  * FIXME: connect() is blocking!
2975  * We do this with the proxy mutex locked, which may
2976  * cause large delays!
2977  *
2978  * http://www.developerweb.net/forum/showthread.php?p=13486
2979  */
2980  this->fd = fr_socket_client_tcp(&home->src_ipaddr,
2981  &home->ipaddr, home->port, false);
2982  } else
2983 #endif
2984 
2985  this->fd = fr_socket(&home->src_ipaddr, src_port);
2986 
2987  if (this->fd < 0) {
2988  this->print(this, buffer,sizeof(buffer));
2989  ERROR("Failed opening new proxy socket '%s' : %s",
2990  buffer, fr_strerror());
2991  home->last_failed_open = now;
2992  listen_free(&this);
2993  return NULL;
2994  }
2995 
2996 
2997 #if defined(WITH_TCP) && defined(WITH_TLS)
2998  if ((home->proto == IPPROTO_TCP) && home->tls) {
2999  DEBUG("Trying SSL to port %d\n", home->port);
3000  sock->tls_session = tls_session_init_client(sock, home->tls, this->fd);
3001  if (!sock->tls_session) {
3002  ERROR("Failed starting SSL to new proxy socket '%s'", buffer);
3003  home->last_failed_open = now;
3004  listen_free(&this);
3005  return NULL;
3006  }
3007 
3008  this->recv = proxy_tls_recv;
3009  this->send = proxy_tls_send;
3010  }
3011 #endif
3012  /*
3013  * Figure out which port we were bound to.
3014  */
3015  if (sock->my_port == 0) {
3016  struct sockaddr_storage src;
3017  socklen_t sizeof_src = sizeof(src);
3018 
3019  memset(&src, 0, sizeof_src);
3020  if (getsockname(this->fd, (struct sockaddr *) &src, &sizeof_src) < 0) {
3021  ERROR("Failed getting socket name for '%s': %s",
3022  buffer, fr_syserror(errno));
3023  home->last_failed_open = now;
3024  listen_free(&this);
3025  return NULL;
3026  }
3027 
3028  if (!fr_ipaddr_from_sockaddr(&src, sizeof_src,
3029  &sock->my_ipaddr, &sock->my_port)) {
3030  ERROR("Socket has unsupported address family for '%s'", buffer);
3031  home->last_failed_open = now;
3032  listen_free(&this);
3033  return NULL;
3034  }
3035 
3036  this->print(this, buffer, sizeof(buffer));
3037  }
3038 
3039  if (rad_debug_lvl >= 3) {
3040  DEBUG("Opened new proxy socket '%s'", buffer);
3041  }
3042 
3043  home->limit.num_connections++;
3044 
3045  return this;
3046 }
3047 #endif
3048 
3049 /*
3050  * Parse the configuration for a listener.
3051  */
3053 {
3054  int rcode;
3055  char const *listen_type;
3056  rad_listen_t *this;
3057  CONF_SECTION *cs = lc->cs;
3058 
3059  cf_log_info(cs, "listen {");
3060 
3061  listen_type = NULL;
3062  rcode = cf_pair_parse(cs, "type", FR_ITEM_POINTER(PW_TYPE_STRING, &listen_type), "", T_DOUBLE_QUOTED_STRING);
3063  if (rcode < 0) return NULL;
3064 
3065  /*
3066  * Allocate a listener.
3067  */
3068  this = listen_alloc(lc, lc->type, lc->proto);
3069  this->server = lc->server_name;
3070  this->fd = -1;
3071  this->cs = cs;
3072 
3073 #ifdef WITH_TCP
3074  /*
3075  * Special-case '+' for "auth+acct".
3076  */
3077  if (strchr(listen_type, '+') != NULL) {
3078  this->dual = true;
3079  }
3080 #endif
3081 
3082  /*
3083  * Call the per-type parser.
3084  */
3085  if (lc->proto->parse(cs, this) < 0) {
3086  listen_free(&this);
3087  return NULL;
3088  }
3089 
3090  cf_log_info(cs, "}");
3091 
3092  return this;
3093 }
3094 
3095 
3096 #ifdef HAVE_PTHREAD_H
3097 /*
3098  * A child thread which does NOTHING other than read and process
3099  * packets.
3100  */
3101 static void *recv_thread(void *arg)
3102 {
3103  rad_listen_t *this = arg;
3104 
3105  while (1) {
3106  this->recv(this);
3107  DEBUG("%p", &this);
3108  }
3109 
3110  return NULL;
3111 }
3112 #endif
3113 
3114 
3115 /** Search for listeners in the server
3116  *
3117  * @param[out] head Where to write listener. Must point to a NULL pointer.
3118  * @param[in] spawn_workers Whether we're spawning child threads.
3119  * @return
3120  * - 0 on success.
3121  * - -1 on failure.
3122  */
3124 {
3125  rad_listen_t **last;
3126  rad_listen_t *this;
3127  listen_config_t *lc;
3128  bool incoming_sockets = false;
3129 
3130  if (!listen_config) {
3131  ERROR("The server is not configured to listen on any ports. Cannot start");
3132  return -1;
3133  }
3134 
3135  for (lc = listen_config; lc != NULL; lc = lc->next) {
3136  if (lc->type == RAD_LISTEN_COMMAND) continue;
3137  if (lc->type == RAD_LISTEN_PROXY) continue;
3138 
3139  incoming_sockets = true;
3140  break;
3141  }
3142 
3143  /*
3144  * @fixme: This check should arguably be in
3145  * listen_bootstrap(). But that function bootstraps only
3146  * one listener, because listeners can be located in
3147  * multiple places. So for now, we put it here.
3148  */
3149  if (!incoming_sockets) {
3150  ERROR("The server is not configured to listen on any ports. Cannot start");
3151  return -1;
3152  }
3153 
3154  /*
3155  * We shouldn't be called with a pre-existing list.
3156  */
3157  rad_assert(head && (*head == NULL));
3158 
3159  /*
3160  * Don't bother opening sockets if we're just checking the configuration.
3161  */
3162  if (check_config) return 0;
3163 
3164  last = head;
3165 
3166  for (lc = listen_config; lc != NULL; lc = lc->next) {
3167  if (lc->proto->open(lc->cs, lc->listener) < 0) {
3168  TALLOC_FREE(listen_ctx);
3169  return -1;
3170  }
3171 
3172  this = lc->listener;
3173  *last = this;
3174  last = &(this->next);
3175  }
3176 
3177  /*
3178  * Print out which sockets we're listening on, and
3179  * add them to the event list.
3180  */
3181  for (this = *head; this != NULL; this = this->next) {
3182 #ifdef WITH_TLS
3183  if (!spawn_workers && this->tls) {
3184  cf_log_err_cs(this->cs, "Threading must be enabled for TLS sockets to function properly");
3185  cf_log_err_cs(this->cs, "You probably need to do '%s -fxx -l stdout' for debugging",
3186  main_config.name);
3187  return -1;
3188  }
3189 #endif
3190  if (this->workers && !spawn_workers) {
3191  WARN("Setting 'workers' requires 'synchronous'. Disabling 'workers'");
3192  this->workers = 0;
3193  }
3194 
3195  if (this->workers) {
3196 #ifdef HAVE_PTHREAD_H
3197  int rcode;
3198  uint32_t i;
3199  char buffer[256];
3200 
3201  this->print(this, buffer, sizeof(buffer));
3202 
3203  for (i = 0; i < this->workers; i++) {
3204  pthread_t id;
3205 
3206  /*
3207  * FIXME: create detached?
3208  */
3209  rcode = pthread_create(&id, 0, recv_thread, this);
3210  if (rcode != 0) {
3211  ERROR("Thread create failed: %s", fr_syserror(rcode));
3212  fr_exit(1);
3213  }
3214 
3215  DEBUG("Thread %d for %s\n", i, buffer);
3216  }
3217 #else
3218  WARN("Setting 'workers' requires 'synchronous'. Disabling 'workers'");
3219  this->workers = 0;
3220 #endif
3221  } else {
3222  radius_update_listener(this);
3223  }
3224  }
3225 
3226  return 0;
3227 }
3228 
3229 /** Free a linked list of listeners
3230  *
3231  * @param head of list to free.
3232  */
3234 {
3235  rad_listen_t *this;
3236 
3237  if (!head || !*head) return;
3238 
3239  this = *head;
3240  while (this) {
3241  rad_listen_t *next = this->next;
3242  talloc_free(this);
3243  this = next;
3244  }
3245 
3246  *head = NULL;
3247 
3248  /*
3249  * @fixme: Hack.
3250  */
3251  if (head == &main_config.listen) TALLOC_FREE(listen_ctx);
3252 }
3253 
3254 #ifdef WITH_STATS
3255 /** Find client list associated with a listener.
3256  *
3257  * @param[in] ipaddr listener is bound to.
3258  * @param[in] port listener is bound to.
3259  * @param[in] proto of listener, one of the IPPROTO_* macros.
3260  * @return
3261  * - List of clients.
3262  * - NULL if no matching listeners found.
3263  */
3264 RADCLIENT_LIST *listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
3265 {
3266  rad_listen_t *this;
3267 
3268  for (this = main_config.listen; this != NULL; this = this->next) {
3269  listen_socket_t *sock;
3270 
3271  if ((this->type != RAD_LISTEN_AUTH)
3272 # ifdef WITH_ACCOUNTING
3273  && (this->type != RAD_LISTEN_ACCT)
3274 # endif
3275 # ifdef WITH_COA
3276  && (this->type != RAD_LISTEN_COA)
3277 # endif
3278  ) continue;
3279 
3280  sock = this->data;
3281 
3282  if (sock->my_port != port) continue;
3283  if (sock->proto != proto) continue;
3284  if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3285 
3286  return sock->clients;
3287  }
3288 
3289  return NULL;
3290 }
3291 #endif
3292 
3293 /** Find a listener associated with an IP address/port/transport proto
3294  *
3295  * @param[in] ipaddr listener is bound to.
3296  * @param[in] port listener is bound to.
3297  * @param[in] proto of listener, one of the IPPROTO_* macros.
3298  * @return
3299  * - Listener matching ipaddr/port/proto.
3300  * - NULL if no listeners match.
3301  */
3302 rad_listen_t *listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
3303 {
3304  rad_listen_t *this;
3305 
3306  for (this = main_config.listen; this != NULL; this = this->next) {
3307  listen_socket_t *sock;
3308 
3309  sock = this->data;
3310 
3311  if (sock->my_port != port) continue;
3312  if (sock->proto != proto) continue;
3313  if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3314 
3315  return this;
3316  }
3317 
3318  /*
3319  * Failed to find a specific one. Find INADDR_ANY
3320  */
3321  for (this = main_config.listen; this != NULL; this = this->next) {
3322  listen_socket_t *sock;
3323 
3324  sock = this->data;
3325 
3326  if (sock->my_port != port) continue;
3327  if (sock->proto != proto) continue;
3328  if (!fr_is_inaddr_any(&sock->my_ipaddr)) continue;
3329 
3330  return this;
3331  }
3332 
3333  return NULL;
3334 }
#define ADDSTRING(_x)
struct fr_command_socket_t fr_command_socket_t
void rad_suid_down(void)
Definition: util.c:1474
#define COMMAND_SOCKET_MAGIC
Definition: command.c:82
int sockfd
Socket this packet was read from.
Definition: libradius.h:147
RAD_LISTEN_TYPE priority
Definition: radiusd.h:276
bool rate_limit
Where addition of clients should be rate limited.
Definition: clients.h:91
fr_ipaddr_t src_ipaddr
Resolved version of src_ipaddr_str.
Definition: realms.h:87
#define pthread_mutex_init(_x, _y)
Definition: rlm_eap.h:75
struct listen_detail_t listen_detail_t
128 Bit IPv6 Address.
Definition: radius.h:40
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Definition: radiusd.h:227
char const * interface
Definition: listen.h:124
static int dual_tcp_recv(rad_listen_t *listener)
Definition: listen.c:698
int id
Packet ID (used to link requests/responses).
Definition: libradius.h:154
static void command_socket_free(rad_listen_t *this)
Definition: command.c:3012
int fr_radius_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret)
Calculate/check digest, and decode radius attributes.
Definition: radius.c:1485
rad_listen_t * listener
created from this configuration
Definition: listen.c:82
int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt, FR_TOKEN dflt_quote)
Parses a CONF_PAIR into a C data type, with a default value.
Definition: conffile.c:1968
fr_socket_limit_t limit
Connections per client (TCP clients only).
Definition: clients.h:73
#define RERROR(fmt,...)
Definition: log.h:207
FR_NAME_NUMBER const fr_net_af_table[]
Strings for address families.
Definition: net.c:48
rlm_rcode_t process_authorize(int type, REQUEST *request)
Definition: modules.c:2098
RADCLIENT * client
Definition: listen.h:158
FR_NAME_NUMBER const fr_net_ip_proto_table[]
Strings for L4 protocols.
Definition: net.c:30
Only displayed when debugging is enabled.
Definition: log.h:41
#define FR_STATS_TYPE_INC(_x)
Definition: stats.h:90
bfd_auth_t auth
Definition: proto_bfd.c:209
int fr_socket_client_tcp(fr_ipaddr_t *src_ipaddr, fr_ipaddr_t *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
Definition: socket.c:167
fr_uint_t total_packets_dropped
Definition: stats.h:49
RADCLIENT_LIST * client_list_parse_section(CONF_SECTION *section, bool tls_required)
RFC2865 - Access-Challenge.
Definition: radius.h:102
Main server configuration.
Definition: radiusd.h:108
rad_listen_debug_t debug
Definition: protocol.h:56
static int command_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
Definition: command.c:3120
RADIUS_PACKET * proxy_reply
Incoming response from proxy server.
Definition: radiusd.h:238
static int listen_bind(rad_listen_t *this)
Definition: listen.c:2649
RAD_LISTEN_TYPE type
Definition: listen.h:76
home_server_t * home
Definition: listen.h:139
bool rbtree_deletebydata(rbtree_t *tree, void const *data)
Delete a node from the tree, based on given data, which MUST have come from rbtree_finddata().
Definition: rbtree.c:496
static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
Definition: listen.c:1710
The module is OK, continue.
Definition: radiusd.h:91
#define TRANSPORT_DUAL
Definition: protocol.h:63
uint16_t other_port
Definition: listen.h:141
fr_socket_limit_t limit
Definition: realms.h:93
#define WAS_PROXIED
rad_listen_print_t print
Definition: protocol.h:55
static int listener_unlink(UNUSED void *ctx, UNUSED void *data)
Definition: listen.c:1264
void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench) CC_HINT(nonnull(3))
Execute a trigger - call an executable to process an event.
Definition: exec.c:686
uint32_t max_rate
Definition: listen.h:136
uint32_t lifetime
How long before the client is removed.
Definition: clients.h:80
RAD_LISTEN_TYPE
Definition: listen.h:38
int radlog(log_type_t lvl, char const *fmt,...) CC_HINT(format(printf
int fr_ipaddr_from_sockaddr(struct sockaddr_storage const *sa, socklen_t salen, fr_ipaddr_t *ipaddr, uint16_t *port)
Definition: inet.c:1095
uint16_t my_port
Definition: listen.h:122
rlm_rcode_t process_send_coa(int type, REQUEST *request)
Definition: modules.c:2189
int rad_accounting(REQUEST *)
Definition: acct.c:38
char const * cf_section_filename(CONF_SECTION const *section)
Definition: conffile.c:3913
rad_listen_t * next
Definition: listen.h:70
char const * fr_packet_codes[FR_MAX_PACKET_CODE]
Definition: radius.c:101
lt_dlhandle lt_dlopenext(char const *name)
Definition: modules.c:151
int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)
Definition: tcp.c:62
fr_ipaddr_t other_ipaddr
Definition: listen.h:140
fr_ipaddr_t src_ipaddr
Src IP address of packet.
Definition: libradius.h:149
static listen_config_t * listen_config
Definition: listen.c:86
uint8_t prefix
Prefix length - Between 0-32 for IPv4 and 0-128 for IPv6.
Definition: inet.h:47
int fr_is_inaddr_any(fr_ipaddr_t *ipaddr)
Determine if an address is the INADDR_ANY address for its address family.
Definition: packet.c:91
#define INFO(fmt,...)
Definition: log.h:143
WiMAX IPv4 or IPv6 address depending on length.
Definition: radius.h:46
static char const * name
uint32_t talloc_pool_size
Size of pool to allocate to hold each REQUEST.
Definition: radiusd.h:155
static fr_protocol_t master_listen[]
Definition: listen.c:97
int fd
Definition: listen.h:77
#define RDEBUG_ENABLED
True if request debug level 1 messages are enabled.
Definition: log.h:237
int common_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize)
Definition: listen.c:1021
rad_listen_parse_t open
Definition: protocol.h:51
#define UNUSED
Definition: libradius.h:134
#define RLM_MODULE_INIT
Definition: modules.h:86
rad_listen_encode_t encode
Definition: protocol.h:57
static int command_tcp_send(rad_listen_t *listener, REQUEST *request)
Error message.
Definition: log.h:36
#define REDEBUG2(fmt,...)
Definition: log.h:255
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
Definition: libradius.h:162
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
Definition: detail.c:1027
struct listen_config_t * next
the next listener
Definition: listen.c:74
void request_stats_reply(REQUEST *request)
Definition: stats.c:481
#define pair_make_request(_a, _b, _c)
Definition: radiusd.h:545
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
Definition: missing.c:538
char const * secret
Secret PSK.
Definition: clients.h:43
static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
Definition: listen.c:2441
RADCLIENT RADCLIENT * client_find(RADCLIENT_LIST const *clients, fr_ipaddr_t const *ipaddr, int proto)
Definition: client.c:431
void void void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt,...) CC_HINT(format(printf
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:686
static int proxy_socket_recv(rad_listen_t *listener)
Definition: listen.c:2286
int fr_radius_send(RADIUS_PACKET *, RADIUS_PACKET const *, char const *secret)
Reply to the request.
Definition: radius.c:506
fr_stats_t auth
Authentication stats.
Definition: clients.h:59
rad_listen_t * listener
The listener that received the request.
Definition: radiusd.h:218
#define PW_AUTHORIZE_ONLY
Definition: radius.h:182
struct listen_socket_t listen_socket_t
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: conffile.h:222
The module considers the request invalid.
Definition: radiusd.h:93
char const * name
Name of the daemon, usually 'radiusd'.
Definition: radiusd.h:109
static int command_tcp_recv(rad_listen_t *listener)
unsigned int number
Monotonically increasing request number. Reset on server restart.
Definition: radiusd.h:213
RADCLIENT_LIST * listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
Find client list associated with a listener.
Definition: listen.c:3264
void listen_free(rad_listen_t **head)
Free a linked list of listeners.
Definition: listen.c:3233
VALUE_PAIR * fr_pair_list_copy_by_num(TALLOC_CTX *ctx, VALUE_PAIR *from, unsigned int vendor, unsigned int attr, int8_t tag)
Copy matching pairs.
Definition: pair.c:1428
rad_listen_send_t send
Definition: listen.h:96
rlm_rcode_t process_recv_coa(int type, REQUEST *request)
Definition: modules.c:2184
int rad_status_server(REQUEST *request)
Definition: listen.c:596
RFC3575/RFC5176 - Disconnect-Ack (positive)
Definition: radius.h:106
uint32_t max_connections
Definition: realms.h:60
uint16_t dst_port
DST Port of packet.
Definition: libradius.h:152
uint16_t src_port
Src port of packet.
Definition: libradius.h:151
fr_ipaddr_t dst_ipaddr
Dst IP address of packet.
Definition: libradius.h:150
fr_ipaddr_t my_ipaddr
Definition: listen.h:121
fr_socket_limit_t limit
Definition: listen.h:156
void common_packet_debug(REQUEST *request, RADIUS_PACKET *packet, bool received)
Definition: listen.c:1153
static int command_domain_accept(rad_listen_t *listener)
Definition: command.c:3513
Defines a CONF_PAIR to C data type mapping.
Definition: conffile.h:267
fr_dict_enum_t * fr_dict_enum_by_name(fr_dict_t *dict, fr_dict_attr_t const *da, char const *val)
Definition: dict.c:3703
#define FR_STATS_INC(_x, _y)
Definition: stats.h:89
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
Definition: conffile.c:3478
char const * cf_pair_value(CONF_PAIR const *pair)
Definition: conffile.c:3506
RFC2866 - Accounting-Response.
Definition: radius.h:96
static char const * proto
Definition: radclient.c:63
rad_listen_recv_t recv
Definition: protocol.h:53
bool client_add_dynamic(RADCLIENT_LIST *clients, RADCLIENT *master, RADCLIENT *c)
Add a dynamic client.
Definition: client.c:708
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
Definition: inet.h:67
RADIUS_PACKET * proxy
Outgoing request to proxy server.
Definition: radiusd.h:237
const FR_NAME_NUMBER mod_rcode_table[]
Definition: modcall.c:186
char const * server
For internal proxying.
Definition: realms.h:75
RFC2865 - Access-Reject.
Definition: radius.h:94
main_config_t * root
Pointer to the main config hack to try and deal with hup.
Definition: radiusd.h:267
RFC3575/RFC5176 - CoA-Ack (positive)
Definition: radius.h:109
int af
Address family.
Definition: inet.h:42
#define TRANSPORT_UDP
Definition: protocol.h:62
#define rad_assert(expr)
Definition: rad_assert.h:38
Reject the request (user is locked out).
Definition: radiusd.h:94
static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
Definition: listen.c:2477
RFC2865 - Access-Request.
Definition: radius.h:92
static TALLOC_CTX * listen_ctx
Definition: listen.c:85
void client_delete(RADCLIENT_LIST *clients, RADCLIENT *client)
Definition: client.c:378
size_t inst_size
Definition: protocol.h:42
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: log.c:238
static int proxy_socket_tcp_recv(rad_listen_t *listener)
Definition: listen.c:2354
Highest priority debug messages (-x).
Definition: log.h:51
time_t last_failed_open
Definition: realms.h:108
int detail_print(rad_listen_t const *this, char *buffer, size_t bufsize)
Definition: detail.c:962
int detail_socket_open(CONF_SECTION *cs, rad_listen_t *this)
static int listener_cmp(void const *one, void const *two)
Definition: listen.c:1257
static int command_domain_send(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
Definition: command.c:3626
rad_listen_t * proxy_new_listener(TALLOC_CTX *ctx, home_server_t *home, uint16_t src_port)
Definition: listen.c:2927
#define DEBUG(fmt,...)
Definition: log.h:175
rbtree_t * rbtree_create(TALLOC_CTX *ctx, rb_comparator_t compare, rb_free_t node_free, int flags)
Create a new RED-BLACK tree.
Definition: rbtree.c:112
int fr_radius_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, char const *secret)
Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet...
Definition: radius.c:1144
int(* RAD_REQUEST_FUNP)(REQUEST *)
Definition: process.h:51
static void print_packet(FILE *fp, RADIUS_PACKET *packet)
Definition: unittest.c:384
#define PW_RADIUS_TLS_PORT
Definition: radius.h:119
static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
Definition: listen.c:2421
static int command_socket_decode(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
Definition: command.c:3640
void void void void cf_log_info(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
static int do_proxy(REQUEST *request)
Definition: listen.c:2010
int rad_authenticate(REQUEST *)
Definition: auth.c:348
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
Definition: pair.c:659
struct listen_config_t listen_config_t
#define DEBUG2(fmt,...)
Definition: log.h:176
RFC2866 - Accounting-Request.
Definition: radius.h:95
RADCLIENT * client_afrom_request(RADCLIENT_LIST *clients, REQUEST *request)
Create a new client, consuming all attributes in the control list of the request. ...
Definition: client.c:1175
#define STRINGIFY(x)
Definition: build.h:34
RADIUS_PACKET * fr_radius_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new RADIUS_PACKET.
Definition: radius.c:1651
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
Definition: conffile.c:2234
RAD_LISTEN_TYPE type
Definition: listen.c:79
Immediately reject the request.
Definition: radiusd.h:89
union fr_ipaddr_t::@1 ipaddr
RFC3575/RFC5176 - CoA-Nak (not willing to perform)
Definition: radius.h:110
RADCLIENT * client_listener_find(rad_listen_t *listener, fr_ipaddr_t const *ipaddr, uint16_t src_port)
Definition: listen.c:344
unsigned int code
Packet code (type).
Definition: libradius.h:155
fr_stats_t stats
Definition: listen.h:106
int rbtree_walk(rbtree_t *tree, rb_order_t order, rb_walker_t compare, void *context)
Definition: rbtree.c:693
uint32_t num_connections
Definition: realms.h:61
RFC2865 - Access-Accept.
Definition: radius.h:93
static rad_listen_t * listen_alloc(TALLOC_CTX *ctx, RAD_LISTEN_TYPE type, fr_protocol_t *proto)
Definition: listen.c:2898
CONF_SECTION * cf_top_section(CONF_SECTION *cs)
Definition: conffile.c:1041
int fr_dict_enum_add(fr_dict_t *dict, char const *attr, char const *alias, int value)
Definition: dict.c:1153
int lt_dlclose(lt_dlhandle handle)
Definition: modules.c:274
rlm_rcode_t process_accounting(int type, REQUEST *request)
Definition: modules.c:2123
static int command_socket_open(CONF_SECTION *cs, rad_listen_t *this)
Definition: command.c:3150
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
static CONF_PARSER performance_config[]
Definition: listen.c:1224
RADIUS_PACKET * reply
Outgoing response.
Definition: radiusd.h:225
static int command_socket_encode(UNUSED rad_listen_t *listener, UNUSED REQUEST *request)
Definition: command.c:3633
static int dual_tcp_accept(rad_listen_t *listener)
Definition: listen.c:816
CONF_SECTION * cs
CONF_SECTION that was parsed to generate the client.
Definition: clients.h:56
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
static int command_write_magic(int newfd, listen_socket_t *sock)
#define UDP_FLAGS_PEEK
Definition: udp.h:40
A truth value.
Definition: radius.h:56
CoA destination (NAS or Proxy)
Definition: realms.h:41
rad_listen_decode_t decode
Definition: protocol.h:58
static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
Definition: listen.c:1634
Configuration AVP similar to a VALUE_PAIR.
Definition: conffile.c:82
void rad_suid_up(void)
Definition: util.c:1471
rad_listen_print_t print
Definition: listen.h:100
fr_event_t * ev
Definition: listen.h:154
static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
Definition: listen.c:2495
Definition: token.h:45
time_t last_packet
Definition: listen.h:152
32 Bit unsigned integer.
Definition: radius.h:34
int rad_coa_recv(REQUEST *request)
Definition: listen.c:2045
RFC3575/RFC5176 - CoA-Request.
Definition: radius.h:108
char const * fr_strerror(void)
Get the last library error.
Definition: log.c:212
char const * server_name
name of the virtual server (if any)
Definition: listen.c:77
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
Definition: conffile.c:3708
void radlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg,...) CC_HINT(format(printf
ssize_t fr_radius_len(uint8_t const *data, size_t data_len)
See how big of a packet is in the buffer.
Definition: radius.c:679
#define DEBUG4(fmt,...)
Definition: log.h:178
void rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of VALUE_PAIRs.
Definition: pair.c:757
#define FORWARD
rad_listen_send_t send
Definition: protocol.h:54
static int coa_socket_recv(rad_listen_t *listener)
Definition: listen.c:2201
char identity[]
Definition: eap_pwd.h:630
uint32_t idle_timeout
Definition: realms.h:65
int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *packet, RADCLIENT *client, RAD_REQUEST_FUNP fun)
Definition: process.c:1523
char const * log_name
The name used for log messages.
Definition: realms.h:69
Module succeeded without doing anything.
Definition: radiusd.h:96
int if_index
Index of receiving interface.
Definition: libradius.h:148
Describes a host allowed to send packets to the server.
Definition: clients.h:35
void * lt_dlhandle
Definition: modpriv.h:42
time_t created
When the client was created.
Definition: clients.h:82
void rdebug_proto_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of protocol VALUE_PAIRs.
Definition: pair.c:784
rbtree_t * children
Definition: listen.h:84
void detail_free(rad_listen_t *this)
Definition: detail.c:914
struct listen_socket_t * parent
Definition: listen.h:157
uint8_t data[]
Definition: eap_pwd.h:625
uint32_t dynamic
Whether the client was dynamically defined.
Definition: clients.h:81
RADIUS_PACKET * fr_tcp_recv(int sockfd, int flags)
Definition: tcp.c:32
int detail_recv(rad_listen_t *listener)
Definition: detail.c:316
#define PW_RADMIN_PORT
Definition: radiusd.h:624
int fr_socket_server_base(int proto, fr_ipaddr_t *ipaddr, int *port, char const *port_name, bool async)
Open an IPv4 / IPv6, and UDP / TCP socket, server side.
Definition: socket.c:422
static bool spawn_workers
Definition: process.c:50
rad_listen_t * proxy_listener
Listener for outgoing requests.
Definition: radiusd.h:236
Module failed, don't reply.
Definition: radiusd.h:90
#define NO_LISTENER
Definition: listen.c:2508
#define TAG_ANY
Definition: pair.h:191
CONF_SECTION * config
Root of the server config.
Definition: radiusd.h:110
RADCLIENT_LIST * clients
Definition: listen.h:174
int fr_socket(fr_ipaddr_t *ipaddr, uint16_t port)
Definition: packet.c:136
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
log_lvl_t rad_debug_lvl
Global debugging level.
Definition: log.c:49
char const * name
The name of the protocol.
Definition: protocol.h:41
void fr_radius_free(RADIUS_PACKET **)
Free a RADIUS_PACKET.
Definition: radius.c:1727
static int _listener_free(rad_listen_t *this)
Definition: listen.c:2831
#define FR_ITEM_POINTER(_t, _p)
Definition: conffile.h:176
CONF_SECTION * server
encapsulating server configuratiuon
Definition: listen.c:75
RADIUS_PACKET * fr_radius_alloc_reply(TALLOC_CTX *ctx, RADIUS_PACKET *)
Allocate a new RADIUS_PACKET response.
Definition: radius.c:1691
rad_listen_t * listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
Find a listener associated with an IP address/port/transport proto.
Definition: listen.c:3302
size_t data_len
Length of packet data.
Definition: libradius.h:161
bool rbtree_insert(rbtree_t *tree, void *data)
Definition: rbtree.c:329
static int _listen_config_free(listen_config_t *lc)
Definition: listen.c:99
ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code)
Basic validation of RADIUS packet header.
Definition: radius.c:299
RADIUS_PACKET * packet
Incoming request.
Definition: radiusd.h:221
fr_ipaddr_t src_ipaddr
IPv4/IPv6 address to send responses from (family must match ipaddr).
Definition: clients.h:37
#define WARN(fmt,...)
Definition: log.h:144
fr_protocol_t * proto
same as Listen-Socket-Type
Definition: listen.c:80
#define RATE_LIMIT(_x)
Rate limit messages.
Definition: log.h:380
int value
Enum value.
Definition: dict.h:96
int status
Definition: listen.h:79
#define REDEBUG(fmt,...)
Definition: log.h:254
RADIUS_PACKET * packet
Definition: listen.h:160
int fr_radius_encode(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret)
Encode a packet.
Definition: radius.c:1318
main_config_t main_config
Main server configuration.
Definition: mainconfig.c:43
time_t opened
Definition: listen.h:153
rad_listen_t * listen
Head of a linked list of listeners.
Definition: radiusd.h:147
bool check_config
Definition: conffile.c:45
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
home_server_t * home_server
Definition: radiusd.h:240
static int acct_socket_recv(rad_listen_t *listener)
Definition: listen.c:1915
char * fr_inet_ntop(char out[FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t *addr)
Print the address portion of a fr_ipaddr_t.
Definition: inet.c:713
uint32_t transports
Definition: protocol.h:45
lt_dlhandle * handle
to dynamically loaded library (if any)
Definition: listen.c:78
RFC2865/RFC5997 - Status Server (request)
Definition: radius.h:103
int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
Definition: detail.c:999
bool status_server
Whether to respond to status-server messages.
Definition: radiusd.h:129
static int command_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize)
Definition: command.c:3160
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:38
fr_stats_t acct
Accounting stats.
Definition: clients.h:61
uint32_t recv_buff
Socket receive buffer size we only allow configuration of SO_RCVBUF, as SO_SNDBUF controls the maximu...
Definition: listen.h:146
IPv4/6 prefix.
Definition: inet.h:41
uint64_t magic
Used to validate loaded library.
Definition: protocol.h:40
char const * client_server
Virtual server associated with this dynamic client.
Definition: clients.h:87
int common_socket_open(CONF_SECTION *cs, rad_listen_t *this)
Definition: listen.c:1599
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
Definition: token.c:506
int detail_send(rad_listen_t *listener, REQUEST *request)
Definition: detail.c:64
static rad_listen_t * listen_parse(listen_config_t *lc)
Definition: listen.c:3052
static CONF_PARSER limit_config[]
Definition: listen.c:1234
void * data
Definition: listen.h:103
RADIUS_PACKET * fr_radius_recv(TALLOC_CTX *ctx, int fd, int flags)
Receive UDP client requests, and fill in the basics of a RADIUS_PACKET structure. ...
Definition: radius.c:1050
int request_proxy_reply(RADIUS_PACKET *packet)
Definition: process.c:2418
bool message_authenticator
Require RADIUS message authenticator in requests.
Definition: clients.h:45
int fr_socket_server_bind(int sockfd, fr_ipaddr_t *ipaddr, int *port, char const *interface)
Bind to an IPv4 / IPv6, and UDP / TCP socket, server side.
Definition: socket.c:615
home_pool_t * home_pool_byname(char const *name, int type)
Definition: realms.c:2704
home_server_t * home_server_find(fr_ipaddr_t *ipaddr, uint16_t port, int proto)
Definition: realms.c:2660
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
Definition: dict.c:3519
String of printable characters.
Definition: radius.h:33
static int stats_socket_recv(rad_listen_t *listener)
Definition: listen.c:1733
time_t last_new_client
Used for relate limiting addition and deletion of dynamic clients.
Definition: clients.h:84
int detail_parse(CONF_SECTION *cs, rad_listen_t *this)
Definition: detail.c:1109
static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
Definition: listen.c:1668
CONF_SECTION * cf_section_sub_find_name2(CONF_SECTION const *, char const *name1, char const *name2)
Find a CONF_SECTION with both names.
Definition: conffile.c:3728
RADCLIENT * client
The client that originally sent us the request.
Definition: radiusd.h:219
User not found.
Definition: radiusd.h:95
RFC3575/RFC5176 - Disconnect-Nak (not willing to perform)
Definition: radius.h:107
#define pthread_mutex_destroy(_x)
Definition: rlm_eap.h:76
#define RCSID(id)
Definition: build.h:135
char const * server
Virtual server client is associated with.
Definition: clients.h:52
fr_uint_t total_unknown_types
Definition: stats.h:51
void radius_update_listener(rad_listen_t *listener)
Definition: process.c:336
static int auth_socket_recv(rad_listen_t *listener)
Definition: listen.c:1801
char const * fr_inet_ntoh(fr_ipaddr_t const *src, char *out, size_t outlen)
Perform reverse resolution of an IP address.
Definition: inet.c:226
OK (pairs modified).
Definition: radiusd.h:97
#define TRANSPORT_TCP
Definition: protocol.h:61
32 Bit IPv4 Address.
Definition: radius.h:35
The module handled the request, so stop.
Definition: radiusd.h:92
#define DEBUG_ENABLED
True if global debug level 1 messages are enabled.
Definition: log.h:169
int listen_init(rad_listen_t **head, bool spawn_workers)
Search for listeners in the server.
Definition: listen.c:3123
char const * secret
Definition: realms.h:95
uint16_t port
Definition: realms.h:79
int fr_ipaddr_cmp(fr_ipaddr_t const *a, fr_ipaddr_t const *b)
Compare two ip addresses.
Definition: inet.c:1026
uint32_t lifetime
Definition: realms.h:64
#define RDEBUG(fmt,...)
Definition: log.h:243
#define fr_exit(_x)
Definition: libradius.h:508
int proto
TCP or UDP.
Definition: realms.h:91
rad_listen_parse_t parse
Definition: protocol.h:50
#define ERROR(fmt,...)
Definition: log.h:145
static void common_socket_free(rad_listen_t *this)
Definition: listen.c:995
#define is_radius_code(_x)
Definition: libradius.h:372
bool in_proxy_hash
Definition: radiusd.h:280
fr_protocol_t * proto
Definition: listen.h:71
void udp_recv_discard(int sockfd)
Discard the next UDP packet.
Definition: udp.c:105
fr_uint_t total_requests
Definition: stats.h:40
Value of an enumerated attribute.
Definition: dict.h:94
16 Bit unsigned integer.
Definition: radius.h:43
fr_ipaddr_t ipaddr
IP address of home server.
Definition: realms.h:78
REQUEST * request_alloc(TALLOC_CTX *ctx)
Create a new REQUEST data structure.
Definition: request.c:85
char const * server
Definition: radiusd.h:289
char const * shortname
Client nickname.
Definition: clients.h:41
RFC3575/RFC5176 - Disconnect-Request.
Definition: radius.h:105
CONF_SECTION * cs
configuration for this listener
Definition: listen.c:76
int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
Definition: listen.c:1274
int listen_bootstrap(CONF_SECTION *server, CONF_SECTION *cs, char const *server_name)
Definition: listen.c:109
int fr_radius_sign(RADIUS_PACKET *packet, RADIUS_PACKET const *original, char const *secret)
Sign a previously encoded packet.
Definition: radius.c:389