18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS authentication server 3bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt * Copyright (c) 2005-2009, 2011-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <net/if.h> 11818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 12818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#include <sqlite3.h> 13818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h" 19818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#include "ap/ap_config.h" 20818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#include "crypto/tls.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius_server.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS_SESSION_TIMEOUT - Session timeout in seconds 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_SESSION_TIMEOUT 60 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 29293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * RADIUS_SESSION_MAINTAIN - Completed session expiration timeout in seconds 30293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt */ 31293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#define RADIUS_SESSION_MAINTAIN 5 32293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 33293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt/** 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS_MAX_SESSION - Maximum number of active sessions 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 36293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#define RADIUS_MAX_SESSION 1000 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_MAX_MSG_LEN 3000 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 431d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct eapol_callbacks radius_server_eapol_cb; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_client; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_server_counters - RADIUS server statistics counters 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_counters { 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_requests; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 invalid_requests; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 dup_access_requests; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_accepts; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_rejects; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_challenges; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 malformed_access_requests; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 bad_authenticators; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 packets_dropped; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 unknown_types; 62bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 63bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_requests; 64bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 invalid_acct_requests; 65bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_responses; 66bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 malformed_acct_requests; 67bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_bad_authenticators; 68bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 unknown_acct_types; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_session - Internal RADIUS server data for a session 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_session { 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *next; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *server; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int sess_id; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *eap; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_eapol_interface *eap_if; 81818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *username; /* from User-Name attribute */ 82818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *nas_ip; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *last_msg; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *last_from_addr; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int last_from_port; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_storage last_from; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t last_fromlen; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_identifier; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *last_reply; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_authenticator[16]; 92f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 93f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unsigned int remediation:1; 94df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt unsigned int macacl:1; 95818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 96818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct hostapd_radius_attr *accept_attr; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_client - Internal RADIUS server data for a client 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_client { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *next; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr addr; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr mask; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr addr6; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr mask6; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *shared_secret; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int shared_secret_len; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sessions; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_counters counters; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_server_data - Internal RADIUS server data 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * auth_sock - Socket for RADIUS authentication messages 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auth_sock; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 126bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt * acct_sock - Socket for RADIUS accounting messages 127bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt */ 128bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int acct_sock; 129bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 130bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt /** 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * clients - List of authorized RADIUS clients 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * next_sess_id - Next session identifier 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int next_sess_id; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * conf_ctx - Context pointer for callbacks 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is used as the ctx argument in get_eap_user() calls. 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *conf_ctx; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * num_sess - Number of active sessions 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_sess; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_priv - EAP-SIM/AKA database context 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is passed to the EAP-SIM/AKA server implementation as a 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * callback context. 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eap_sim_db_priv; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ssl_ctx - TLS context 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is passed to the EAP server implementation as a callback 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context for TLS operations. 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ssl_ctx; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This parameter is used to set a key for EAP-FAST to encrypt the 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * set, must point to a 16-octet key. 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pac_opaque_encr_key; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id - EAP-FAST authority identity (A-ID) 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If EAP-FAST is not used, this can be set to %NULL. In theory, this 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is a variable length field, but due to some existing implementations 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requiring A-ID to be 16 octets in length, it is recommended to use 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that length for the field to provide interoperability with deployed 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer implementations. 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *eap_fast_a_id; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_fast_a_id_len; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id_info - EAP-FAST authority identifier information 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This A-ID-Info contains a user-friendly name for the A-ID. For 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * example, this could be the enterprise and server names in 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * human-readable format. This field is encoded as UTF-8. If EAP-FAST 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is not used, this can be set to %NULL. 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *eap_fast_a_id_info; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_prov - EAP-FAST provisioning modes 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 0 = provisioning disabled, 1 = only anonymous provisioning allowed, 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2 = only authenticated provisioning allowed, 3 = both provisioning 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modes allowed. 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_fast_prov; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is the hard limit on how long a provisioned PAC-Key can be 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used. 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pac_key_lifetime; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is a soft limit on the PAC-Key. The server will automatically 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * generate a new PAC-Key when this number of seconds (or fewer) of the 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * lifetime remains. 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pac_key_refresh_time; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This controls whether the protected success/failure indication 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA. 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_sim_aka_result_ind; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tnc - Trusted Network Connect (TNC) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This controls whether TNC is enabled and will be required before the 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer is allowed to connect. Note: This is only used with EAP-TTLS 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and EAP-FAST. If any other EAP method is enabled, the peer will be 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allowed to connect without TNC. 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pwd_group - The D-H group assigned for EAP-pwd 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If EAP-pwd is not used it can be set to zero. 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 pwd_group; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 25534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt * server_id - Server identity 25634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt */ 25734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt const char *server_id; 25834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 25934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /** 2606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * erp - Whether EAP Re-authentication Protocol (ERP) is enabled 2616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * 2626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * This controls whether the authentication server derives ERP key 2636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * hierarchy (rRK and rIK) from full EAP authentication and allows 2646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * these keys to be used to perform ERP to derive rMSK instead of full 2656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * EAP authentication to derive MSK. 2666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 2676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int erp; 2686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *erp_domain; 2706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct dl_list erp_keys; /* struct eap_server_erp_key */ 2726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int tls_session_lifetime; 274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /** 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wps - Wi-Fi Protected Setup context 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If WPS is used with an external RADIUS server (which is quite 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unlikely configuration), this is used to provide a pointer to WPS 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data. Normally, this can be set to %NULL. 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_context *wps; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ipv6 - Whether to enable IPv6 support in the RADIUS server 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ipv6; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * start_time - Timestamp of server start 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 292fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime start_time; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * counters - Statistics counters for server operations 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These counters are the sum over all clients. 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_counters counters; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * get_eap_user - Callback for fetching EAP user information 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data from conf_ctx 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity: User identity 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: identity buffer length in octets 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @phase2: Whether this is for Phase 2 identity 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @user: Data structure for filling in the user information 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is used to fetch information from user database. The callback 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will fill in information about allowed EAP methods and the user 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * password. The password field will be an allocated copy of the 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * password data and RADIUS server will free it after use. 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int phase2, struct eap_user *user); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text - Optional data for EAP-Request/Identity 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to configure an optional, displayable message that 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be sent in EAP-Request/Identity. This string can contain an 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASCII-0 character (nul) to separate network infromation per RFC 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4284. The actual string length is explicit provided in 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text_len since nul character will not be used as a string 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * terminator. 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *eap_req_id_text; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text_len - Length of eap_req_id_text buffer in octets 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_req_id_text_len; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * msg_ctx - Context data for wpa_msg() calls 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *msg_ctx; 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *dump_msk_file; 3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 343f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 344f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char *subscr_remediation_url; 345f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 subscr_remediation_method; 346818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 347818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 348818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3 *db; 349818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DEBUG(args...) \ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_printf(MSG_DEBUG, "RADIUS SRV: " args) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_ERROR(args...) \ 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_printf(MSG_ERROR, "RADIUS SRV: " args) 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DUMP(args...) \ 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DUMP_ASCII(args...) \ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove_timeout(void *eloop_ctx, 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 367818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid srv_log(struct radius_session *sess, const char *fmt, ...) 368818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry ShmidtPRINTF_FORMAT(2, 3); 369818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 370818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid srv_log(struct radius_session *sess, const char *fmt, ...) 371818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 372818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_list ap; 373818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *buf; 374818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int buflen; 375818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 376818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_start(ap, fmt); 377818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 378818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_end(ap); 379818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 380818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt buf = os_malloc(buflen); 381818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (buf == NULL) 382818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return; 383818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_start(ap, fmt); 384818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt vsnprintf(buf, buflen, fmt, ap); 385818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_end(ap); 386818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 387818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf); 388818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 389818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 390818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->server->db) { 391818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *sql; 392818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sql = sqlite3_mprintf("INSERT INTO authlog" 393818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "(timestamp,session,nas_ip,username,note)" 394818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt " VALUES (" 395818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "strftime('%%Y-%%m-%%d %%H:%%M:%%f'," 396818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "'now'),%u,%Q,%Q,%Q)", 397818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->sess_id, sess->nas_ip, 398818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->username, buf); 399818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sql) { 400818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sqlite3_exec(sess->server->db, sql, NULL, NULL, 401818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt NULL) != SQLITE_OK) { 402818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s", 403818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_errmsg(sess->server->db)); 404818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 405818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_free(sql); 406818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 407818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 408818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 409818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 410818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(buf); 411818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 412818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_client * 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_client(struct radius_server_data *data, struct in_addr *addr, 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ipv6) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = data->clients; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (client) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6) { 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr *addr6; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6 = (struct in6_addr *) addr; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 16; i++) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((addr6->s6_addr[i] & 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->mask6.s6_addr[i]) != 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (client->addr6.s6_addr[i] & 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->mask6.s6_addr[i])) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = 17; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == 16) { 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) == 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (addr->s_addr & client->mask.s_addr)) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = client->next; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return client; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_session(struct radius_client *client, unsigned int sess_id) 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = client->sessions; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (sess) { 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->sess_id == sess_id) { 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = sess->next; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_free(struct radius_server_data *data, 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess) 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_timeout, data, sess); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_sm_deinit(sess->eap); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_msg); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess->last_from_addr); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_reply); 478818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(sess->username); 479818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(sess->nas_ip); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->num_sess--; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove(struct radius_server_data *data, 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess) 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = sess->client; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *session, *prev; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = client->sessions; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (session) { 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (session == sess) { 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->sessions = sess->next; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = sess->next; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, sess); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = session; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = session->next; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove_timeout(void *eloop_ctx, 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx) 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = timeout_ctx; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove(data, sess); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx) 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = timeout_ctx; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove(data, sess); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_new_session(struct radius_server_data *data, 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client) 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->num_sess >= RADIUS_MAX_SESSION) { 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Maximum number of existing session - no room " 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for a new session"); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = os_zalloc(sizeof(*sess)); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->server = data; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->client = client; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->sess_id = data->next_sess_id++; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->next = client->sessions; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->sessions = sess; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0, 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_timeout, data, sess); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->num_sess++; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 559818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 560818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_testing_options_tls(struct radius_session *sess, 561818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const char *tls, 562818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_config *eap_conf) 563818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 564818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int test = atoi(tls); 565818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 566818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt switch (test) { 567818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 1: 568818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break VerifyData"); 569818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA; 570818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 571818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 2: 572818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash"); 573818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH; 574818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 575818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 3: 576818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature"); 577818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE; 578818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 579b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 4: 580b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime"); 581b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_511B; 582b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 583b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 5: 584b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime"); 585b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_767B; 586b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 587b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 6: 588b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\""); 589b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_15; 590b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 591b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 7: 592b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container"); 593b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_58B; 594b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 595b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 8: 596b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a non-prime"); 597b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_NON_PRIME; 598b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 599818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt default: 600818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Unrecognized TLS test"); 601818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 602818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 603818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 604818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 605818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 606818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_testing_options(struct radius_session *sess, 607818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_config *eap_conf) 608818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 609818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 610818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const char *pos; 611818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 612818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos = os_strstr(sess->username, "@test-"); 613818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (pos == NULL) 614818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return; 615818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 6; 616818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (os_strncmp(pos, "tls-", 4) == 0) 617818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_testing_options_tls(sess, pos + 4, eap_conf); 618818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt else 619818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Unrecognized test: %s", pos); 620818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 621818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 622818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 623818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_new_session(struct radius_server_data *data, 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 627818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct radius_msg *msg, const char *from_addr) 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *user; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t user_len; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_config eap_conf; 634818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_user tmp; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Creating a new session"); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user, 639818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt &user_len, NULL) < 0) { 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Could not get User-Name"); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP_ASCII("User-Name", user, user_len); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 645818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_memset(&tmp, 0, sizeof(tmp)); 646818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp); 647c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 649818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (res != 0) { 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("User-Name not found from user database"); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 654818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("Matching user entry found"); 655818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess = radius_server_new_session(data, client); 656818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess == NULL) { 657818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("Failed to create a new session"); 658818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 659818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 660818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->accept_attr = tmp.accept_attr; 661df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt sess->macacl = tmp.macacl; 662818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 663b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt sess->username = os_malloc(user_len * 4 + 1); 664818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->username == NULL) { 665818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_session_free(data, sess); 666818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 667818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 668b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt printf_encode(sess->username, user_len * 4 + 1, user, user_len); 669818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 670818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->nas_ip = os_strdup(from_addr); 671818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->nas_ip == NULL) { 672818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_session_free(data, sess); 673818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 674818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 675818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 676818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "New session created"); 677818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eap_conf, 0, sizeof(eap_conf)); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.ssl_ctx = data->ssl_ctx; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.msg_ctx = data->msg_ctx; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_sim_db_priv = data->eap_sim_db_priv; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.backend_auth = TRUE; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_server = 1; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id = data->eap_fast_a_id; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_prov = data->eap_fast_prov; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_key_lifetime = data->pac_key_lifetime; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_key_refresh_time = data->pac_key_refresh_time; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.tnc = data->tnc; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.wps = data->wps; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pwd_group = data->pwd_group; 69534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eap_conf.server_id = (const u8 *) data->server_id; 69634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eap_conf.server_id_len = os_strlen(data->server_id); 6976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt eap_conf.erp = data->erp; 698d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_conf.tls_session_lifetime = data->tls_session_lifetime; 699818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_testing_options(sess, &eap_conf); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb, 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &eap_conf); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap == NULL) { 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to initialize EAP state machine for the " 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "new session"); 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, sess); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if = eap_get_interface(sess->eap); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapRestart = TRUE; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->portEnabled = TRUE; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_msg * 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_encapsulate_eap(struct radius_server_data *data, 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess, 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *request) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int code; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int sess_id; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapFail) { 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapFail = FALSE; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sess->eap_if->eapSuccess) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapSuccess = FALSE; 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_ACCEPT; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapReq = FALSE; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_CHALLENGE; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(code, hdr->identifier); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to allocate reply message"); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess_id = htonl(sess->sess_id); 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_CHALLENGE && 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &sess_id, sizeof(sess_id))) { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add State attribute"); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapReqData && 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(sess->eap_if->eapReqData))) { 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add EAP-Message attribute"); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (data->dump_msk_file) { 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FILE *f; 7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char buf[2 * 64 + 1]; 7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt f = fopen(data->dump_msk_file, "a"); 7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (f) { 7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = sess->eap_if->eapKeyDataLen; 7681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len > 64) 7691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = 64; 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = wpa_snprintf_hex( 7711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt buf, sizeof(buf), 7721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sess->eap_if->eapKeyData, len); 7731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt buf[len] = '\0'; 7741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fprintf(f, "%s\n", buf); 7751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fclose(f); 7761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapKeyDataLen > 64) { 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 32; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sess->eap_if->eapKeyDataLen / 2; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) client->shared_secret, 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapKeyData + len, 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, sess->eap_if->eapKeyData, 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len)) { 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add MPPE key attributes"); 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 794f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 795f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation && 796f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt data->subscr_remediation_url) { 797f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 *buf; 798f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t url_len = os_strlen(data->subscr_remediation_url); 799f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf = os_malloc(1 + url_len); 800f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (buf == NULL) { 801f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt radius_msg_free(msg); 802f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return NULL; 803f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 804f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf[0] = data->subscr_remediation_method; 805f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(&buf[1], data->subscr_remediation_url, url_len); 806f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 807f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 808f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf, 1 + url_len)) { 809f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 810f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 811f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(buf); 812f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) { 813f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 buf[1]; 814f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 815f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 816f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf, 0)) { 817f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 818f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 819f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 820f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 821f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT) { 829818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct hostapd_radius_attr *attr; 830818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt for (attr = sess->accept_attr; attr; attr = attr->next) { 831818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, 832818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpabuf_head(attr->val), 833818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpabuf_len(attr->val))) { 834818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 835818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_msg_free(msg); 836818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 837818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 838818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 839818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 840818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->authenticator) < 0) { 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 851df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtstatic struct radius_msg * 852df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtradius_server_macacl(struct radius_server_data *data, 853df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_client *client, 854df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_session *sess, 855df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_msg *request) 856df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt{ 857df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_msg *msg; 858df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt int code; 859df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 860df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt u8 *pw; 861df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt size_t pw_len; 862df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 863df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_ACCEPT; 864df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 865df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw, 866df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt &pw_len, NULL) < 0) { 867df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Could not get User-Password"); 868df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 869df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } else { 870df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt int res; 871df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct eap_user tmp; 872df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 873df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt os_memset(&tmp, 0, sizeof(tmp)); 874df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username, 875df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt os_strlen(sess->username), 0, &tmp); 876df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (res || !tmp.macacl || tmp.password == NULL) { 877df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("No MAC ACL user entry"); 878c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 879df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 880df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } else { 881df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt u8 buf[128]; 882df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt res = radius_user_password_hide( 883df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt request, tmp.password, tmp.password_len, 884df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt (u8 *) client->shared_secret, 885df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt client->shared_secret_len, 886df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt buf, sizeof(buf)); 887c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 888df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 889df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (res < 0 || pw_len != (size_t) res || 890c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(pw, buf, res) != 0) { 891df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Incorrect User-Password"); 892df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 893df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 894df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 895df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 896df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 897df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt msg = radius_msg_new(code, hdr->identifier); 898df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (msg == NULL) { 899df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to allocate reply message"); 900df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 901df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 902df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 903df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 904df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 905df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radius_msg_free(msg); 906df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 907df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 908df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 909df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT) { 910df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct hostapd_radius_attr *attr; 911df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt for (attr = sess->accept_attr; attr; attr = attr->next) { 912df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, 913df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpabuf_head(attr->val), 914df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpabuf_len(attr->val))) { 915df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 916df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radius_msg_free(msg); 917df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 918df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 919df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 920df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 921df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 922df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 923df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt client->shared_secret_len, 924df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt hdr->authenticator) < 0) { 925df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 926df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 927df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 928df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return msg; 929df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt} 930df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 931df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_reject(struct radius_server_data *data, 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *request, 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr *from, socklen_t fromlen, 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *from_addr, int from_port) 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr eapfail; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Reject invalid request from %s:%d", 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eapfail, 0, sizeof(eapfail)); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.code = EAP_CODE_FAILURE; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.identifier = 0; 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.length = host_to_be16(sizeof(eapfail)); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add EAP-Message attribute"); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->authenticator) < 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(msg); 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects++; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_rejects++; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(msg); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, sizeof(*from)) < 0) { 983cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_request(struct radius_server_data *data, 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg, 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr *from, socklen_t fromlen, 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *from_addr, int from_port, 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *force_sess) 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 100061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *eap = NULL; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, state_included = 0; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 statebuf[4]; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int state; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *reply; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int is_complete = 0; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_sess) 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = force_sess; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(statebuf)); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state_included = res >= 0; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == sizeof(statebuf)) { 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = WPA_GET_BE32(statebuf); 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = radius_server_get_session(client, state); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = NULL; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess) { 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (state_included) { 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("State attribute included but no session found"); 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_reject(data, client, msg, from, fromlen, 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1030818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess = radius_server_get_new_session(data, client, msg, 1031818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt from_addr); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) { 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Could not create a new session"); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_reject(data, client, msg, from, fromlen, 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->last_from_port == from_port && 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_identifier == radius_msg_get_hdr(msg)->identifier && 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sess->last_authenticator, 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(msg)->authenticator, 16) == 0) { 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Duplicate message from %s", from_addr); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.dup_access_requests++; 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.dup_access_requests++; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->last_reply) { 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(sess->last_reply); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sendto(data->auth_sock, wpabuf_head(buf), 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(buf), 0, 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, fromlen); 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1055cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1056cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No previous reply available for duplicate " 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message"); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1065293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 106661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap = radius_msg_get_eap(msg); 1067df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (eap == NULL && sess->macacl) { 1068df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt reply = radius_server_macacl(data, client, sess, msg); 1069df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (reply == NULL) 1070df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return -1; 1071df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt goto send_reply; 1072df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) { 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr); 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 108161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: if Code is Request, Success, or Failure, send Access-Reject; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC3579 Sect. 2.6.2. 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Include EAP-Response/Nak with no preferred method if 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * code == request. 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If code is not 1-4, discard the packet silently. 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Or is this already done by the EAP state machine? */ 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sess->eap_if->eapRespData); 109161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sess->eap_if->eapRespData = eap; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapResp = TRUE; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_sm_step(sess->eap); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess || 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapFail) && sess->eap_if->eapReqData) { 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP("EAP data from the state machine", 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(sess->eap_if->eapReqData), 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(sess->eap_if->eapReqData)); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sess->eap_if->eapFail) { 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP data from the state machine, but eapFail " 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "set"); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (eap_sm_method_pending(sess->eap)) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_msg); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_msg = msg; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port = from_port; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess->last_from_addr); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_addr = os_strdup(from_addr); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_fromlen = fromlen; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&sess->last_from, from, fromlen); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP data from the state machine - ignore this" 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " Access-Request silently (assuming it was a " 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duplicate)"); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt is_complete = 1; 1123818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->eap_if->eapFail) 1124818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP authentication failed"); 1125818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt else if (sess->eap_if->eapSuccess) 1126818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP authentication succeeded"); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = radius_server_encapsulate_eap(data, client, sess, msg); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1130df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtsend_reply: 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply) { 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(reply); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (radius_msg_get_hdr(reply)->code) { 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_ACCEPT: 1142818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Sending Access-Accept"); 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_accepts++; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_accepts++; 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_REJECT: 1147818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Sending Access-Reject"); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects++; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_rejects++; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_CHALLENGE: 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_challenges++; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_challenges++; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(reply); 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sendto(data->auth_sock, wpabuf_head(buf), 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(buf), 0, 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, fromlen); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1161cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1162cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_reply); 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_reply = reply; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port = from_port; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = radius_msg_get_hdr(msg); 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_identifier = hdr->identifier; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sess->last_authenticator, hdr->authenticator, 16); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_complete) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Removing completed session 0x%x after timeout", 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->sess_id); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, sess); 1180293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0, 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove_timeout, 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, sess); 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_receive_auth(int sock, void *eloop_ctx, 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *sock_ctx) 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf = NULL; 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_storage ss; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in sin; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in6 sin6; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } from; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = NULL; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg = NULL; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char abuf[50]; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int from_port = 0; 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(RADIUS_MAX_MSG_LEN); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen = sizeof(from); 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &from.ss, &fromlen); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 1217cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1218cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ipv6) { 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(abuf)) == NULL) 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf[0] = '\0'; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_port = ntohs(from.sin6.sin6_port); 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, abuf, from_port); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = radius_server_get_client(data, 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct in_addr *) 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &from.sin6.sin6_addr, 1); 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data->ipv6) { 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_port = ntohs(from.sin.sin_port); 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, abuf, from_port); 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = radius_server_get_client(data, &from.sin.sin_addr, 0); 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP("Received data", buf, len); 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client == NULL) { 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.invalid_requests++; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_parse(buf, len); 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.malformed_access_requests++; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.malformed_access_requests++; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = NULL; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(msg); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) { 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Unexpected RADIUS code %d", 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(msg)->code); 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.unknown_types++; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.unknown_types++; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_requests++; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_requests++; 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret, 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, NULL)) { 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf); 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.bad_authenticators++; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.bad_authenticators++; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_server_request(data, msg, (struct sockaddr *) &from, 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen, client, abuf, from_port, NULL) == 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt -2) 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* msg was stored with the session */ 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1299bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtstatic void radius_server_receive_acct(int sock, void *eloop_ctx, 1300bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt void *sock_ctx) 1301bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt{ 1302bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_server_data *data = eloop_ctx; 1303bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u8 *buf = NULL; 1304bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt union { 1305bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_storage ss; 1306bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_in sin; 1307bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1308bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_in6 sin6; 1309bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1310bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } from; 1311bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt socklen_t fromlen; 1312bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int len, res; 1313bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_client *client = NULL; 1314bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_msg *msg = NULL, *resp = NULL; 1315bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt char abuf[50]; 1316bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int from_port = 0; 1317bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_hdr *hdr; 1318bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct wpabuf *rbuf; 1319bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1320bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt buf = os_malloc(RADIUS_MAX_MSG_LEN); 1321bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (buf == NULL) { 1322bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1323bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1324bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1325bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt fromlen = sizeof(from); 1326bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1327bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct sockaddr *) &from.ss, &fromlen); 1328bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (len < 0) { 1329bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1330bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt strerror(errno)); 1331bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1332bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1333bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1334bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1335bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->ipv6) { 1336bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1337bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt sizeof(abuf)) == NULL) 1338bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt abuf[0] = '\0'; 1339bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt from_port = ntohs(from.sin6.sin6_port); 1340bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 1341bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len, abuf, from_port); 1342bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1343bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client = radius_server_get_client(data, 1344bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct in_addr *) 1345bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt &from.sin6.sin6_addr, 1); 1346bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1347bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1348bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1349bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (!data->ipv6) { 1350bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1351bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt from_port = ntohs(from.sin.sin_port); 1352bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 1353bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len, abuf, from_port); 1354bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1355bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1356bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1357bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1358bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DUMP("Received data", buf, len); 1359bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1360bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (client == NULL) { 1361bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1362bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.invalid_acct_requests++; 1363bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1364bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1365bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1366bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt msg = radius_msg_parse(buf, len); 1367bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (msg == NULL) { 1368bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1369bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.malformed_acct_requests++; 1370bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.malformed_acct_requests++; 1371bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1372bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1373bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1374bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(buf); 1375bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt buf = NULL; 1376bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1377bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 1378bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_dump(msg); 1379bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1380bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1381bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) { 1382bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Unexpected RADIUS code %d", 1383bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_get_hdr(msg)->code); 1384bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_acct_types++; 1385bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.unknown_acct_types++; 1386bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1387bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1388bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1389bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_requests++; 1390bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_requests++; 1391bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1392bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret, 1393bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->shared_secret_len)) { 1394bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Invalid Authenticator from %s", abuf); 1395bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_bad_authenticators++; 1396bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_bad_authenticators++; 1397bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1398bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1399bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1400bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt /* TODO: Write accounting information to a file or database */ 1401bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1402bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt hdr = radius_msg_get_hdr(msg); 1403bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1404bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier); 1405bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (resp == NULL) 1406bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1407bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1408bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret, 1409bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->shared_secret_len, 1410bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt hdr->authenticator); 1411bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1412bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Reply to %s:%d", abuf, from_port); 1413bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 1414bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_dump(resp); 1415bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1416bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt rbuf = radius_msg_get_buf(resp); 1417bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_responses++; 1418bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_responses++; 1419bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0, 1420bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct sockaddr *) &from.ss, fromlen); 1421bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (res < 0) { 1422bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1423bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt strerror(errno)); 1424bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1425bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1426bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtfail: 1427bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_free(resp); 1428bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_free(msg); 1429bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(buf); 1430bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt} 1431bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1432bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_disable_pmtu_discovery(int s) 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int r = -1; 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Turn off Path MTU discovery on IPv4/UDP sockets. */ 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int action = IP_PMTUDISC_DONT; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(action)); 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == -1) 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", strerror(errno)); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_open_socket(int port) 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in addr; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 1456cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno)); 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_disable_pmtu_discovery(s); 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin_family = AF_INET; 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin_port = htons(port); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1466cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_open_socket6(int port) 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s; 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in6 addr; 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_INET6, SOCK_DGRAM, 0); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 1483cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s", 1484cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin6_family = AF_INET6; 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin6_port = htons(port); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1493cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s; 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_free_sessions(struct radius_server_data *data, 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sessions) 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *session, *prev; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = sessions; 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (session) { 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = session; 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = session->next; 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, prev); 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_free_clients(struct radius_server_data *data, 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients) 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, *prev; 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = clients; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (client) { 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = client; 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = client->next; 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_sessions(data, prev->sessions); 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev->shared_secret); 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_client * 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_read_clients(const char *client_file, int ipv6) 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const int buf_size = 1024; 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, *pos; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients, *tail, *entry; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int line = 0, mask, failed = 0, i; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr addr; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr addr6; 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int val; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(client_file, "r"); 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) { 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ERROR("Could not open client file '%s'", client_file); 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_size); 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = tail = NULL; 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (fgets(buf, buf_size, f)) { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Configuration file format: 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 192.168.1.0/24 secret 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 192.168.1.2 secret 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fe80::211:22ff:fe33:4455/64 secretipv6 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line++; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[buf_size - 1] = '\0'; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0' && *pos != '\n') 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n') 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*buf == '\0' || *buf == '#') 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((*pos >= '0' && *pos <= '9') || *pos == '.' || 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*pos >= 'a' && *pos <= 'f') || *pos == ':' || 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*pos >= 'A' && *pos <= 'F')) { 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '/') { 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end; 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask = strtol(pos, &end, 10); 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((pos == end) || 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (mask < 0 || mask > (ipv6 ? 128 : 32))) { 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end; 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask = ipv6 ? 128 : 32; 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6 && inet_aton(buf, &addr) == 0) { 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) { 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_pton(AF_INET, buf, &addr) <= 0) { 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert IPv4 address to IPv6 */ 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mask <= 32) 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask += (128 - 32); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr6.s6_addr, 0, 10); 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6.s6_addr[10] = 0xff; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6.s6_addr[11] = 0xff; 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4); 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos == ' ' || *pos == '\t') { 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->shared_secret = os_strdup(pos); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->shared_secret == NULL) { 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->shared_secret_len = os_strlen(entry->shared_secret); 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6) { 16477d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt entry->addr.s_addr = addr.s_addr; 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = 0; 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mask; i++) 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= 1 << (31 - i); 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->mask.s_addr = htonl(val); 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6) { 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int offset = mask / 8; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16); 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(entry->mask6.s6_addr, 0xff, offset); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = 0; 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < (mask % 8); i++) 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= 1 << (7 - i); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (offset < 16) 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->mask6.s6_addr[offset] = val; 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tail == NULL) { 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = tail = entry; 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail->next = entry; 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail = entry; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (failed) { 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ERROR("Invalid line %d in '%s'", line, client_file); 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_clients(NULL, clients); 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = NULL; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clients; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_init - Initialize RADIUS server 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Configuration for the RADIUS server 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to private RADIUS server context or %NULL on failure 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This initializes a RADIUS server instance and returns a context pointer that 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be used in other calls to the RADIUS server module. The server can be 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialize by calling radius_server_deinit(). 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data * 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_init(struct radius_server_conf *conf) 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data; 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_IPV6 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ipv6) { 1704cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support"); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_init(&data->erp_keys); 1714fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&data->start_time); 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conf_ctx = conf->conf_ctx; 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_sim_db_priv = conf->eap_sim_db_priv; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl_ctx = conf->ssl_ctx; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->msg_ctx = conf->msg_ctx; 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ipv6 = conf->ipv6; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->pac_opaque_encr_key) { 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_opaque_encr_key = os_malloc(16); 17224171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (data->pac_opaque_encr_key) { 17234171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt os_memcpy(data->pac_opaque_encr_key, 17244171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt conf->pac_opaque_encr_key, 16); 17254171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt } 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id) { 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->eap_fast_a_id) { 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id, 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->eap_fast_a_id_len); 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id_len = conf->eap_fast_a_id_len; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id_info) 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_prov = conf->eap_fast_prov; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_key_lifetime = conf->pac_key_lifetime; 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_key_refresh_time = conf->pac_key_refresh_time; 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_eap_user = conf->get_eap_user; 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tnc = conf->tnc; 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->wps = conf->wps; 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pwd_group = conf->pwd_group; 174534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt data->server_id = conf->server_id; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_req_id_text) { 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len); 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->eap_req_id_text) { 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->eap_req_id_text, conf->eap_req_id_text, 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->eap_req_id_text_len); 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_req_id_text_len = conf->eap_req_id_text_len; 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data->erp = conf->erp; 17556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt data->erp_domain = conf->erp_domain; 1756d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->tls_session_lifetime = conf->tls_session_lifetime; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (conf->subscr_remediation_url) { 1759f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt data->subscr_remediation_url = 1760f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_strdup(conf->subscr_remediation_url); 1761f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1762717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt data->subscr_remediation_method = conf->subscr_remediation_method; 1763f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1764818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 1765818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conf->sqlite_file) { 1766818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sqlite3_open(conf->sqlite_file, &data->db)) { 1767818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_ERROR("Could not open SQLite file '%s'", 1768818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conf->sqlite_file); 1769818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_deinit(data); 1770818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 1771818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 1772818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 1773818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 1774818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 17751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 17761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conf->dump_msk_file) 17771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt data->dump_msk_file = os_strdup(conf->dump_msk_file); 17781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 17791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->clients = radius_server_read_clients(conf->client_file, 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ipv6); 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->clients == NULL) { 1783cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "No RADIUS clients configured"); 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ipv6) 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth_sock = radius_server_open_socket6(conf->auth_port); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth_sock = radius_server_open_socket(conf->auth_port); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth_sock < 0) { 1795cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server"); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_register_read_sock(data->auth_sock, 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_receive_auth, 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, NULL)) { 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1806bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (conf->acct_port) { 1807bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1808bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (conf->ipv6) 1809bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = radius_server_open_socket6( 1810bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt conf->acct_port); 1811bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt else 1812bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1813bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = radius_server_open_socket(conf->acct_port); 1814bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->acct_sock < 0) { 1815bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server"); 1816bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_deinit(data); 1817bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return NULL; 1818bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1819bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (eloop_register_read_sock(data->acct_sock, 1820bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_receive_acct, 1821bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data, NULL)) { 1822bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_deinit(data); 1823bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return NULL; 1824bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1825bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } else { 1826bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = -1; 1827bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1828bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * radius_server_erp_flush - Flush all ERP keys 18356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @data: RADIUS server context from radius_server_init() 18366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 18376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid radius_server_erp_flush(struct radius_server_data *data) 18386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 18396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_server_erp_key *erp; 18406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (data == NULL) 18426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 18436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key, 18446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt list)) != NULL) { 18456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_del(&erp->list); 18466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bin_clear_free(erp, sizeof(*erp)); 18476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 18486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 18496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/** 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_deinit - Deinitialize RADIUS server 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid radius_server_deinit(struct radius_server_data *data) 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth_sock >= 0) { 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(data->auth_sock); 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->auth_sock); 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1865bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->acct_sock >= 0) { 1866bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt eloop_unregister_read_sock(data->acct_sock); 1867bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt close(data->acct_sock); 1868bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1869bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_clients(data, data->clients); 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->pac_opaque_encr_key); 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_fast_a_id); 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_fast_a_id_info); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_req_id_text); 18761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 18771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(data->dump_msk_file); 18781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 1879f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(data->subscr_remediation_url); 1880818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 1881818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 1882818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (data->db) 1883818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_close(data->db); 1884818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 1885818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 18866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt radius_server_erp_flush(data); 18876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_get_mib - Get RADIUS server MIB information 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning the MIB data in text format 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: buf length in octets 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of octets written into buf 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint radius_server_get_mib(struct radius_server_data *data, char *buf, 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen) 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret, uptime; 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int idx; 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end, *pos; 1905fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *cli; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 2619 - RADIUS Authentication Server MIB */ 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL || buflen == 0) 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uptime = (now.sec - data->start_time.sec) * 100 + 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((now.usec - data->start_time.usec) / 10000) % 100; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RADIUS-AUTH-SERVER-MIB\n" 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServIdent=hostapd\n" 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServUpTime=%d\n" 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServResetTime=0\n" 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServConfigReset=4\n", 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uptime); 19266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) { 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessRequests=%u\n" 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalInvalidRequests=%u\n" 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalDupAccessRequests=%u\n" 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessAccepts=%u\n" 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessRejects=%u\n" 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessChallenges=%u\n" 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalMalformedAccessRequests=%u\n" 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalBadAuthenticators=%u\n" 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalPacketsDropped=%u\n" 1942bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAuthServTotalUnknownTypes=%u\n" 1943bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalRequests=%u\n" 1944bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalInvalidRequests=%u\n" 1945bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalResponses=%u\n" 1946bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalMalformedRequests=%u\n" 1947bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalBadAuthenticators=%u\n" 1948bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalUnknownTypes=%u\n", 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_requests, 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.invalid_requests, 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.dup_access_requests, 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_accepts, 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects, 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_challenges, 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.malformed_access_requests, 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.bad_authenticators, 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped, 1958bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_types, 1959bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_requests, 1960bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.invalid_acct_requests, 1961bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_responses, 1962bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.malformed_acct_requests, 1963bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_bad_authenticators, 1964bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_acct_types); 19656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) { 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) { 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char abuf[50], mbuf[50]; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ipv6) { 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_ntop(AF_INET6, &cli->addr6, abuf, 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(abuf)) == NULL) 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf[0] = '\0'; 1978661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (inet_ntop(AF_INET6, &cli->mask6, mbuf, 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mbuf)) == NULL) 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mbuf[0] = '\0'; 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data->ipv6) { 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf)); 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf)); 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthClientIndex=%u\n" 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthClientAddress=%s/%s\n" 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessRequests=%u\n" 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServDupAccessRequests=%u\n" 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessAccepts=%u\n" 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessRejects=%u\n" 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessChallenges=%u\n" 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServMalformedAccessRequests=%u\n" 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServBadAuthenticators=%u\n" 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServPacketsDropped=%u\n" 1999bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAuthServUnknownTypes=%u\n" 2000bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalRequests=%u\n" 2001bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalInvalidRequests=%u\n" 2002bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalResponses=%u\n" 2003bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalMalformedRequests=%u\n" 2004bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalBadAuthenticators=%u\n" 2005bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalUnknownTypes=%u\n", 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx, 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf, mbuf, 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_requests, 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.dup_access_requests, 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_accepts, 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_rejects, 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_challenges, 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.malformed_access_requests, 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.bad_authenticators, 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.packets_dropped, 2016bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.unknown_types, 2017bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_requests, 2018bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.invalid_acct_requests, 2019bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_responses, 2020bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.malformed_acct_requests, 2021bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_bad_authenticators, 2022bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.unknown_acct_types); 20236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) { 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_get_eap_user(void *ctx, const u8 *identity, 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len, int phase2, 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_user *user) 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = ctx; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = sess->server; 2040f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int ret; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2042f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ret = data->get_eap_user(data->conf_ctx, identity, identity_len, 2043f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt phase2, user); 2044818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (ret == 0 && user) { 2045818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->accept_attr = user->accept_attr; 2046f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sess->remediation = user->remediation; 2047df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt sess->macacl = user->macacl; 2048818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 2049912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 2050912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt if (ret) { 2051912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt RADIUS_DEBUG("%s: User-Name not found from user database", 2052912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt __func__); 2053912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt } 2054912c6ecf72fb2c84fbf17dbd0666492778dbd9fcDmitry Shmidt 2055f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return ret; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len) 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = ctx; 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = sess->server; 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = data->eap_req_id_text_len; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->eap_req_id_text; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_log_msg(void *ctx, const char *msg) 2069818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 2070818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct radius_session *sess = ctx; 2071818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP: %s", msg); 2072818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 2073818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 2074818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 20756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 20766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic const char * radius_server_get_erp_domain(void *ctx) 20786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 20796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_session *sess = ctx; 20806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_server_data *data = sess->server; 20816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return data->erp_domain; 20836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 20846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic struct eap_server_erp_key * 20876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtradius_server_erp_get_key(void *ctx, const char *keyname) 20886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 20896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_session *sess = ctx; 20906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_server_data *data = sess->server; 20916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_server_erp_key *erp; 20926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key, 20946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt list) { 20956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_strcmp(erp->keyname_nai, keyname) == 0) 20966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return erp; 20976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 20986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 20996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 21006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 21016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp) 21046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 21056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_session *sess = ctx; 21066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct radius_server_data *data = sess->server; 21076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dl_list_add(&data->erp_keys, &erp->list); 21096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 21106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 21116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 21136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21151d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic const struct eapol_callbacks radius_server_eapol_cb = 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_eap_user = radius_server_get_eap_user, 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_eap_req_id_text = radius_server_get_eap_req_id_text, 2119818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt .log_msg = radius_server_log_msg, 21206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_ERP 21216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt .get_erp_send_reauth_start = NULL, 21226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt .get_erp_domain = radius_server_get_erp_domain, 21236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt .erp_get_key = radius_server_erp_get_key, 21246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt .erp_add_key = radius_server_erp_add_key, 21256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_ERP */ 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_eap_pending_cb - Pending EAP data notification 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pending EAP context pointer 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to notify EAP server module that a pending operation 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been completed and processing of the EAP session can proceed. 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx) 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *cli; 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *s, *sess = NULL; 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cli = data->clients; cli; cli = cli->next) { 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = cli->sessions; s; s = s->next) { 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->eap == ctx && s->last_msg) { 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = s; 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess) 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) { 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No session matched callback ctx"); 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = sess->last_msg; 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_msg = NULL; 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_pending_cb(sess->eap); 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_server_request(data, msg, 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &sess->last_from, 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_fromlen, cli, 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_addr, 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port, sess) == -2) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* msg was stored with the session */ 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2174