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/** 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS_MAX_SESSION - Maximum number of active sessions 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_MAX_SESSION 100 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_MAX_MSG_LEN 3000 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eapol_callbacks radius_server_eapol_cb; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_client; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_server_counters - RADIUS server statistics counters 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_counters { 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_requests; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 invalid_requests; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 dup_access_requests; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_accepts; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_rejects; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 access_challenges; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 malformed_access_requests; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 bad_authenticators; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 packets_dropped; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 unknown_types; 57bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 58bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_requests; 59bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 invalid_acct_requests; 60bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_responses; 61bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 malformed_acct_requests; 62bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 acct_bad_authenticators; 63bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u32 unknown_acct_types; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_session - Internal RADIUS server data for a session 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_session { 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *next; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *server; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int sess_id; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sm *eap; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_eapol_interface *eap_if; 76818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *username; /* from User-Name attribute */ 77818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *nas_ip; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *last_msg; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *last_from_addr; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int last_from_port; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_storage last_from; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t last_fromlen; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_identifier; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *last_reply; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 last_authenticator[16]; 87f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 88f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt unsigned int remediation:1; 89df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt unsigned int macacl:1; 90818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 91818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct hostapd_radius_attr *accept_attr; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_client - Internal RADIUS server data for a client 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_client { 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *next; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr addr; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr mask; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr addr6; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr mask6; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *shared_secret; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int shared_secret_len; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sessions; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_counters counters; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * struct radius_server_data - Internal RADIUS server data 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data { 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * auth_sock - Socket for RADIUS authentication messages 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auth_sock; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 121bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt * acct_sock - Socket for RADIUS accounting messages 122bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt */ 123bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int acct_sock; 124bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 125bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt /** 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * clients - List of authorized RADIUS clients 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * next_sess_id - Next session identifier 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int next_sess_id; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * conf_ctx - Context pointer for callbacks 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is used as the ctx argument in get_eap_user() calls. 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *conf_ctx; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * num_sess - Number of active sessions 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_sess; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_priv - EAP-SIM/AKA database context 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is passed to the EAP-SIM/AKA server implementation as a 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * callback context. 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eap_sim_db_priv; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ssl_ctx - TLS context 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is passed to the EAP server implementation as a callback 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context for TLS operations. 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ssl_ctx; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This parameter is used to set a key for EAP-FAST to encrypt the 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * set, must point to a 16-octet key. 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pac_opaque_encr_key; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id - EAP-FAST authority identity (A-ID) 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If EAP-FAST is not used, this can be set to %NULL. In theory, this 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is a variable length field, but due to some existing implementations 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requiring A-ID to be 16 octets in length, it is recommended to use 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that length for the field to provide interoperability with deployed 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer implementations. 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *eap_fast_a_id; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_fast_a_id_len; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_a_id_info - EAP-FAST authority identifier information 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This A-ID-Info contains a user-friendly name for the A-ID. For 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * example, this could be the enterprise and server names in 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * human-readable format. This field is encoded as UTF-8. If EAP-FAST 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is not used, this can be set to %NULL. 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *eap_fast_a_id_info; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_fast_prov - EAP-FAST provisioning modes 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 0 = provisioning disabled, 1 = only anonymous provisioning allowed, 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2 = only authenticated provisioning allowed, 3 = both provisioning 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modes allowed. 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_fast_prov; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is the hard limit on how long a provisioned PAC-Key can be 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used. 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pac_key_lifetime; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is a soft limit on the PAC-Key. The server will automatically 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * generate a new PAC-Key when this number of seconds (or fewer) of the 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * lifetime remains. 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pac_key_refresh_time; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This controls whether the protected success/failure indication 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA. 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_sim_aka_result_ind; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tnc - Trusted Network Connect (TNC) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This controls whether TNC is enabled and will be required before the 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * peer is allowed to connect. Note: This is only used with EAP-TTLS 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and EAP-FAST. If any other EAP method is enabled, the peer will be 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allowed to connect without TNC. 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pwd_group - The D-H group assigned for EAP-pwd 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If EAP-pwd is not used it can be set to zero. 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 pwd_group; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 25034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt * server_id - Server identity 25134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt */ 25234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt const char *server_id; 25334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 25434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /** 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wps - Wi-Fi Protected Setup context 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If WPS is used with an external RADIUS server (which is quite 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unlikely configuration), this is used to provide a pointer to WPS 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * context data. Normally, this can be set to %NULL. 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_context *wps; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ipv6 - Whether to enable IPv6 support in the RADIUS server 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ipv6; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * start_time - Timestamp of server start 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 271fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime start_time; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * counters - Statistics counters for server operations 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These counters are the sum over all clients. 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_counters counters; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * get_eap_user - Callback for fetching EAP user information 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context data from conf_ctx 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity: User identity 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: identity buffer length in octets 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @phase2: Whether this is for Phase 2 identity 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @user: Data structure for filling in the user information 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is used to fetch information from user database. The callback 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will fill in information about allowed EAP methods and the user 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * password. The password field will be an allocated copy of the 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * password data and RADIUS server will free it after use. 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len, 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int phase2, struct eap_user *user); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text - Optional data for EAP-Request/Identity 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be used to configure an optional, displayable message that 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be sent in EAP-Request/Identity. This string can contain an 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASCII-0 character (nul) to separate network infromation per RFC 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4284. The actual string length is explicit provided in 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text_len since nul character will not be used as a string 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * terminator. 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *eap_req_id_text; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /** 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_req_id_text_len - Length of eap_req_id_text buffer in octets 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_req_id_text_len; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * msg_ctx - Context data for wpa_msg() calls 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *msg_ctx; 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char *dump_msk_file; 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 322f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 323f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt char *subscr_remediation_url; 324f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 subscr_remediation_method; 325818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 326818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 327818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3 *db; 328818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DEBUG(args...) \ 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_printf(MSG_DEBUG, "RADIUS SRV: " args) 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_ERROR(args...) \ 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_printf(MSG_ERROR, "RADIUS SRV: " args) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DUMP(args...) \ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args) 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RADIUS_DUMP_ASCII(args...) \ 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args) 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove_timeout(void *eloop_ctx, 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 346818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid srv_log(struct radius_session *sess, const char *fmt, ...) 347818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry ShmidtPRINTF_FORMAT(2, 3); 348818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 349818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid srv_log(struct radius_session *sess, const char *fmt, ...) 350818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 351818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_list ap; 352818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *buf; 353818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int buflen; 354818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 355818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_start(ap, fmt); 356818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 357818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_end(ap); 358818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 359818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt buf = os_malloc(buflen); 360818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (buf == NULL) 361818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return; 362818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_start(ap, fmt); 363818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt vsnprintf(buf, buflen, fmt, ap); 364818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt va_end(ap); 365818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 366818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf); 367818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 368818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 369818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->server->db) { 370818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt char *sql; 371818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sql = sqlite3_mprintf("INSERT INTO authlog" 372818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "(timestamp,session,nas_ip,username,note)" 373818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt " VALUES (" 374818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "strftime('%%Y-%%m-%%d %%H:%%M:%%f'," 375818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt "'now'),%u,%Q,%Q,%Q)", 376818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->sess_id, sess->nas_ip, 377818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->username, buf); 378818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sql) { 379818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sqlite3_exec(sess->server->db, sql, NULL, NULL, 380818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt NULL) != SQLITE_OK) { 381818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s", 382818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_errmsg(sess->server->db)); 383818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 384818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_free(sql); 385818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 386818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 387818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 388818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 389818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(buf); 390818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 391818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_client * 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_client(struct radius_server_data *data, struct in_addr *addr, 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ipv6) 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = data->clients; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (client) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6) { 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr *addr6; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6 = (struct in6_addr *) addr; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 16; i++) { 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((addr6->s6_addr[i] & 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->mask6.s6_addr[i]) != 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (client->addr6.s6_addr[i] & 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->mask6.s6_addr[i])) { 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = 17; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == 16) { 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) == 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (addr->s_addr & client->mask.s_addr)) { 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = client->next; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return client; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_session(struct radius_client *client, unsigned int sess_id) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = client->sessions; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (sess) { 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->sess_id == sess_id) { 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = sess->next; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_free(struct radius_server_data *data, 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess) 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_timeout, data, sess); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_sm_deinit(sess->eap); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_msg); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess->last_from_addr); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_reply); 457818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(sess->username); 458818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_free(sess->nas_ip); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->num_sess--; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove(struct radius_server_data *data, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess) 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = sess->client; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *session, *prev; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = client->sessions; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (session) { 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (session == sess) { 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) { 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->sessions = sess->next; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = sess->next; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, sess); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = session; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = session->next; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_remove_timeout(void *eloop_ctx, 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx) 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = timeout_ctx; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove(data, sess); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx) 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = timeout_ctx; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove(data, sess); 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_new_session(struct radius_server_data *data, 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client) 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->num_sess >= RADIUS_MAX_SESSION) { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Maximum number of existing session - no room " 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for a new session"); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = os_zalloc(sizeof(*sess)); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->server = data; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->client = client; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->sess_id = data->next_sess_id++; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->next = client->sessions; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->sessions = sess; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0, 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_timeout, data, sess); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->num_sess++; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 539818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_testing_options_tls(struct radius_session *sess, 540818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const char *tls, 541818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_config *eap_conf) 542818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 543818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt int test = atoi(tls); 544818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 545818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt switch (test) { 546818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 1: 547818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break VerifyData"); 548818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA; 549818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 550818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 2: 551818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash"); 552818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH; 553818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 554818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case 3: 555818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature"); 556818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE; 557818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 558b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 4: 559b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime"); 560b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_511B; 561b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 562b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 5: 563b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime"); 564b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_767B; 565b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 566b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 6: 567b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\""); 568b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_15; 569b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 570b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 7: 571b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container"); 572b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_PRIME_58B; 573b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 574b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt case 8: 575b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt srv_log(sess, "TLS test - RSA-DHE using a non-prime"); 576b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eap_conf->tls_test_flags = TLS_DHE_NON_PRIME; 577b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt break; 578818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt default: 579818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Unrecognized TLS test"); 580818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt break; 581818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 582818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 583818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 584818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 585818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_testing_options(struct radius_session *sess, 586818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_config *eap_conf) 587818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 588818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 589818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const char *pos; 590818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 591818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos = os_strstr(sess->username, "@test-"); 592818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (pos == NULL) 593818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return; 594818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt pos += 6; 595818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (os_strncmp(pos, "tls-", 4) == 0) 596818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_testing_options_tls(sess, pos + 4, eap_conf); 597818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt else 598818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Unrecognized test: %s", pos); 599818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 600818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 601818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 602818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_session * 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_get_new_session(struct radius_server_data *data, 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 606818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct radius_msg *msg, const char *from_addr) 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *user; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t user_len; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_config eap_conf; 613818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_user tmp; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Creating a new session"); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 617818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user, 618818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt &user_len, NULL) < 0) { 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Could not get User-Name"); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP_ASCII("User-Name", user, user_len); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 624818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt os_memset(&tmp, 0, sizeof(tmp)); 625818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp); 626c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (res != 0) { 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("User-Name not found from user database"); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 633818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("Matching user entry found"); 634818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess = radius_server_new_session(data, client); 635818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess == NULL) { 636818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_DEBUG("Failed to create a new session"); 637818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 638818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 639818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->accept_attr = tmp.accept_attr; 640df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt sess->macacl = tmp.macacl; 641818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 642b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt sess->username = os_malloc(user_len * 4 + 1); 643818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->username == NULL) { 644818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_session_free(data, sess); 645818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 646818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 647b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt printf_encode(sess->username, user_len * 4 + 1, user, user_len); 648818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 649818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->nas_ip = os_strdup(from_addr); 650818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->nas_ip == NULL) { 651818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_session_free(data, sess); 652818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 653818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 654818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 655818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "New session created"); 656818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eap_conf, 0, sizeof(eap_conf)); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.ssl_ctx = data->ssl_ctx; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.msg_ctx = data->msg_ctx; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_sim_db_priv = data->eap_sim_db_priv; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.backend_auth = TRUE; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_server = 1; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id = data->eap_fast_a_id; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_fast_prov = data->eap_fast_prov; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_key_lifetime = data->pac_key_lifetime; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pac_key_refresh_time = data->pac_key_refresh_time; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.tnc = data->tnc; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.wps = data->wps; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_conf.pwd_group = data->pwd_group; 67434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eap_conf.server_id = (const u8 *) data->server_id; 67534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt eap_conf.server_id_len = os_strlen(data->server_id); 676818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_testing_options(sess, &eap_conf); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb, 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &eap_conf); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap == NULL) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to initialize EAP state machine for the " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "new session"); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, sess); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if = eap_get_interface(sess->eap); 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapRestart = TRUE; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->portEnabled = TRUE; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return sess; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_msg * 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_encapsulate_eap(struct radius_server_data *data, 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess, 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *request) 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int code; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int sess_id; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapFail) { 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapFail = FALSE; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sess->eap_if->eapSuccess) { 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapSuccess = FALSE; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_ACCEPT; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapReq = FALSE; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt code = RADIUS_CODE_ACCESS_CHALLENGE; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(code, hdr->identifier); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to allocate reply message"); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess_id = htonl(sess->sess_id); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_CHALLENGE && 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &sess_id, sizeof(sess_id))) { 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add State attribute"); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapReqData && 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(sess->eap_if->eapReqData))) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add EAP-Message attribute"); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 7381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 7391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (data->dump_msk_file) { 7401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FILE *f; 7411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt char buf[2 * 64 + 1]; 7421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt f = fopen(data->dump_msk_file, "a"); 7431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (f) { 7441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = sess->eap_if->eapKeyDataLen; 7451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len > 64) 7461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = 64; 7471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt len = wpa_snprintf_hex( 7481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt buf, sizeof(buf), 7491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sess->eap_if->eapKeyData, len); 7501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt buf[len] = '\0'; 7511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fprintf(f, "%s\n", buf); 7521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fclose(f); 7531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapKeyDataLen > 64) { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 32; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sess->eap_if->eapKeyDataLen / 2; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) client->shared_secret, 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapKeyData + len, 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, sess->eap_if->eapKeyData, 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len)) { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add MPPE key attributes"); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 771f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#ifdef CONFIG_HS20 772f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation && 773f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt data->subscr_remediation_url) { 774f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 *buf; 775f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt size_t url_len = os_strlen(data->subscr_remediation_url); 776f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf = os_malloc(1 + url_len); 777f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (buf == NULL) { 778f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt radius_msg_free(msg); 779f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return NULL; 780f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 781f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf[0] = data->subscr_remediation_method; 782f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_memcpy(&buf[1], data->subscr_remediation_url, url_len); 783f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 784f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 785f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf, 1 + url_len)) { 786f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 787f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 788f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(buf); 789f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) { 790f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt u8 buf[1]; 791f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!radius_msg_add_wfa( 792f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 793f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt buf, 0)) { 794f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 795f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 796f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 797f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt#endif /* CONFIG_HS20 */ 798f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 805818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT) { 806818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct hostapd_radius_attr *attr; 807818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt for (attr = sess->accept_attr; attr; attr = attr->next) { 808818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, 809818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpabuf_head(attr->val), 810818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpabuf_len(attr->val))) { 811818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 812818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_msg_free(msg); 813818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 814818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 815818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 816818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 817818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->authenticator) < 0) { 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtstatic struct radius_msg * 829df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtradius_server_macacl(struct radius_server_data *data, 830df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_client *client, 831df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_session *sess, 832df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_msg *request) 833df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt{ 834df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_msg *msg; 835df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt int code; 836df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 837df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt u8 *pw; 838df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt size_t pw_len; 839df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 840df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_ACCEPT; 841df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 842df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw, 843df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt &pw_len, NULL) < 0) { 844df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Could not get User-Password"); 845df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 846df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } else { 847df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt int res; 848df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct eap_user tmp; 849df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 850df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt os_memset(&tmp, 0, sizeof(tmp)); 851df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username, 852df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt os_strlen(sess->username), 0, &tmp); 853df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (res || !tmp.macacl || tmp.password == NULL) { 854df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("No MAC ACL user entry"); 855c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 856df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 857df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } else { 858df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt u8 buf[128]; 859df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt res = radius_user_password_hide( 860df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt request, tmp.password, tmp.password_len, 861df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt (u8 *) client->shared_secret, 862df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt client->shared_secret_len, 863df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt buf, sizeof(buf)); 864c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(tmp.password, tmp.password_len); 865df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 866df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (res < 0 || pw_len != (size_t) res || 867c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(pw, buf, res) != 0) { 868df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Incorrect User-Password"); 869df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt code = RADIUS_CODE_ACCESS_REJECT; 870df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 871df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 872df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 873df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 874df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt msg = radius_msg_new(code, hdr->identifier); 875df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (msg == NULL) { 876df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to allocate reply message"); 877df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 878df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 879df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 880df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 881df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 882df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radius_msg_free(msg); 883df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 884df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 885df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 886df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (code == RADIUS_CODE_ACCESS_ACCEPT) { 887df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt struct hostapd_radius_attr *attr; 888df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt for (attr = sess->accept_attr; attr; attr = attr->next) { 889df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, 890df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpabuf_head(attr->val), 891df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpabuf_len(attr->val))) { 892df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 893df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radius_msg_free(msg); 894df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return NULL; 895df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 896df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 897df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 898df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 899df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 900df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt client->shared_secret_len, 901df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt hdr->authenticator) < 0) { 902df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 903df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 904df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 905df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return msg; 906df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt} 907df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 908df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_reject(struct radius_server_data *data, 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *request, 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr *from, socklen_t fromlen, 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *from_addr, int from_port) 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr eapfail; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(request); 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Reject invalid request from %s:%d", 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eapfail, 0, sizeof(eapfail)); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.code = EAP_CODE_FAILURE; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.identifier = 0; 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapfail.length = host_to_be16(sizeof(eapfail)); 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add EAP-Message attribute"); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->authenticator) < 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(msg); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects++; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_rejects++; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(msg); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, sizeof(*from)) < 0) { 960cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_request(struct radius_server_data *data, 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg, 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr *from, socklen_t fromlen, 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *from_addr, int from_port, 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *force_sess) 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 97761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *eap = NULL; 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, state_included = 0; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 statebuf[4]; 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int state; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess; 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *reply; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int is_complete = 0; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (force_sess) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = force_sess; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(statebuf)); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state_included = res >= 0; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == sizeof(statebuf)) { 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = WPA_GET_BE32(statebuf); 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = radius_server_get_session(client, state); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = NULL; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess) { 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (state_included) { 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("State attribute included but no session found"); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_reject(data, client, msg, from, fromlen, 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1007818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess = radius_server_get_new_session(data, client, msg, 1008818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt from_addr); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) { 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Could not create a new session"); 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_reject(data, client, msg, from, fromlen, 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr, from_port); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->last_from_port == from_port && 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_identifier == radius_msg_get_hdr(msg)->identifier && 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sess->last_authenticator, 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(msg)->authenticator, 16) == 0) { 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Duplicate message from %s", from_addr); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.dup_access_requests++; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.dup_access_requests++; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->last_reply) { 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(sess->last_reply); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sendto(data->auth_sock, wpabuf_head(buf), 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(buf), 0, 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, fromlen); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1032cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1033cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No previous reply available for duplicate " 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message"); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 104361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap = radius_msg_get_eap(msg); 1044df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (eap == NULL && sess->macacl) { 1045df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt reply = radius_server_macacl(data, client, sess, msg); 1046df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (reply == NULL) 1047df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return -1; 1048df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt goto send_reply; 1049df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) { 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_addr); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 105861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: if Code is Request, Success, or Failure, send Access-Reject; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RFC3579 Sect. 2.6.2. 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Include EAP-Response/Nak with no preferred method if 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * code == request. 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If code is not 1-4, discard the packet silently. 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Or is this already done by the EAP state machine? */ 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sess->eap_if->eapRespData); 106861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sess->eap_if->eapRespData = eap; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapResp = TRUE; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_sm_step(sess->eap); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess || 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->eap_if->eapFail) && sess->eap_if->eapReqData) { 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP("EAP data from the state machine", 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(sess->eap_if->eapReqData), 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(sess->eap_if->eapReqData)); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sess->eap_if->eapFail) { 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP data from the state machine, but eapFail " 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "set"); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (eap_sm_method_pending(sess->eap)) { 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_msg); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_msg = msg; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port = from_port; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sess->last_from_addr); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_addr = os_strdup(from_addr); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_fromlen = fromlen; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&sess->last_from, from, fromlen); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No EAP data from the state machine - ignore this" 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " Access-Request silently (assuming it was a " 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "duplicate)"); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt is_complete = 1; 1100818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sess->eap_if->eapFail) 1101818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP authentication failed"); 1102818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt else if (sess->eap_if->eapSuccess) 1103818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP authentication succeeded"); 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = radius_server_encapsulate_eap(data, client, sess, msg); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1107df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidtsend_reply: 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reply) { 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr; 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port); 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(reply); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (radius_msg_get_hdr(reply)->code) { 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_ACCEPT: 1119818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Sending Access-Accept"); 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_accepts++; 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_accepts++; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_REJECT: 1124818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "Sending Access-Reject"); 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects++; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_rejects++; 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_CHALLENGE: 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_challenges++; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_challenges++; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = radius_msg_get_buf(reply); 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sendto(data->auth_sock, wpabuf_head(buf), 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(buf), 0, 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) from, fromlen); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1138cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1139cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(sess->last_reply); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_reply = reply; 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port = from_port; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = radius_msg_get_hdr(msg); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_identifier = hdr->identifier; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sess->last_authenticator, hdr->authenticator, 16); 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped++; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.packets_dropped++; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (is_complete) { 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Removing completed session 0x%x after timeout", 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->sess_id); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(radius_server_session_remove_timeout, 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, sess); 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(10, 0, 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_remove_timeout, 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, sess); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_receive_auth(int sock, void *eloop_ctx, 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *sock_ctx) 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = eloop_ctx; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf = NULL; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_storage ss; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in sin; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in6 sin6; 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } from; 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client = NULL; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg = NULL; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char abuf[50]; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int from_port = 0; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(RADIUS_MAX_MSG_LEN); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen = sizeof(from); 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &from.ss, &fromlen); 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 1194cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1195cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ipv6) { 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(abuf)) == NULL) 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf[0] = '\0'; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_port = ntohs(from.sin6.sin6_port); 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, abuf, from_port); 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = radius_server_get_client(data, 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct in_addr *) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &from.sin6.sin6_addr, 1); 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data->ipv6) { 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt from_port = ntohs(from.sin.sin_port); 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len, abuf, from_port); 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = radius_server_get_client(data, &from.sin.sin_addr, 0); 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DUMP("Received data", buf, len); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client == NULL) { 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.invalid_requests++; 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_parse(buf, len); 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.malformed_access_requests++; 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.malformed_access_requests++; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = NULL; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_dump(msg); 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) { 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Unexpected RADIUS code %d", 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(msg)->code); 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.unknown_types++; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.unknown_types++; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_requests++; 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.access_requests++; 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret, 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->shared_secret_len, NULL)) { 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf); 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.bad_authenticators++; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client->counters.bad_authenticators++; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_server_request(data, msg, (struct sockaddr *) &from, 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen, client, abuf, from_port, NULL) == 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt -2) 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* msg was stored with the session */ 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1276bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtstatic void radius_server_receive_acct(int sock, void *eloop_ctx, 1277bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt void *sock_ctx) 1278bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt{ 1279bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_server_data *data = eloop_ctx; 1280bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt u8 *buf = NULL; 1281bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt union { 1282bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_storage ss; 1283bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_in sin; 1284bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1285bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct sockaddr_in6 sin6; 1286bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1287bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } from; 1288bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt socklen_t fromlen; 1289bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int len, res; 1290bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_client *client = NULL; 1291bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_msg *msg = NULL, *resp = NULL; 1292bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt char abuf[50]; 1293bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt int from_port = 0; 1294bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct radius_hdr *hdr; 1295bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt struct wpabuf *rbuf; 1296bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1297bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt buf = os_malloc(RADIUS_MAX_MSG_LEN); 1298bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (buf == NULL) { 1299bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1300bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1301bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1302bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt fromlen = sizeof(from); 1303bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1304bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct sockaddr *) &from.ss, &fromlen); 1305bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (len < 0) { 1306bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1307bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt strerror(errno)); 1308bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1309bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1310bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1311bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1312bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->ipv6) { 1313bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1314bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt sizeof(abuf)) == NULL) 1315bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt abuf[0] = '\0'; 1316bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt from_port = ntohs(from.sin6.sin6_port); 1317bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 1318bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len, abuf, from_port); 1319bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1320bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client = radius_server_get_client(data, 1321bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct in_addr *) 1322bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt &from.sin6.sin6_addr, 1); 1323bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1324bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1325bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1326bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (!data->ipv6) { 1327bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1328bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt from_port = ntohs(from.sin.sin_port); 1329bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Received %d bytes from %s:%d", 1330bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt len, abuf, from_port); 1331bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1332bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1333bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1334bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1335bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DUMP("Received data", buf, len); 1336bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1337bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (client == NULL) { 1338bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1339bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.invalid_acct_requests++; 1340bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1341bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1342bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1343bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt msg = radius_msg_parse(buf, len); 1344bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (msg == NULL) { 1345bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1346bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.malformed_acct_requests++; 1347bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.malformed_acct_requests++; 1348bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1349bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1350bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1351bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(buf); 1352bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt buf = NULL; 1353bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1354bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 1355bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_dump(msg); 1356bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1357bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1358bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) { 1359bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Unexpected RADIUS code %d", 1360bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_get_hdr(msg)->code); 1361bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_acct_types++; 1362bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.unknown_acct_types++; 1363bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1364bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1365bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1366bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_requests++; 1367bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_requests++; 1368bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1369bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret, 1370bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->shared_secret_len)) { 1371bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Invalid Authenticator from %s", abuf); 1372bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_bad_authenticators++; 1373bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_bad_authenticators++; 1374bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1375bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1376bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1377bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt /* TODO: Write accounting information to a file or database */ 1378bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1379bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt hdr = radius_msg_get_hdr(msg); 1380bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1381bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier); 1382bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (resp == NULL) 1383bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt goto fail; 1384bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1385bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret, 1386bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->shared_secret_len, 1387bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt hdr->authenticator); 1388bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1389bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt RADIUS_DEBUG("Reply to %s:%d", abuf, from_port); 1390bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) { 1391bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_dump(resp); 1392bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1393bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt rbuf = radius_msg_get_buf(resp); 1394bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_responses++; 1395bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt client->counters.acct_responses++; 1396bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0, 1397bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt (struct sockaddr *) &from.ss, fromlen); 1398bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (res < 0) { 1399bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1400bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt strerror(errno)); 1401bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1402bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1403bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidtfail: 1404bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_free(resp); 1405bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_msg_free(msg); 1406bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(buf); 1407bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt} 1408bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 1409bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_disable_pmtu_discovery(int s) 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int r = -1; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Turn off Path MTU discovery on IPv4/UDP sockets. */ 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int action = IP_PMTUDISC_DONT; 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(action)); 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == -1) 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", strerror(errno)); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_open_socket(int port) 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s; 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in addr; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_INET, SOCK_DGRAM, 0); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 1433cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno)); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_disable_pmtu_discovery(s); 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin_family = AF_INET; 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin_port = htons(port); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1443cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_open_socket6(int port) 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s; 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_in6 addr; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_INET6, SOCK_DGRAM, 0); 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 1460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s", 1461cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin6_family = AF_INET6; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)); 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sin6_port = htons(port); 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1470cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s; 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_free_sessions(struct radius_server_data *data, 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sessions) 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *session, *prev; 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = sessions; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (session) { 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = session; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt session = session->next; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_session_free(data, prev); 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void radius_server_free_clients(struct radius_server_data *data, 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients) 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *client, *prev; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = clients; 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (client) { 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = client; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client = client->next; 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_sessions(data, prev->sessions); 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev->shared_secret); 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct radius_client * 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_read_clients(const char *client_file, int ipv6) 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const int buf_size = 1024; 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, *pos; 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *clients, *tail, *entry; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int line = 0, mask, failed = 0, i; 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr addr; 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in6_addr addr6; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int val; 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(client_file, "r"); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) { 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ERROR("Could not open client file '%s'", client_file); 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(buf_size); 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = tail = NULL; 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (fgets(buf, buf_size, f)) { 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Configuration file format: 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 192.168.1.0/24 secret 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 192.168.1.2 secret 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fe80::211:22ff:fe33:4455/64 secretipv6 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line++; 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[buf_size - 1] = '\0'; 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0' && *pos != '\n') 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n') 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*buf == '\0' || *buf == '#') 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((*pos >= '0' && *pos <= '9') || *pos == '.' || 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*pos >= 'a' && *pos <= 'f') || *pos == ':' || 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*pos >= 'A' && *pos <= 'F')) { 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '/') { 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask = strtol(pos, &end, 10); 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((pos == end) || 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (mask < 0 || mask > (ipv6 ? 128 : 32))) { 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask = ipv6 ? 128 : 32; 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6 && inet_aton(buf, &addr) == 0) { 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) { 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_pton(AF_INET, buf, &addr) <= 0) { 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert IPv4 address to IPv6 */ 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mask <= 32) 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask += (128 - 32); 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr6.s6_addr, 0, 10); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6.s6_addr[10] = 0xff; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr6.s6_addr[11] = 0xff; 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4); 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos == ' ' || *pos == '\t') { 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->shared_secret = os_strdup(pos); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->shared_secret == NULL) { 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt failed = 1; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->shared_secret_len = os_strlen(entry->shared_secret); 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ipv6) { 16247d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt entry->addr.s_addr = addr.s_addr; 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = 0; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mask; i++) 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= 1 << (31 - i); 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->mask.s_addr = htonl(val); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ipv6) { 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int offset = mask / 8; 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16); 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(entry->mask6.s6_addr, 0xff, offset); 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = 0; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < (mask % 8); i++) 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= 1 << (7 - i); 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (offset < 16) 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->mask6.s6_addr[offset] = val; 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tail == NULL) { 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = tail = entry; 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail->next = entry; 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail = entry; 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (failed) { 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ERROR("Invalid line %d in '%s'", line, client_file); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_clients(NULL, clients); 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clients = NULL; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clients; 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_init - Initialize RADIUS server 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Configuration for the RADIUS server 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to private RADIUS server context or %NULL on failure 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This initializes a RADIUS server instance and returns a context pointer that 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will be used in other calls to the RADIUS server module. The server can be 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialize by calling radius_server_deinit(). 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct radius_server_data * 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtradius_server_init(struct radius_server_conf *conf) 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_IPV6 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ipv6) { 1681cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support"); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1690fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&data->start_time); 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conf_ctx = conf->conf_ctx; 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_sim_db_priv = conf->eap_sim_db_priv; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ssl_ctx = conf->ssl_ctx; 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->msg_ctx = conf->msg_ctx; 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ipv6 = conf->ipv6; 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->pac_opaque_encr_key) { 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_opaque_encr_key = os_malloc(16); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->pac_opaque_encr_key, conf->pac_opaque_encr_key, 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16); 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id) { 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->eap_fast_a_id) { 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id, 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->eap_fast_a_id_len); 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id_len = conf->eap_fast_a_id_len; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_fast_a_id_info) 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_fast_prov = conf->eap_fast_prov; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_key_lifetime = conf->pac_key_lifetime; 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pac_key_refresh_time = conf->pac_key_refresh_time; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_eap_user = conf->get_eap_user; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tnc = conf->tnc; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->wps = conf->wps; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pwd_group = conf->pwd_group; 171934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt data->server_id = conf->server_id; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->eap_req_id_text) { 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len); 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->eap_req_id_text) { 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data->eap_req_id_text, conf->eap_req_id_text, 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->eap_req_id_text_len); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap_req_id_text_len = conf->eap_req_id_text_len; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1729f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (conf->subscr_remediation_url) { 1730f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt data->subscr_remediation_url = 1731f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_strdup(conf->subscr_remediation_url); 1732f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 1733717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt data->subscr_remediation_method = conf->subscr_remediation_method; 1734f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1735818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 1736818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (conf->sqlite_file) { 1737818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (sqlite3_open(conf->sqlite_file, &data->db)) { 1738818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt RADIUS_ERROR("Could not open SQLite file '%s'", 1739818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt conf->sqlite_file); 1740818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt radius_server_deinit(data); 1741818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return NULL; 1742818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 1743818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 1744818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 1745818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 17461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 17471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conf->dump_msk_file) 17481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt data->dump_msk_file = os_strdup(conf->dump_msk_file); 17491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 17501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->clients = radius_server_read_clients(conf->client_file, 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ipv6); 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->clients == NULL) { 1754cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "No RADIUS clients configured"); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ipv6) 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth_sock = radius_server_open_socket6(conf->auth_port); 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth_sock = radius_server_open_socket(conf->auth_port); 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth_sock < 0) { 1766cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server"); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_register_read_sock(data->auth_sock, 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_receive_auth, 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, NULL)) { 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_deinit(data); 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1777bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (conf->acct_port) { 1778bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#ifdef CONFIG_IPV6 1779bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (conf->ipv6) 1780bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = radius_server_open_socket6( 1781bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt conf->acct_port); 1782bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt else 1783bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt#endif /* CONFIG_IPV6 */ 1784bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = radius_server_open_socket(conf->acct_port); 1785bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->acct_sock < 0) { 1786bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server"); 1787bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_deinit(data); 1788bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return NULL; 1789bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1790bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (eloop_register_read_sock(data->acct_sock, 1791bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_receive_acct, 1792bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data, NULL)) { 1793bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt radius_server_deinit(data); 1794bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return NULL; 1795bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1796bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } else { 1797bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->acct_sock = -1; 1798bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1799bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_deinit - Deinitialize RADIUS server 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid radius_server_deinit(struct radius_server_data *data) 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth_sock >= 0) { 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(data->auth_sock); 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->auth_sock); 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->acct_sock >= 0) { 1819bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt eloop_unregister_read_sock(data->acct_sock); 1820bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt close(data->acct_sock); 1821bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 1822bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_server_free_clients(data, data->clients); 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->pac_opaque_encr_key); 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_fast_a_id); 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_fast_a_id_info); 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->eap_req_id_text); 18291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST 18301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(data->dump_msk_file); 18311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */ 1832f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt os_free(data->subscr_remediation_url); 1833818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 1834818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_SQLITE 1835818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (data->db) 1836818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sqlite3_close(data->db); 1837818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_SQLITE */ 1838818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_get_mib - Get RADIUS server MIB information 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning the MIB data in text format 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: buf length in octets 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of octets written into buf 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint radius_server_get_mib(struct radius_server_data *data, char *buf, 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen) 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret, uptime; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int idx; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end, *pos; 1856fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *cli; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 2619 - RADIUS Authentication Server MIB */ 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL || buflen == 0) 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + buflen; 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1867fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uptime = (now.sec - data->start_time.sec) * 100 + 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((now.usec - data->start_time.usec) / 10000) % 100; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "RADIUS-AUTH-SERVER-MIB\n" 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServIdent=hostapd\n" 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServUpTime=%d\n" 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServResetTime=0\n" 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServConfigReset=4\n", 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uptime); 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) { 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessRequests=%u\n" 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalInvalidRequests=%u\n" 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalDupAccessRequests=%u\n" 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessAccepts=%u\n" 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessRejects=%u\n" 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalAccessChallenges=%u\n" 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalMalformedAccessRequests=%u\n" 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalBadAuthenticators=%u\n" 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServTotalPacketsDropped=%u\n" 1893bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAuthServTotalUnknownTypes=%u\n" 1894bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalRequests=%u\n" 1895bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalInvalidRequests=%u\n" 1896bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalResponses=%u\n" 1897bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalMalformedRequests=%u\n" 1898bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalBadAuthenticators=%u\n" 1899bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalUnknownTypes=%u\n", 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_requests, 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.invalid_requests, 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.dup_access_requests, 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_accepts, 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_rejects, 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.access_challenges, 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.malformed_access_requests, 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.bad_authenticators, 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->counters.packets_dropped, 1909bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_types, 1910bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_requests, 1911bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.invalid_acct_requests, 1912bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_responses, 1913bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.malformed_acct_requests, 1914bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.acct_bad_authenticators, 1915bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->counters.unknown_acct_types); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) { 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) { 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char abuf[50], mbuf[50]; 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IPV6 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->ipv6) { 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_ntop(AF_INET6, &cli->addr6, abuf, 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(abuf)) == NULL) 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf[0] = '\0'; 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inet_ntop(AF_INET6, &cli->mask6, abuf, 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mbuf)) == NULL) 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mbuf[0] = '\0'; 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IPV6 */ 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!data->ipv6) { 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf)); 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf)); 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthClientIndex=%u\n" 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthClientAddress=%s/%s\n" 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessRequests=%u\n" 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServDupAccessRequests=%u\n" 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessAccepts=%u\n" 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessRejects=%u\n" 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServAccessChallenges=%u\n" 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServMalformedAccessRequests=%u\n" 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServBadAuthenticators=%u\n" 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radiusAuthServPacketsDropped=%u\n" 1950bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAuthServUnknownTypes=%u\n" 1951bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalRequests=%u\n" 1952bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalInvalidRequests=%u\n" 1953bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalResponses=%u\n" 1954bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalMalformedRequests=%u\n" 1955bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalBadAuthenticators=%u\n" 1956bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt "radiusAccServTotalUnknownTypes=%u\n", 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx, 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abuf, mbuf, 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_requests, 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.dup_access_requests, 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_accepts, 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_rejects, 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.access_challenges, 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.malformed_access_requests, 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.bad_authenticators, 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->counters.packets_dropped, 1967bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.unknown_types, 1968bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_requests, 1969bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.invalid_acct_requests, 1970bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_responses, 1971bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.malformed_acct_requests, 1972bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.acct_bad_authenticators, 1973bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt cli->counters.unknown_acct_types); 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) { 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int radius_server_get_eap_user(void *ctx, const u8 *identity, 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t identity_len, int phase2, 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_user *user) 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = ctx; 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = sess->server; 1991f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int ret; 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1993f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ret = data->get_eap_user(data->conf_ctx, identity, identity_len, 1994f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt phase2, user); 1995818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (ret == 0 && user) { 1996818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt sess->accept_attr = user->accept_attr; 1997f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt sess->remediation = user->remediation; 1998df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt sess->macacl = user->macacl; 1999818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 2000f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return ret; 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len) 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *sess = ctx; 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_server_data *data = sess->server; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = data->eap_req_id_text_len; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->eap_req_id_text; 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2013818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void radius_server_log_msg(void *ctx, const char *msg) 2014818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 2015818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct radius_session *sess = ctx; 2016818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt srv_log(sess, "EAP: %s", msg); 2017818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 2018818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 2019818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eapol_callbacks radius_server_eapol_cb = 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_eap_user = radius_server_get_eap_user, 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt .get_eap_req_id_text = radius_server_get_eap_req_id_text, 2024818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt .log_msg = radius_server_log_msg, 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * radius_server_eap_pending_cb - Pending EAP data notification 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: RADIUS server context from radius_server_init() 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Pending EAP context pointer 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to notify EAP server module that a pending operation 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been completed and processing of the EAP session can proceed. 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx) 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client *cli; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_session *s, *sess = NULL; 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (cli = data->clients; cli; cli = cli->next) { 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = cli->sessions; s; s = s->next) { 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s->eap == ctx && s->last_msg) { 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess = s; 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess) 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess) 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sess == NULL) { 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_DEBUG("No session matched callback ctx"); 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = sess->last_msg; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_msg = NULL; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_pending_cb(sess->eap); 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (radius_server_request(data, msg, 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct sockaddr *) &sess->last_from, 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_fromlen, cli, 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_addr, 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sess->last_from_port, sess) == -2) 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* msg was stored with the session */ 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2075