2 * listen.c Handle socket stuff
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.
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.
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
20 * Copyright 2005,2006 The FreeRADIUS server project
21 * Copyright 2005 Alan DeKok <aland@ox.org>
24 #include <freeradius-devel/ident.h>
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/rad_assert.h>
30 #include <freeradius-devel/vqp.h>
31 #include <freeradius-devel/dhcp.h>
33 #include <freeradius-devel/vmps.h>
34 #include <freeradius-devel/detail.h>
37 #include <freeradius-devel/udpfromto.h>
40 #ifdef HAVE_SYS_RESOURCE_H
41 #include <sys/resource.h>
54 * We'll use this below.
56 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
57 typedef void (*rad_listen_free_t)(rad_listen_t *);
59 typedef struct rad_listen_master_t {
60 rad_listen_parse_t parse;
61 rad_listen_free_t free;
62 rad_listen_recv_t recv;
63 rad_listen_send_t send;
64 rad_listen_print_t print;
65 rad_listen_encode_t encode;
66 rad_listen_decode_t decode;
67 } rad_listen_master_t;
69 typedef struct listen_socket_t {
75 #ifdef SO_BINDTODEVICE
76 const char *interface;
78 RADCLIENT_LIST *clients;
81 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
84 * Find a per-socket client.
86 RADCLIENT *client_listener_find(const rad_listen_t *listener,
87 const fr_ipaddr_t *ipaddr, int src_port)
89 #ifdef WITH_DYNAMIC_CLIENTS
91 listen_socket_t *sock;
97 RADCLIENT_LIST *clients;
99 rad_assert(listener != NULL);
100 rad_assert(ipaddr != NULL);
102 clients = ((listen_socket_t *)listener->data)->clients;
105 * This HAS to have been initialized previously.
107 rad_assert(clients != NULL);
109 client = client_find(clients, ipaddr);
111 static time_t last_printed = 0;
112 char name[256], buffer[128];
114 #ifdef WITH_DYNAMIC_CLIENTS
115 unknown: /* used only for dynamic clients */
119 * DoS attack quenching, but only in debug mode.
120 * If they're running in debug mode, show them
123 if (debug_flag == 0) {
125 if (last_printed == now) return NULL;
130 listener->print(listener, name, sizeof(name));
132 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d",
133 name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
134 buffer, sizeof(buffer)),
139 #ifndef WITH_DYNAMIC_CLIENTS
140 return client; /* return the found client. */
144 * No server defined, and it's not dynamic. Return it.
146 if (!client->client_server && !client->dynamic) return client;
151 * It's a dynamically generated client, check it.
153 if (client->dynamic && (src_port != 0)) {
155 * Lives forever. Return it.
157 if (client->lifetime == 0) return client;
160 * Rate-limit the deletion of known clients.
161 * This makes them last a little longer, but
162 * prevents the server from melting down if (say)
163 * 10k clients all expire at once.
165 if (now == client->last_new_client) return client;
168 * It's not dead yet. Return it.
170 if ((client->created + client->lifetime) > now) return client;
173 * This really puts them onto a queue for later
176 client_delete(clients, client);
179 * Go find the enclosing network again.
181 client = client_find(clients, ipaddr);
186 if (!client) goto unknown;
187 if (!client->client_server) goto unknown;
190 * At this point, 'client' is the enclosing
191 * network that configures where dynamic clients
194 rad_assert(client->dynamic == 0);
197 * The IP is unknown, so we've found an enclosing
198 * network. Enable DoS protection. We only
199 * allow one new client per second. Known
200 * clients aren't subject to this restriction.
202 if (now == client->last_new_client) goto unknown;
205 client->last_new_client = now;
207 request = request_alloc();
208 if (!request) goto unknown;
210 request->listener = listener;
211 request->client = client;
212 request->packet = rad_alloc(0);
213 if (!request->packet) {
214 request_free(&request);
217 request->reply = rad_alloc(0);
218 if (!request->reply) {
219 request_free(&request);
222 request->packet->timestamp = request->timestamp;
224 request->priority = listener->type;
225 request->server = client->client_server;
226 request->root = &mainconfig;
229 * Run a fake request through the given virtual server.
230 * Look for FreeRADIUS-Client-IP-Address
231 * FreeRADIUS-Client-Secret
234 * and create the RADCLIENT structure from that.
237 sock = listener->data;
238 request->packet->sockfd = listener->fd;
239 request->packet->src_ipaddr = *ipaddr;
240 request->packet->src_port = 0; /* who cares... */
241 request->packet->dst_ipaddr = sock->ipaddr;
242 request->packet->dst_port = sock->port;
244 request->reply->sockfd = request->packet->sockfd;
245 request->reply->dst_ipaddr = request->packet->src_ipaddr;
246 request->reply->src_ipaddr = request->packet->dst_ipaddr;
247 request->reply->dst_port = request->packet->src_port;
248 request->reply->src_port = request->packet->dst_port;
249 request->reply->id = request->packet->id;
250 request->reply->code = 0; /* UNKNOWN code */
253 DEBUG("server %s {", request->server);
255 rcode = module_authorize(0, request);
257 DEBUG("} # server %s", request->server);
259 if (rcode != RLM_MODULE_OK) {
260 request_free(&request);
265 * If the client was updated by rlm_dynamic_clients,
266 * don't create the client from attribute-value pairs.
268 if (request->client == client) {
269 created = client_create(clients, request);
271 created = request->client;
274 * This frees the client if it isn't valid.
276 if (!client_validate(clients, client, created)) goto unknown;
278 request_free(&request);
280 if (!created) goto unknown;
286 static int listen_bind(rad_listen_t *this);
290 * Process and reply to a server-status request.
291 * Like rad_authenticate and rad_accounting this should
292 * live in it's own file but it's so small we don't bother.
294 static int rad_status_server(REQUEST *request)
296 int rcode = RLM_MODULE_OK;
299 switch (request->listener->type) {
301 case RAD_LISTEN_NONE:
303 case RAD_LISTEN_AUTH:
304 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
306 rcode = module_authorize(dval->value, request);
308 rcode = RLM_MODULE_OK;
313 case RLM_MODULE_UPDATED:
314 request->reply->code = PW_AUTHENTICATION_ACK;
317 case RLM_MODULE_FAIL:
318 case RLM_MODULE_HANDLED:
319 request->reply->code = 0; /* don't reply */
323 case RLM_MODULE_REJECT:
324 request->reply->code = PW_AUTHENTICATION_REJECT;
329 #ifdef WITH_ACCOUNTING
330 case RAD_LISTEN_ACCT:
331 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
333 rcode = module_accounting(dval->value, request);
335 rcode = RLM_MODULE_OK;
340 case RLM_MODULE_UPDATED:
341 request->reply->code = PW_ACCOUNTING_RESPONSE;
345 request->reply->code = 0; /* don't reply */
353 * This is a vendor extension. Suggested by Glen
354 * Zorn in IETF 72, and rejected by the rest of
355 * the WG. We like it, so it goes in here.
358 dval = dict_valbyname(PW_RECV_COA_TYPE, "Status-Server");
360 rcode = module_recv_coa(dval->value, request);
362 rcode = RLM_MODULE_OK;
367 case RLM_MODULE_UPDATED:
368 request->reply->code = PW_COA_ACK;
372 request->reply->code = 0; /* don't reply */
384 * Full statistics are available only on a statistics
387 if (request->listener->type == RAD_LISTEN_NONE) {
388 request_stats_reply(request);
396 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
399 listen_socket_t *sock = this->data;
402 switch (this->type) {
404 case RAD_LISTEN_NONE: /* what a hack... */
409 case RAD_LISTEN_AUTH:
410 name = "authentication";
413 #ifdef WITH_ACCOUNTING
414 case RAD_LISTEN_ACCT:
420 case RAD_LISTEN_PROXY:
432 case RAD_LISTEN_DHCP:
448 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
449 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
453 #ifdef SO_BINDTODEVICE
454 if (sock->interface) {
455 ADDSTRING(" interface ");
456 ADDSTRING(sock->interface);
460 ADDSTRING(" address ");
462 if ((sock->ipaddr.af == AF_INET) &&
463 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
464 strlcpy(buffer, "*", bufsize);
466 ip_ntoh(&sock->ipaddr, buffer, bufsize);
471 snprintf(buffer, bufsize, "%d", sock->port);
475 ADDSTRING(" as server ");
476 ADDSTRING(this->server);
487 * Parse an authentication or accounting socket.
489 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
494 listen_socket_t *sock = this->data;
495 char *section_name = NULL;
496 CONF_SECTION *client_cs, *parentcs;
501 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
502 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
503 &ipaddr.ipaddr.ip4addr, NULL);
504 if (rcode < 0) return -1;
506 if (rcode == 0) { /* successfully parsed IPv4 */
509 } else { /* maybe IPv6? */
510 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
511 &ipaddr.ipaddr.ip6addr, NULL);
512 if (rcode < 0) return -1;
515 cf_log_err(cf_sectiontoitem(cs),
516 "No address specified in listen section");
519 ipaddr.af = AF_INET6;
522 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
524 if (rcode < 0) return -1;
526 if ((listen_port < 0) || (listen_port > 65535)) {
527 cf_log_err(cf_sectiontoitem(cs),
528 "Invalid value for \"port\"");
532 sock->ipaddr = ipaddr;
533 sock->port = listen_port;
536 * If we can bind to interfaces, do so,
539 if (cf_pair_find(cs, "interface")) {
540 #ifndef SO_BINDTODEVICE
541 cf_log_err(cf_sectiontoitem(cs),
542 "System does not support binding to interfaces. Delete this line from the configuration file.");
546 CONF_PAIR *cp = cf_pair_find(cs, "interface");
548 rad_assert(cp != NULL);
549 value = cf_pair_value(cp);
551 cf_log_err(cf_sectiontoitem(cs),
552 "No interface name given");
555 sock->interface = value;
560 * And bind it to the port.
562 if (listen_bind(this) < 0) {
564 cf_log_err(cf_sectiontoitem(cs),
565 "Error binding to port for %s port %d",
566 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
573 * Proxy sockets don't have clients.
575 if (this->type == RAD_LISTEN_PROXY) return 0;
579 * The more specific configurations are preferred to more
583 parentcs = cf_top_section(cs);
584 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
585 §ion_name, NULL);
586 if (rcode < 0) return -1; /* bad string */
589 * Explicit list given: use it.
591 client_cs = cf_section_sub_find_name2(parentcs,
595 client_cs = cf_section_find(section_name);
598 cf_log_err(cf_sectiontoitem(cs),
599 "Failed to find clients %s {...}",
605 } /* else there was no "clients = " entry. */
608 CONF_SECTION *server_cs;
610 server_cs = cf_section_sub_find_name2(parentcs,
614 * Found a "server foo" section. If there are clients
618 (cf_section_sub_find(server_cs, "client") != NULL)) {
619 client_cs = server_cs;
624 * Still nothing. Look for global clients.
626 if (!client_cs) client_cs = parentcs;
628 sock->clients = clients_parse_section(client_cs);
629 if (!sock->clients) {
630 cf_log_err(cf_sectiontoitem(cs),
631 "Failed to load clients for this listen section");
639 * Send an authentication response packet
641 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
643 rad_assert(request->listener == listener);
644 rad_assert(listener->send == auth_socket_send);
646 return rad_send(request->reply, request->packet,
647 request->client->secret);
651 #ifdef WITH_ACCOUNTING
653 * Send an accounting response packet (or not)
655 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
657 rad_assert(request->listener == listener);
658 rad_assert(listener->send == acct_socket_send);
661 * Accounting reject's are silently dropped.
663 * We do it here to avoid polluting the rest of the
664 * code with this knowledge
666 if (request->reply->code == 0) return 0;
668 return rad_send(request->reply, request->packet,
669 request->client->secret);
675 * Send a packet to a home server.
677 * FIXME: have different code for proxy auth & acct!
679 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
681 listen_socket_t *sock = listener->data;
683 rad_assert(request->proxy_listener == listener);
684 rad_assert(listener->send == proxy_socket_send);
686 request->proxy->src_ipaddr = sock->ipaddr;
687 request->proxy->src_port = sock->port;
689 return rad_send(request->proxy, request->packet,
690 request->home_server->secret);
696 * Check if an incoming request is "ok"
698 * It takes packets, not requests. It sees if the packet looks
699 * OK. If so, it does a number of sanity checks on it.
701 static int stats_socket_recv(rad_listen_t *listener,
702 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
706 RADIUS_PACKET *packet;
708 fr_ipaddr_t src_ipaddr;
710 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
711 if (rcode < 0) return 0;
713 RAD_STATS_TYPE_INC(listener, total_requests);
715 if (rcode < 20) { /* AUTH_HDR_LEN */
716 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
720 if ((client = client_listener_find(listener,
721 &src_ipaddr, src_port)) == NULL) {
722 rad_recv_discard(listener->fd);
723 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
728 * We only understand Status-Server on this socket.
730 if (code != PW_STATUS_SERVER) {
731 DEBUG("Ignoring packet code %d sent to Status-Server port",
733 rad_recv_discard(listener->fd);
734 RAD_STATS_TYPE_INC(listener, total_unknown_types);
735 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
740 * Now that we've sanity checked everything, receive the
743 packet = rad_recv(listener->fd, 1); /* require message authenticator */
745 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
746 DEBUG("%s", fr_strerror());
750 if (!received_request(listener, packet, prequest, client)) {
751 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
752 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
757 *pfun = rad_status_server;
764 * Check if an incoming request is "ok"
766 * It takes packets, not requests. It sees if the packet looks
767 * OK. If so, it does a number of sanity checks on it.
769 static int auth_socket_recv(rad_listen_t *listener,
770 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
774 RADIUS_PACKET *packet;
775 RAD_REQUEST_FUNP fun = NULL;
777 fr_ipaddr_t src_ipaddr;
779 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
780 if (rcode < 0) return 0;
782 RAD_STATS_TYPE_INC(listener, total_requests);
784 if (rcode < 20) { /* AUTH_HDR_LEN */
785 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
789 if ((client = client_listener_find(listener,
790 &src_ipaddr, src_port)) == NULL) {
791 rad_recv_discard(listener->fd);
792 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
797 * Some sanity checks, based on the packet code.
800 case PW_AUTHENTICATION_REQUEST:
801 RAD_STATS_CLIENT_INC(listener, client, total_requests);
802 fun = rad_authenticate;
805 case PW_STATUS_SERVER:
806 if (!mainconfig.status_server) {
807 rad_recv_discard(listener->fd);
808 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
809 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
810 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
813 fun = rad_status_server;
817 rad_recv_discard(listener->fd);
818 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
819 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
821 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
822 code, client->shortname, src_port);
825 } /* switch over packet types */
828 * Now that we've sanity checked everything, receive the
831 packet = rad_recv(listener->fd, client->message_authenticator);
833 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
834 DEBUG("%s", fr_strerror());
838 if (!received_request(listener, packet, prequest, client)) {
839 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
840 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
850 #ifdef WITH_ACCOUNTING
852 * Receive packets from an accounting socket
854 static int acct_socket_recv(rad_listen_t *listener,
855 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
859 RADIUS_PACKET *packet;
860 RAD_REQUEST_FUNP fun = NULL;
862 fr_ipaddr_t src_ipaddr;
864 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
865 if (rcode < 0) return 0;
867 RAD_STATS_TYPE_INC(listener, total_requests);
869 if (rcode < 20) { /* AUTH_HDR_LEN */
870 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
874 if ((client = client_listener_find(listener,
875 &src_ipaddr, src_port)) == NULL) {
876 rad_recv_discard(listener->fd);
877 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
882 * Some sanity checks, based on the packet code.
885 case PW_ACCOUNTING_REQUEST:
886 RAD_STATS_CLIENT_INC(listener, client, total_requests);
887 fun = rad_accounting;
890 case PW_STATUS_SERVER:
891 if (!mainconfig.status_server) {
892 rad_recv_discard(listener->fd);
893 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
894 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
896 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
899 fun = rad_status_server;
903 rad_recv_discard(listener->fd);
904 RAD_STATS_TYPE_INC(listener, total_unknown_types);
905 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
907 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
908 code, client->shortname, src_port);
910 } /* switch over packet types */
913 * Now that we've sanity checked everything, receive the
916 packet = rad_recv(listener->fd, 0);
918 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
919 radlog(L_ERR, "%s", fr_strerror());
924 * There can be no duplicate accounting packets.
926 if (!received_request(listener, packet, prequest, client)) {
927 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
928 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
941 * For now, all CoA requests are *only* originated, and not
942 * proxied. So all of the necessary work is done in the
943 * post-proxy section, which is automatically handled by event.c.
944 * As a result, we don't have to do anything here.
946 static int rad_coa_reply(REQUEST *request)
951 * Inform the user about RFC requirements.
953 s1 = pairfind(request->proxy->vps, PW_STATE);
955 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
958 DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
960 } else if ((s1->length != s2->length) ||
961 (memcmp(s1->vp_octets, s2->vp_octets,
963 DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
967 return RLM_MODULE_OK;
971 * Receive a CoA packet.
973 static int rad_coa_recv(REQUEST *request)
975 int rcode = RLM_MODULE_OK;
980 * Get the correct response
982 switch (request->packet->code) {
988 case PW_DISCONNECT_REQUEST:
989 ack = PW_DISCONNECT_ACK;
990 nak = PW_DISCONNECT_NAK;
993 default: /* shouldn't happen */
994 return RLM_MODULE_FAIL;
998 #define WAS_PROXIED (request->proxy)
1000 #define WAS_PROXIED (0)
1005 * RFC 5176 Section 3.3. If we have a CoA-Request
1006 * with Service-Type = Authorize-Only, it MUST
1007 * have a State attribute in it.
1009 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE);
1010 if (request->packet->code == PW_COA_REQUEST) {
1011 if (vp && (vp->vp_integer == 17)) {
1012 vp = pairfind(request->packet->vps, PW_STATE);
1013 if (!vp || (vp->length == 0)) {
1014 RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1015 request->reply->code = PW_COA_NAK;
1016 return RLM_MODULE_FAIL;
1021 * RFC 5176, Section 3.2.
1023 RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1024 request->reply->code = PW_DISCONNECT_NAK;
1025 return RLM_MODULE_FAIL;
1028 rcode = module_recv_coa(0, request);
1030 case RLM_MODULE_FAIL:
1031 case RLM_MODULE_INVALID:
1032 case RLM_MODULE_REJECT:
1033 case RLM_MODULE_USERLOCK:
1035 request->reply->code = nak;
1038 case RLM_MODULE_HANDLED:
1041 case RLM_MODULE_NOOP:
1042 case RLM_MODULE_NOTFOUND:
1044 case RLM_MODULE_UPDATED:
1045 request->reply->code = ack;
1050 * Start the reply code with the proxy reply
1053 request->reply->code = request->proxy_reply->code;
1057 * Copy State from the request to the reply.
1058 * See RFC 5176 Section 3.3.
1060 vp = paircopy2(request->packet->vps, PW_STATE);
1061 if (vp) pairadd(&request->reply->vps, vp);
1064 * We may want to over-ride the reply.
1066 rcode = module_send_coa(0, request);
1069 * We need to send CoA-NAK back if Service-Type
1070 * is Authorize-Only. Rely on the user's policy
1071 * to do that. We're not a real NAS, so this
1072 * restriction doesn't (ahem) apply to us.
1074 case RLM_MODULE_FAIL:
1075 case RLM_MODULE_INVALID:
1076 case RLM_MODULE_REJECT:
1077 case RLM_MODULE_USERLOCK:
1079 request->reply->code = nak;
1082 case RLM_MODULE_HANDLED:
1085 case RLM_MODULE_NOOP:
1086 case RLM_MODULE_NOTFOUND:
1088 case RLM_MODULE_UPDATED:
1089 request->reply->code = ack;
1094 return RLM_MODULE_OK;
1099 * Check if an incoming request is "ok"
1101 * It takes packets, not requests. It sees if the packet looks
1102 * OK. If so, it does a number of sanity checks on it.
1104 static int coa_socket_recv(rad_listen_t *listener,
1105 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1109 RADIUS_PACKET *packet;
1110 RAD_REQUEST_FUNP fun = NULL;
1113 fr_ipaddr_t src_ipaddr;
1115 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1116 if (rcode < 0) return 0;
1118 RAD_STATS_TYPE_INC(listener, total_requests);
1120 if (rcode < 20) { /* AUTH_HDR_LEN */
1121 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1125 if ((client = client_listener_find(listener,
1126 &src_ipaddr, src_port)) == NULL) {
1127 rad_recv_discard(listener->fd);
1128 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1130 if (debug_flag > 0) {
1133 listener->print(listener, name, sizeof(name));
1136 * This is debugging rather than logging, so that
1137 * DoS attacks don't affect us.
1139 DEBUG("Ignoring request to %s from unknown client %s port %d",
1141 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
1142 buffer, sizeof(buffer)), src_port);
1149 * Some sanity checks, based on the packet code.
1152 case PW_COA_REQUEST:
1153 case PW_DISCONNECT_REQUEST:
1158 rad_recv_discard(listener->fd);
1159 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1160 code, client->shortname, src_port);
1163 } /* switch over packet types */
1166 * Now that we've sanity checked everything, receive the
1169 packet = rad_recv(listener->fd, client->message_authenticator);
1171 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1172 DEBUG("%s", fr_strerror());
1176 if (!received_request(listener, packet, prequest, client)) {
1188 * Recieve packets from a proxy socket.
1190 static int proxy_socket_recv(rad_listen_t *listener,
1191 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1194 RADIUS_PACKET *packet;
1195 RAD_REQUEST_FUNP fun = NULL;
1198 packet = rad_recv(listener->fd, 0);
1200 radlog(L_ERR, "%s", fr_strerror());
1205 * FIXME: Client MIB updates?
1207 switch(packet->code) {
1208 case PW_AUTHENTICATION_ACK:
1209 case PW_ACCESS_CHALLENGE:
1210 case PW_AUTHENTICATION_REJECT:
1211 fun = rad_authenticate;
1214 #ifdef WITH_ACCOUNTING
1215 case PW_ACCOUNTING_RESPONSE:
1216 fun = rad_accounting;
1221 case PW_DISCONNECT_ACK:
1222 case PW_DISCONNECT_NAK:
1225 fun = rad_coa_reply;
1231 * FIXME: Update MIB for packet types?
1233 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1234 "from home server %s port %d - ID %d : IGNORED",
1236 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1237 packet->src_port, packet->id);
1242 request = received_proxy_response(packet);
1250 * Distinguish proxied CoA requests from ones we
1253 if ((fun == rad_coa_reply) &&
1254 (request->packet->code == request->proxy->code)) {
1259 rad_assert(fun != NULL);
1261 *prequest = request;
1268 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1270 if (!request->reply->code) return 0;
1272 rad_encode(request->reply, request->packet,
1273 request->client->secret);
1274 rad_sign(request->reply, request->packet,
1275 request->client->secret);
1281 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1283 if (rad_verify(request->packet, NULL,
1284 request->client->secret) < 0) {
1288 return rad_decode(request->packet, NULL,
1289 request->client->secret);
1293 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1295 rad_encode(request->proxy, NULL, request->home_server->secret);
1296 rad_sign(request->proxy, NULL, request->home_server->secret);
1302 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1305 * rad_verify is run in event.c, received_proxy_response()
1308 return rad_decode(request->proxy_reply, request->proxy,
1309 request->home_server->secret);
1315 #include "command.c"
1317 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1319 { common_socket_parse, NULL,
1320 stats_socket_recv, auth_socket_send,
1321 socket_print, client_socket_encode, client_socket_decode },
1324 * This always gets defined.
1326 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1331 { common_socket_parse, NULL,
1332 proxy_socket_recv, proxy_socket_send,
1333 socket_print, proxy_socket_encode, proxy_socket_decode },
1336 /* authentication */
1337 { common_socket_parse, NULL,
1338 auth_socket_recv, auth_socket_send,
1339 socket_print, client_socket_encode, client_socket_decode },
1341 #ifdef WITH_ACCOUNTING
1343 { common_socket_parse, NULL,
1344 acct_socket_recv, acct_socket_send,
1345 socket_print, client_socket_encode, client_socket_decode},
1350 { detail_parse, detail_free,
1351 detail_recv, detail_send,
1352 detail_print, detail_encode, detail_decode },
1356 /* vlan query protocol */
1357 { common_socket_parse, NULL,
1358 vqp_socket_recv, vqp_socket_send,
1359 socket_print, vqp_socket_encode, vqp_socket_decode },
1363 /* dhcp query protocol */
1364 { dhcp_socket_parse, NULL,
1365 dhcp_socket_recv, dhcp_socket_send,
1366 socket_print, dhcp_socket_encode, dhcp_socket_decode },
1369 #ifdef WITH_COMMAND_SOCKET
1370 /* TCP command socket */
1371 { command_socket_parse, NULL,
1372 command_domain_accept, command_domain_send,
1373 command_socket_print, command_socket_encode, command_socket_decode },
1377 /* Change of Authorization */
1378 { common_socket_parse, NULL,
1379 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1380 socket_print, client_socket_encode, client_socket_decode },
1388 * Binds a listener to a socket.
1390 static int listen_bind(rad_listen_t *this)
1393 struct sockaddr_storage salocal;
1395 listen_socket_t *sock = this->data;
1398 * If the port is zero, then it means the appropriate
1399 * thing from /etc/services.
1401 if (sock->port == 0) {
1402 struct servent *svp;
1404 switch (this->type) {
1405 case RAD_LISTEN_AUTH:
1406 svp = getservbyname ("radius", "udp");
1408 sock->port = ntohs(svp->s_port);
1410 sock->port = PW_AUTH_UDP_PORT;
1414 #ifdef WITH_ACCOUNTING
1415 case RAD_LISTEN_ACCT:
1416 svp = getservbyname ("radacct", "udp");
1418 sock->port = ntohs(svp->s_port);
1420 sock->port = PW_ACCT_UDP_PORT;
1426 case RAD_LISTEN_PROXY:
1432 case RAD_LISTEN_VQP:
1438 case RAD_LISTEN_COA:
1439 sock->port = PW_COA_UDP_PORT;
1444 radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");
1450 * Copy fr_socket() here, as we may need to bind to a device.
1452 this->fd = socket(sock->ipaddr.af, SOCK_DGRAM, 0);
1454 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1458 #ifdef SO_BINDTODEVICE
1460 * Bind to a device BEFORE touching IP addresses.
1462 if (sock->interface) {
1464 strcpy(ifreq.ifr_name, sock->interface);
1467 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1468 (char *)&ifreq, sizeof(ifreq));
1472 radlog(L_ERR, "Failed binding to interface %s: %s",
1473 sock->interface, strerror(errno));
1475 } /* else it worked. */
1479 #ifdef WITH_UDPFROMTO
1481 * Initialize udpfromto for all sockets.
1483 if (udpfromto_init(this->fd) != 0) {
1490 * Set up sockaddr stuff.
1492 if (!fr_ipaddr2sockaddr(&sock->ipaddr, sock->port, &salocal, &salen)) {
1497 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1498 if (sock->ipaddr.af == AF_INET6) {
1500 * Listening on '::' does NOT get you IPv4 to
1501 * IPv6 mapping. You've got to listen on an IPv4
1502 * address, too. This makes the rest of the server
1503 * design a little simpler.
1507 if (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr)) {
1510 setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
1511 (char *)&on, sizeof(on));
1513 #endif /* IPV6_V6ONLY */
1515 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
1518 * May be binding to priviledged ports.
1521 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
1525 radlog(L_ERR, "Failed binding to socket: %s\n",
1531 * FreeBSD jail issues. We bind to 0.0.0.0, but the
1532 * kernel instead binds us to a 1.2.3.4. If this
1533 * happens, notice, and remember our real IP.
1536 struct sockaddr_storage src;
1537 socklen_t sizeof_src = sizeof(src);
1539 memset(&src, 0, sizeof_src);
1540 if (getsockname(this->fd, (struct sockaddr *) &src,
1542 radlog(L_ERR, "Failed getting socket name: %s",
1547 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
1548 &sock->ipaddr, &sock->port)) {
1549 radlog(L_ERR, "Socket has unsupported address family");
1558 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1559 radlog(L_ERR, "Failure getting socket flags: %s)\n",
1564 flags |= O_NONBLOCK;
1565 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1566 radlog(L_ERR, "Failure setting socket flags: %s)\n",
1578 * Allocate & initialize a new listener.
1580 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1584 this = rad_malloc(sizeof(*this));
1585 memset(this, 0, sizeof(*this));
1588 this->recv = master_listen[this->type].recv;
1589 this->send = master_listen[this->type].send;
1590 this->print = master_listen[this->type].print;
1591 this->encode = master_listen[this->type].encode;
1592 this->decode = master_listen[this->type].decode;
1596 case RAD_LISTEN_NONE:
1598 case RAD_LISTEN_AUTH:
1599 #ifdef WITH_ACCOUNTING
1600 case RAD_LISTEN_ACCT:
1603 case RAD_LISTEN_PROXY:
1606 case RAD_LISTEN_VQP:
1609 case RAD_LISTEN_DHCP:
1612 case RAD_LISTEN_COA:
1614 this->data = rad_malloc(sizeof(listen_socket_t));
1615 memset(this->data, 0, sizeof(listen_socket_t));
1619 case RAD_LISTEN_DETAIL:
1624 #ifdef WITH_COMMAND_SOCKET
1625 case RAD_LISTEN_COMMAND:
1626 this->data = rad_malloc(sizeof(fr_command_socket_t));
1627 memset(this->data, 0, sizeof(fr_command_socket_t));
1632 rad_assert("Unsupported option!" == NULL);
1642 * Externally visible function for creating a new proxy LISTENER.
1644 * For now, don't take ipaddr or port.
1646 * Not thread-safe, but all calls to it are protected by the
1647 * proxy mutex in request_list.c
1649 rad_listen_t *proxy_new_listener()
1651 int last_proxy_port, port;
1652 rad_listen_t *this, *tmp, **last;
1653 listen_socket_t *sock, *old;
1655 this = listen_alloc(RAD_LISTEN_PROXY);
1658 * Find an existing proxy socket to copy.
1660 * FIXME: Make it per-realm, or per-home server!
1662 last_proxy_port = 0;
1664 last = &mainconfig.listen;
1665 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1666 if (tmp->type == RAD_LISTEN_PROXY) {
1668 if (sock->port > last_proxy_port) {
1669 last_proxy_port = sock->port + 1;
1671 if (!old) old = sock;
1674 last = &(tmp->next);
1679 return NULL; /* This is a serious error. */
1683 * FIXME: find a new IP address to listen on?
1685 * This could likely be done in the "home server"
1686 * configuration, to have per-home-server source IP's.
1689 memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1692 * Keep going until we find an unused port.
1694 for (port = last_proxy_port; port < 64000; port++) {
1696 if (listen_bind(this) == 0) {
1698 * Add the new listener to the list of
1711 static const FR_NAME_NUMBER listen_compare[] = {
1713 { "status", RAD_LISTEN_NONE },
1715 { "auth", RAD_LISTEN_AUTH },
1716 #ifdef WITH_ACCOUNTING
1717 { "acct", RAD_LISTEN_ACCT },
1720 { "detail", RAD_LISTEN_DETAIL },
1723 { "proxy", RAD_LISTEN_PROXY },
1726 { "vmps", RAD_LISTEN_VQP },
1729 { "dhcp", RAD_LISTEN_DHCP },
1731 #ifdef WITH_COMMAND_SOCKET
1732 { "control", RAD_LISTEN_COMMAND },
1735 { "coa", RAD_LISTEN_COA },
1741 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1749 cf_log_info(cs, "listen {");
1751 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1753 if (rcode < 0) return NULL;
1756 cf_log_err(cf_sectiontoitem(cs),
1757 "No type specified in listen section");
1761 type = fr_str2int(listen_compare, listen_type, -1);
1763 cf_log_err(cf_sectiontoitem(cs),
1764 "Invalid type \"%s\" in listen section.",
1772 * Allow listen sections in the default config to
1773 * refer to a server.
1776 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
1778 if (rcode == 1) { /* compatiblity with 2.0-pre */
1779 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1782 if (rcode < 0) return NULL;
1786 * Set up cross-type data.
1788 this = listen_alloc(type);
1789 this->server = server;
1793 * Call per-type parser.
1795 if (master_listen[type].parse(cs, this) < 0) {
1800 cf_log_info(cs, "}");
1806 * Generate a list of listeners. Takes an input list of
1807 * listeners, too, so we don't close sockets with waiting packets.
1809 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1811 int override = FALSE;
1813 CONF_SECTION *cs = NULL;
1814 rad_listen_t **last;
1816 fr_ipaddr_t server_ipaddr;
1819 int defined_proxy = 0;
1823 * We shouldn't be called with a pre-existing list.
1825 rad_assert(head && (*head == NULL));
1828 server_ipaddr.af = AF_UNSPEC;
1831 * If the port is specified on the command-line,
1832 * it over-rides the configuration file.
1834 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1836 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1839 * If the IP address was configured on the command-line,
1840 * use that as the "bind_address"
1842 if (mainconfig.myip.af != AF_UNSPEC) {
1843 memcpy(&server_ipaddr, &mainconfig.myip,
1844 sizeof(server_ipaddr));
1850 * Else look for bind_address and/or listen sections.
1852 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1853 rcode = cf_item_parse(config, "bind_address",
1855 &server_ipaddr.ipaddr.ip4addr, NULL);
1856 if (rcode < 0) return -1; /* error parsing it */
1858 if (rcode == 0) { /* successfully parsed IPv4 */
1859 listen_socket_t *sock;
1860 server_ipaddr.af = AF_INET;
1862 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1866 if (strcmp(progname, "vmpsd") == 0) {
1867 this = listen_alloc(RAD_LISTEN_VQP);
1868 if (!auth_port) auth_port = 1589;
1871 this = listen_alloc(RAD_LISTEN_AUTH);
1875 sock->ipaddr = server_ipaddr;
1876 sock->port = auth_port;
1878 sock->clients = clients_parse_section(config);
1879 if (!sock->clients) {
1880 cf_log_err(cf_sectiontoitem(config),
1881 "Failed to find any clients for this listen section");
1886 if (listen_bind(this) < 0) {
1888 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1892 auth_port = sock->port; /* may have been updated in listen_bind */
1894 cs = cf_section_sub_find_name2(config, "server",
1896 if (cs) this->server = mainconfig.name;
1900 last = &(this->next);
1906 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1909 #ifdef WITH_ACCOUNTING
1911 * Open Accounting Socket.
1913 * If we haven't already gotten acct_port from
1914 * /etc/services, then make it auth_port + 1.
1916 this = listen_alloc(RAD_LISTEN_ACCT);
1920 * Create the accounting socket.
1922 * The accounting port is always the
1923 * authentication port + 1
1925 sock->ipaddr = server_ipaddr;
1926 sock->port = auth_port + 1;
1928 sock->clients = clients_parse_section(config);
1929 if (!sock->clients) {
1930 cf_log_err(cf_sectiontoitem(config),
1931 "Failed to find any clients for this listen section");
1935 if (listen_bind(this) < 0) {
1938 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1943 cs = cf_section_sub_find_name2(config, "server",
1945 if (cs) this->server = mainconfig.name;
1949 last = &(this->next);
1951 } else if (mainconfig.port > 0) { /* no bind address, but a port */
1952 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1958 * They specified an IP on the command-line, ignore
1959 * all listen sections except the one in '-n'.
1961 if (mainconfig.myip.af != AF_UNSPEC) {
1962 CONF_SECTION *subcs;
1963 const char *name2 = cf_section_name2(cs);
1965 cs = cf_section_sub_find_name2(config, "server",
1967 if (!cs) goto do_proxy;
1970 * Should really abstract this code...
1972 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
1974 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
1975 this = listen_parse(subcs, name2);
1982 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
1986 last = &(this->next);
1987 } /* loop over "listen" directives in server <foo> */
1993 * Walk through the "listen" sections, if they exist.
1995 for (cs = cf_subsection_find_next(config, NULL, "listen");
1997 cs = cf_subsection_find_next(config, cs, "listen")) {
1998 this = listen_parse(cs, NULL);
2005 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2009 last = &(this->next);
2013 * Check virtual servers for "listen" sections, too.
2015 * FIXME: Move to virtual server init?
2017 for (cs = cf_subsection_find_next(config, NULL, "server");
2019 cs = cf_subsection_find_next(config, cs, "server")) {
2020 CONF_SECTION *subcs;
2021 const char *name2 = cf_section_name2(cs);
2023 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2025 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2026 this = listen_parse(subcs, name2);
2033 if (this->type == RAD_LISTEN_PROXY) {
2034 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2041 last = &(this->next);
2042 } /* loop over "listen" directives in virtual servers */
2043 } /* loop over virtual servers */
2046 * If we're proxying requests, open the proxy FD.
2047 * Otherwise, don't do anything.
2051 if (mainconfig.proxy_requests == TRUE) {
2053 listen_socket_t *sock = NULL;
2056 * No sockets to receive packets, therefore
2057 * proxying is pointless.
2059 if (!*head) return -1;
2061 if (defined_proxy) goto done;
2064 * Find the first authentication port,
2067 for (this = *head; this != NULL; this = this->next) {
2068 if (this->type == RAD_LISTEN_AUTH) {
2070 if (server_ipaddr.af == AF_UNSPEC) {
2071 server_ipaddr = sock->ipaddr;
2073 port = sock->port + 2; /* skip acct port */
2077 if (this->type == RAD_LISTEN_VQP) {
2079 if (server_ipaddr.af == AF_UNSPEC) {
2080 server_ipaddr = sock->ipaddr;
2082 port = sock->port + 1;
2088 if (port < 0) port = 1024 + (fr_rand() & 0x1ff);
2091 * Address is still unspecified, use IPv4.
2093 if (server_ipaddr.af == AF_UNSPEC) {
2094 server_ipaddr.af = AF_INET;
2095 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2098 this = listen_alloc(RAD_LISTEN_PROXY);
2102 * Create the first proxy socket.
2104 sock->ipaddr = server_ipaddr;
2107 * Try to find a proxy port (value doesn't matter)
2109 for (sock->port = port;
2112 if (listen_bind(this) == 0) {
2114 last = &(this->next); /* just in case */
2119 if (sock->port >= 64000) {
2122 radlog(L_ERR, "Failed to open socket for proxying");
2127 done: /* used only in proxy code. */
2134 * Free a linked list of listeners;
2136 void listen_free(rad_listen_t **head)
2140 if (!head || !*head) return;
2144 rad_listen_t *next = this->next;
2147 * Other code may have eaten the FD.
2149 if (this->fd >= 0) close(this->fd);
2151 if (master_listen[this->type].free) {
2152 master_listen[this->type].free(this);
2164 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2169 for (this = mainconfig.listen; this != NULL; this = this->next) {
2170 listen_socket_t *sock;
2172 if ((this->type != RAD_LISTEN_AUTH) &&
2173 (this->type != RAD_LISTEN_ACCT)) continue;
2177 if ((sock->port == port) &&
2178 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2179 return sock->clients;
2187 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2191 for (this = mainconfig.listen; this != NULL; this = this->next) {
2192 listen_socket_t *sock;
2195 * FIXME: For TCP, ignore the *secondary*
2196 * listeners associated with the main socket.
2198 if ((this->type != RAD_LISTEN_AUTH) &&
2199 (this->type != RAD_LISTEN_ACCT)) continue;
2203 if ((sock->port == port) &&
2204 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2208 if ((sock->port == port) &&
2209 ((sock->ipaddr.af == AF_INET) &&
2210 (sock->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY))) {
2214 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2215 if ((sock->port == port) &&
2216 (sock->ipaddr.af == AF_INET6) &&
2217 (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr))) {