radius_server.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168
  1. /*
  2. * RADIUS authentication server
  3. * Copyright (c) 2005-2009, 2011-2014, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include <net/if.h>
  10. #ifdef CONFIG_SQLITE
  11. #include <sqlite3.h>
  12. #endif /* CONFIG_SQLITE */
  13. #include "common.h"
  14. #include "radius.h"
  15. #include "eloop.h"
  16. #include "eap_server/eap.h"
  17. #include "ap/ap_config.h"
  18. #include "crypto/tls.h"
  19. #include "radius_server.h"
  20. /**
  21. * RADIUS_SESSION_TIMEOUT - Session timeout in seconds
  22. */
  23. #define RADIUS_SESSION_TIMEOUT 60
  24. /**
  25. * RADIUS_MAX_SESSION - Maximum number of active sessions
  26. */
  27. #define RADIUS_MAX_SESSION 100
  28. /**
  29. * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
  30. */
  31. #define RADIUS_MAX_MSG_LEN 3000
  32. static const struct eapol_callbacks radius_server_eapol_cb;
  33. struct radius_client;
  34. struct radius_server_data;
  35. /**
  36. * struct radius_server_counters - RADIUS server statistics counters
  37. */
  38. struct radius_server_counters {
  39. u32 access_requests;
  40. u32 invalid_requests;
  41. u32 dup_access_requests;
  42. u32 access_accepts;
  43. u32 access_rejects;
  44. u32 access_challenges;
  45. u32 malformed_access_requests;
  46. u32 bad_authenticators;
  47. u32 packets_dropped;
  48. u32 unknown_types;
  49. u32 acct_requests;
  50. u32 invalid_acct_requests;
  51. u32 acct_responses;
  52. u32 malformed_acct_requests;
  53. u32 acct_bad_authenticators;
  54. u32 unknown_acct_types;
  55. };
  56. /**
  57. * struct radius_session - Internal RADIUS server data for a session
  58. */
  59. struct radius_session {
  60. struct radius_session *next;
  61. struct radius_client *client;
  62. struct radius_server_data *server;
  63. unsigned int sess_id;
  64. struct eap_sm *eap;
  65. struct eap_eapol_interface *eap_if;
  66. char *username; /* from User-Name attribute */
  67. char *nas_ip;
  68. struct radius_msg *last_msg;
  69. char *last_from_addr;
  70. int last_from_port;
  71. struct sockaddr_storage last_from;
  72. socklen_t last_fromlen;
  73. u8 last_identifier;
  74. struct radius_msg *last_reply;
  75. u8 last_authenticator[16];
  76. unsigned int remediation:1;
  77. unsigned int macacl:1;
  78. struct hostapd_radius_attr *accept_attr;
  79. };
  80. /**
  81. * struct radius_client - Internal RADIUS server data for a client
  82. */
  83. struct radius_client {
  84. struct radius_client *next;
  85. struct in_addr addr;
  86. struct in_addr mask;
  87. #ifdef CONFIG_IPV6
  88. struct in6_addr addr6;
  89. struct in6_addr mask6;
  90. #endif /* CONFIG_IPV6 */
  91. char *shared_secret;
  92. int shared_secret_len;
  93. struct radius_session *sessions;
  94. struct radius_server_counters counters;
  95. };
  96. /**
  97. * struct radius_server_data - Internal RADIUS server data
  98. */
  99. struct radius_server_data {
  100. /**
  101. * auth_sock - Socket for RADIUS authentication messages
  102. */
  103. int auth_sock;
  104. /**
  105. * acct_sock - Socket for RADIUS accounting messages
  106. */
  107. int acct_sock;
  108. /**
  109. * clients - List of authorized RADIUS clients
  110. */
  111. struct radius_client *clients;
  112. /**
  113. * next_sess_id - Next session identifier
  114. */
  115. unsigned int next_sess_id;
  116. /**
  117. * conf_ctx - Context pointer for callbacks
  118. *
  119. * This is used as the ctx argument in get_eap_user() calls.
  120. */
  121. void *conf_ctx;
  122. /**
  123. * num_sess - Number of active sessions
  124. */
  125. int num_sess;
  126. /**
  127. * eap_sim_db_priv - EAP-SIM/AKA database context
  128. *
  129. * This is passed to the EAP-SIM/AKA server implementation as a
  130. * callback context.
  131. */
  132. void *eap_sim_db_priv;
  133. /**
  134. * ssl_ctx - TLS context
  135. *
  136. * This is passed to the EAP server implementation as a callback
  137. * context for TLS operations.
  138. */
  139. void *ssl_ctx;
  140. /**
  141. * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST
  142. *
  143. * This parameter is used to set a key for EAP-FAST to encrypt the
  144. * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If
  145. * set, must point to a 16-octet key.
  146. */
  147. u8 *pac_opaque_encr_key;
  148. /**
  149. * eap_fast_a_id - EAP-FAST authority identity (A-ID)
  150. *
  151. * If EAP-FAST is not used, this can be set to %NULL. In theory, this
  152. * is a variable length field, but due to some existing implementations
  153. * requiring A-ID to be 16 octets in length, it is recommended to use
  154. * that length for the field to provide interoperability with deployed
  155. * peer implementations.
  156. */
  157. u8 *eap_fast_a_id;
  158. /**
  159. * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets
  160. */
  161. size_t eap_fast_a_id_len;
  162. /**
  163. * eap_fast_a_id_info - EAP-FAST authority identifier information
  164. *
  165. * This A-ID-Info contains a user-friendly name for the A-ID. For
  166. * example, this could be the enterprise and server names in
  167. * human-readable format. This field is encoded as UTF-8. If EAP-FAST
  168. * is not used, this can be set to %NULL.
  169. */
  170. char *eap_fast_a_id_info;
  171. /**
  172. * eap_fast_prov - EAP-FAST provisioning modes
  173. *
  174. * 0 = provisioning disabled, 1 = only anonymous provisioning allowed,
  175. * 2 = only authenticated provisioning allowed, 3 = both provisioning
  176. * modes allowed.
  177. */
  178. int eap_fast_prov;
  179. /**
  180. * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds
  181. *
  182. * This is the hard limit on how long a provisioned PAC-Key can be
  183. * used.
  184. */
  185. int pac_key_lifetime;
  186. /**
  187. * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds
  188. *
  189. * This is a soft limit on the PAC-Key. The server will automatically
  190. * generate a new PAC-Key when this number of seconds (or fewer) of the
  191. * lifetime remains.
  192. */
  193. int pac_key_refresh_time;
  194. /**
  195. * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
  196. *
  197. * This controls whether the protected success/failure indication
  198. * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA.
  199. */
  200. int eap_sim_aka_result_ind;
  201. /**
  202. * tnc - Trusted Network Connect (TNC)
  203. *
  204. * This controls whether TNC is enabled and will be required before the
  205. * peer is allowed to connect. Note: This is only used with EAP-TTLS
  206. * and EAP-FAST. If any other EAP method is enabled, the peer will be
  207. * allowed to connect without TNC.
  208. */
  209. int tnc;
  210. /**
  211. * pwd_group - The D-H group assigned for EAP-pwd
  212. *
  213. * If EAP-pwd is not used it can be set to zero.
  214. */
  215. u16 pwd_group;
  216. /**
  217. * server_id - Server identity
  218. */
  219. const char *server_id;
  220. /**
  221. * erp - Whether EAP Re-authentication Protocol (ERP) is enabled
  222. *
  223. * This controls whether the authentication server derives ERP key
  224. * hierarchy (rRK and rIK) from full EAP authentication and allows
  225. * these keys to be used to perform ERP to derive rMSK instead of full
  226. * EAP authentication to derive MSK.
  227. */
  228. int erp;
  229. const char *erp_domain;
  230. struct dl_list erp_keys; /* struct eap_server_erp_key */
  231. unsigned int tls_session_lifetime;
  232. /**
  233. * wps - Wi-Fi Protected Setup context
  234. *
  235. * If WPS is used with an external RADIUS server (which is quite
  236. * unlikely configuration), this is used to provide a pointer to WPS
  237. * context data. Normally, this can be set to %NULL.
  238. */
  239. struct wps_context *wps;
  240. /**
  241. * ipv6 - Whether to enable IPv6 support in the RADIUS server
  242. */
  243. int ipv6;
  244. /**
  245. * start_time - Timestamp of server start
  246. */
  247. struct os_reltime start_time;
  248. /**
  249. * counters - Statistics counters for server operations
  250. *
  251. * These counters are the sum over all clients.
  252. */
  253. struct radius_server_counters counters;
  254. /**
  255. * get_eap_user - Callback for fetching EAP user information
  256. * @ctx: Context data from conf_ctx
  257. * @identity: User identity
  258. * @identity_len: identity buffer length in octets
  259. * @phase2: Whether this is for Phase 2 identity
  260. * @user: Data structure for filling in the user information
  261. * Returns: 0 on success, -1 on failure
  262. *
  263. * This is used to fetch information from user database. The callback
  264. * will fill in information about allowed EAP methods and the user
  265. * password. The password field will be an allocated copy of the
  266. * password data and RADIUS server will free it after use.
  267. */
  268. int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
  269. int phase2, struct eap_user *user);
  270. /**
  271. * eap_req_id_text - Optional data for EAP-Request/Identity
  272. *
  273. * This can be used to configure an optional, displayable message that
  274. * will be sent in EAP-Request/Identity. This string can contain an
  275. * ASCII-0 character (nul) to separate network infromation per RFC
  276. * 4284. The actual string length is explicit provided in
  277. * eap_req_id_text_len since nul character will not be used as a string
  278. * terminator.
  279. */
  280. char *eap_req_id_text;
  281. /**
  282. * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
  283. */
  284. size_t eap_req_id_text_len;
  285. /*
  286. * msg_ctx - Context data for wpa_msg() calls
  287. */
  288. void *msg_ctx;
  289. #ifdef CONFIG_RADIUS_TEST
  290. char *dump_msk_file;
  291. #endif /* CONFIG_RADIUS_TEST */
  292. char *subscr_remediation_url;
  293. u8 subscr_remediation_method;
  294. #ifdef CONFIG_SQLITE
  295. sqlite3 *db;
  296. #endif /* CONFIG_SQLITE */
  297. };
  298. #define RADIUS_DEBUG(args...) \
  299. wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
  300. #define RADIUS_ERROR(args...) \
  301. wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
  302. #define RADIUS_DUMP(args...) \
  303. wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
  304. #define RADIUS_DUMP_ASCII(args...) \
  305. wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
  306. static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
  307. static void radius_server_session_remove_timeout(void *eloop_ctx,
  308. void *timeout_ctx);
  309. void srv_log(struct radius_session *sess, const char *fmt, ...)
  310. PRINTF_FORMAT(2, 3);
  311. void srv_log(struct radius_session *sess, const char *fmt, ...)
  312. {
  313. va_list ap;
  314. char *buf;
  315. int buflen;
  316. va_start(ap, fmt);
  317. buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
  318. va_end(ap);
  319. buf = os_malloc(buflen);
  320. if (buf == NULL)
  321. return;
  322. va_start(ap, fmt);
  323. vsnprintf(buf, buflen, fmt, ap);
  324. va_end(ap);
  325. RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf);
  326. #ifdef CONFIG_SQLITE
  327. if (sess->server->db) {
  328. char *sql;
  329. sql = sqlite3_mprintf("INSERT INTO authlog"
  330. "(timestamp,session,nas_ip,username,note)"
  331. " VALUES ("
  332. "strftime('%%Y-%%m-%%d %%H:%%M:%%f',"
  333. "'now'),%u,%Q,%Q,%Q)",
  334. sess->sess_id, sess->nas_ip,
  335. sess->username, buf);
  336. if (sql) {
  337. if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
  338. NULL) != SQLITE_OK) {
  339. RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s",
  340. sqlite3_errmsg(sess->server->db));
  341. }
  342. sqlite3_free(sql);
  343. }
  344. }
  345. #endif /* CONFIG_SQLITE */
  346. os_free(buf);
  347. }
  348. static struct radius_client *
  349. radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
  350. int ipv6)
  351. {
  352. struct radius_client *client = data->clients;
  353. while (client) {
  354. #ifdef CONFIG_IPV6
  355. if (ipv6) {
  356. struct in6_addr *addr6;
  357. int i;
  358. addr6 = (struct in6_addr *) addr;
  359. for (i = 0; i < 16; i++) {
  360. if ((addr6->s6_addr[i] &
  361. client->mask6.s6_addr[i]) !=
  362. (client->addr6.s6_addr[i] &
  363. client->mask6.s6_addr[i])) {
  364. i = 17;
  365. break;
  366. }
  367. }
  368. if (i == 16) {
  369. break;
  370. }
  371. }
  372. #endif /* CONFIG_IPV6 */
  373. if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
  374. (addr->s_addr & client->mask.s_addr)) {
  375. break;
  376. }
  377. client = client->next;
  378. }
  379. return client;
  380. }
  381. static struct radius_session *
  382. radius_server_get_session(struct radius_client *client, unsigned int sess_id)
  383. {
  384. struct radius_session *sess = client->sessions;
  385. while (sess) {
  386. if (sess->sess_id == sess_id) {
  387. break;
  388. }
  389. sess = sess->next;
  390. }
  391. return sess;
  392. }
  393. static void radius_server_session_free(struct radius_server_data *data,
  394. struct radius_session *sess)
  395. {
  396. eloop_cancel_timeout(radius_server_session_timeout, data, sess);
  397. eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
  398. eap_server_sm_deinit(sess->eap);
  399. radius_msg_free(sess->last_msg);
  400. os_free(sess->last_from_addr);
  401. radius_msg_free(sess->last_reply);
  402. os_free(sess->username);
  403. os_free(sess->nas_ip);
  404. os_free(sess);
  405. data->num_sess--;
  406. }
  407. static void radius_server_session_remove(struct radius_server_data *data,
  408. struct radius_session *sess)
  409. {
  410. struct radius_client *client = sess->client;
  411. struct radius_session *session, *prev;
  412. eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
  413. prev = NULL;
  414. session = client->sessions;
  415. while (session) {
  416. if (session == sess) {
  417. if (prev == NULL) {
  418. client->sessions = sess->next;
  419. } else {
  420. prev->next = sess->next;
  421. }
  422. radius_server_session_free(data, sess);
  423. break;
  424. }
  425. prev = session;
  426. session = session->next;
  427. }
  428. }
  429. static void radius_server_session_remove_timeout(void *eloop_ctx,
  430. void *timeout_ctx)
  431. {
  432. struct radius_server_data *data = eloop_ctx;
  433. struct radius_session *sess = timeout_ctx;
  434. RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
  435. radius_server_session_remove(data, sess);
  436. }
  437. static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
  438. {
  439. struct radius_server_data *data = eloop_ctx;
  440. struct radius_session *sess = timeout_ctx;
  441. RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
  442. radius_server_session_remove(data, sess);
  443. }
  444. static struct radius_session *
  445. radius_server_new_session(struct radius_server_data *data,
  446. struct radius_client *client)
  447. {
  448. struct radius_session *sess;
  449. if (data->num_sess >= RADIUS_MAX_SESSION) {
  450. RADIUS_DEBUG("Maximum number of existing session - no room "
  451. "for a new session");
  452. return NULL;
  453. }
  454. sess = os_zalloc(sizeof(*sess));
  455. if (sess == NULL)
  456. return NULL;
  457. sess->server = data;
  458. sess->client = client;
  459. sess->sess_id = data->next_sess_id++;
  460. sess->next = client->sessions;
  461. client->sessions = sess;
  462. eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
  463. radius_server_session_timeout, data, sess);
  464. data->num_sess++;
  465. return sess;
  466. }
  467. #ifdef CONFIG_TESTING_OPTIONS
  468. static void radius_server_testing_options_tls(struct radius_session *sess,
  469. const char *tls,
  470. struct eap_config *eap_conf)
  471. {
  472. int test = atoi(tls);
  473. switch (test) {
  474. case 1:
  475. srv_log(sess, "TLS test - break VerifyData");
  476. eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA;
  477. break;
  478. case 2:
  479. srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash");
  480. eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH;
  481. break;
  482. case 3:
  483. srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature");
  484. eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE;
  485. break;
  486. case 4:
  487. srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime");
  488. eap_conf->tls_test_flags = TLS_DHE_PRIME_511B;
  489. break;
  490. case 5:
  491. srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime");
  492. eap_conf->tls_test_flags = TLS_DHE_PRIME_767B;
  493. break;
  494. case 6:
  495. srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\"");
  496. eap_conf->tls_test_flags = TLS_DHE_PRIME_15;
  497. break;
  498. case 7:
  499. srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container");
  500. eap_conf->tls_test_flags = TLS_DHE_PRIME_58B;
  501. break;
  502. case 8:
  503. srv_log(sess, "TLS test - RSA-DHE using a non-prime");
  504. eap_conf->tls_test_flags = TLS_DHE_NON_PRIME;
  505. break;
  506. default:
  507. srv_log(sess, "Unrecognized TLS test");
  508. break;
  509. }
  510. }
  511. #endif /* CONFIG_TESTING_OPTIONS */
  512. static void radius_server_testing_options(struct radius_session *sess,
  513. struct eap_config *eap_conf)
  514. {
  515. #ifdef CONFIG_TESTING_OPTIONS
  516. const char *pos;
  517. pos = os_strstr(sess->username, "@test-");
  518. if (pos == NULL)
  519. return;
  520. pos += 6;
  521. if (os_strncmp(pos, "tls-", 4) == 0)
  522. radius_server_testing_options_tls(sess, pos + 4, eap_conf);
  523. else
  524. srv_log(sess, "Unrecognized test: %s", pos);
  525. #endif /* CONFIG_TESTING_OPTIONS */
  526. }
  527. static struct radius_session *
  528. radius_server_get_new_session(struct radius_server_data *data,
  529. struct radius_client *client,
  530. struct radius_msg *msg, const char *from_addr)
  531. {
  532. u8 *user;
  533. size_t user_len;
  534. int res;
  535. struct radius_session *sess;
  536. struct eap_config eap_conf;
  537. struct eap_user tmp;
  538. RADIUS_DEBUG("Creating a new session");
  539. if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user,
  540. &user_len, NULL) < 0) {
  541. RADIUS_DEBUG("Could not get User-Name");
  542. return NULL;
  543. }
  544. RADIUS_DUMP_ASCII("User-Name", user, user_len);
  545. os_memset(&tmp, 0, sizeof(tmp));
  546. res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
  547. bin_clear_free(tmp.password, tmp.password_len);
  548. if (res != 0) {
  549. RADIUS_DEBUG("User-Name not found from user database");
  550. return NULL;
  551. }
  552. RADIUS_DEBUG("Matching user entry found");
  553. sess = radius_server_new_session(data, client);
  554. if (sess == NULL) {
  555. RADIUS_DEBUG("Failed to create a new session");
  556. return NULL;
  557. }
  558. sess->accept_attr = tmp.accept_attr;
  559. sess->macacl = tmp.macacl;
  560. sess->username = os_malloc(user_len * 4 + 1);
  561. if (sess->username == NULL) {
  562. radius_server_session_free(data, sess);
  563. return NULL;
  564. }
  565. printf_encode(sess->username, user_len * 4 + 1, user, user_len);
  566. sess->nas_ip = os_strdup(from_addr);
  567. if (sess->nas_ip == NULL) {
  568. radius_server_session_free(data, sess);
  569. return NULL;
  570. }
  571. srv_log(sess, "New session created");
  572. os_memset(&eap_conf, 0, sizeof(eap_conf));
  573. eap_conf.ssl_ctx = data->ssl_ctx;
  574. eap_conf.msg_ctx = data->msg_ctx;
  575. eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
  576. eap_conf.backend_auth = TRUE;
  577. eap_conf.eap_server = 1;
  578. eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
  579. eap_conf.eap_fast_a_id = data->eap_fast_a_id;
  580. eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len;
  581. eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info;
  582. eap_conf.eap_fast_prov = data->eap_fast_prov;
  583. eap_conf.pac_key_lifetime = data->pac_key_lifetime;
  584. eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
  585. eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
  586. eap_conf.tnc = data->tnc;
  587. eap_conf.wps = data->wps;
  588. eap_conf.pwd_group = data->pwd_group;
  589. eap_conf.server_id = (const u8 *) data->server_id;
  590. eap_conf.server_id_len = os_strlen(data->server_id);
  591. eap_conf.erp = data->erp;
  592. eap_conf.tls_session_lifetime = data->tls_session_lifetime;
  593. radius_server_testing_options(sess, &eap_conf);
  594. sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
  595. &eap_conf);
  596. if (sess->eap == NULL) {
  597. RADIUS_DEBUG("Failed to initialize EAP state machine for the "
  598. "new session");
  599. radius_server_session_free(data, sess);
  600. return NULL;
  601. }
  602. sess->eap_if = eap_get_interface(sess->eap);
  603. sess->eap_if->eapRestart = TRUE;
  604. sess->eap_if->portEnabled = TRUE;
  605. RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
  606. return sess;
  607. }
  608. static struct radius_msg *
  609. radius_server_encapsulate_eap(struct radius_server_data *data,
  610. struct radius_client *client,
  611. struct radius_session *sess,
  612. struct radius_msg *request)
  613. {
  614. struct radius_msg *msg;
  615. int code;
  616. unsigned int sess_id;
  617. struct radius_hdr *hdr = radius_msg_get_hdr(request);
  618. if (sess->eap_if->eapFail) {
  619. sess->eap_if->eapFail = FALSE;
  620. code = RADIUS_CODE_ACCESS_REJECT;
  621. } else if (sess->eap_if->eapSuccess) {
  622. sess->eap_if->eapSuccess = FALSE;
  623. code = RADIUS_CODE_ACCESS_ACCEPT;
  624. } else {
  625. sess->eap_if->eapReq = FALSE;
  626. code = RADIUS_CODE_ACCESS_CHALLENGE;
  627. }
  628. msg = radius_msg_new(code, hdr->identifier);
  629. if (msg == NULL) {
  630. RADIUS_DEBUG("Failed to allocate reply message");
  631. return NULL;
  632. }
  633. sess_id = htonl(sess->sess_id);
  634. if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
  635. !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
  636. (u8 *) &sess_id, sizeof(sess_id))) {
  637. RADIUS_DEBUG("Failed to add State attribute");
  638. }
  639. if (sess->eap_if->eapReqData &&
  640. !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
  641. wpabuf_len(sess->eap_if->eapReqData))) {
  642. RADIUS_DEBUG("Failed to add EAP-Message attribute");
  643. }
  644. if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
  645. int len;
  646. #ifdef CONFIG_RADIUS_TEST
  647. if (data->dump_msk_file) {
  648. FILE *f;
  649. char buf[2 * 64 + 1];
  650. f = fopen(data->dump_msk_file, "a");
  651. if (f) {
  652. len = sess->eap_if->eapKeyDataLen;
  653. if (len > 64)
  654. len = 64;
  655. len = wpa_snprintf_hex(
  656. buf, sizeof(buf),
  657. sess->eap_if->eapKeyData, len);
  658. buf[len] = '\0';
  659. fprintf(f, "%s\n", buf);
  660. fclose(f);
  661. }
  662. }
  663. #endif /* CONFIG_RADIUS_TEST */
  664. if (sess->eap_if->eapKeyDataLen > 64) {
  665. len = 32;
  666. } else {
  667. len = sess->eap_if->eapKeyDataLen / 2;
  668. }
  669. if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
  670. (u8 *) client->shared_secret,
  671. client->shared_secret_len,
  672. sess->eap_if->eapKeyData + len,
  673. len, sess->eap_if->eapKeyData,
  674. len)) {
  675. RADIUS_DEBUG("Failed to add MPPE key attributes");
  676. }
  677. }
  678. #ifdef CONFIG_HS20
  679. if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation &&
  680. data->subscr_remediation_url) {
  681. u8 *buf;
  682. size_t url_len = os_strlen(data->subscr_remediation_url);
  683. buf = os_malloc(1 + url_len);
  684. if (buf == NULL) {
  685. radius_msg_free(msg);
  686. return NULL;
  687. }
  688. buf[0] = data->subscr_remediation_method;
  689. os_memcpy(&buf[1], data->subscr_remediation_url, url_len);
  690. if (!radius_msg_add_wfa(
  691. msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
  692. buf, 1 + url_len)) {
  693. RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
  694. }
  695. os_free(buf);
  696. } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) {
  697. u8 buf[1];
  698. if (!radius_msg_add_wfa(
  699. msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
  700. buf, 0)) {
  701. RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
  702. }
  703. }
  704. #endif /* CONFIG_HS20 */
  705. if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
  706. RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
  707. radius_msg_free(msg);
  708. return NULL;
  709. }
  710. if (code == RADIUS_CODE_ACCESS_ACCEPT) {
  711. struct hostapd_radius_attr *attr;
  712. for (attr = sess->accept_attr; attr; attr = attr->next) {
  713. if (!radius_msg_add_attr(msg, attr->type,
  714. wpabuf_head(attr->val),
  715. wpabuf_len(attr->val))) {
  716. wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
  717. radius_msg_free(msg);
  718. return NULL;
  719. }
  720. }
  721. }
  722. if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
  723. client->shared_secret_len,
  724. hdr->authenticator) < 0) {
  725. RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
  726. }
  727. return msg;
  728. }
  729. static struct radius_msg *
  730. radius_server_macacl(struct radius_server_data *data,
  731. struct radius_client *client,
  732. struct radius_session *sess,
  733. struct radius_msg *request)
  734. {
  735. struct radius_msg *msg;
  736. int code;
  737. struct radius_hdr *hdr = radius_msg_get_hdr(request);
  738. u8 *pw;
  739. size_t pw_len;
  740. code = RADIUS_CODE_ACCESS_ACCEPT;
  741. if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw,
  742. &pw_len, NULL) < 0) {
  743. RADIUS_DEBUG("Could not get User-Password");
  744. code = RADIUS_CODE_ACCESS_REJECT;
  745. } else {
  746. int res;
  747. struct eap_user tmp;
  748. os_memset(&tmp, 0, sizeof(tmp));
  749. res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username,
  750. os_strlen(sess->username), 0, &tmp);
  751. if (res || !tmp.macacl || tmp.password == NULL) {
  752. RADIUS_DEBUG("No MAC ACL user entry");
  753. bin_clear_free(tmp.password, tmp.password_len);
  754. code = RADIUS_CODE_ACCESS_REJECT;
  755. } else {
  756. u8 buf[128];
  757. res = radius_user_password_hide(
  758. request, tmp.password, tmp.password_len,
  759. (u8 *) client->shared_secret,
  760. client->shared_secret_len,
  761. buf, sizeof(buf));
  762. bin_clear_free(tmp.password, tmp.password_len);
  763. if (res < 0 || pw_len != (size_t) res ||
  764. os_memcmp_const(pw, buf, res) != 0) {
  765. RADIUS_DEBUG("Incorrect User-Password");
  766. code = RADIUS_CODE_ACCESS_REJECT;
  767. }
  768. }
  769. }
  770. msg = radius_msg_new(code, hdr->identifier);
  771. if (msg == NULL) {
  772. RADIUS_DEBUG("Failed to allocate reply message");
  773. return NULL;
  774. }
  775. if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
  776. RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
  777. radius_msg_free(msg);
  778. return NULL;
  779. }
  780. if (code == RADIUS_CODE_ACCESS_ACCEPT) {
  781. struct hostapd_radius_attr *attr;
  782. for (attr = sess->accept_attr; attr; attr = attr->next) {
  783. if (!radius_msg_add_attr(msg, attr->type,
  784. wpabuf_head(attr->val),
  785. wpabuf_len(attr->val))) {
  786. wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
  787. radius_msg_free(msg);
  788. return NULL;
  789. }
  790. }
  791. }
  792. if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
  793. client->shared_secret_len,
  794. hdr->authenticator) < 0) {
  795. RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
  796. }
  797. return msg;
  798. }
  799. static int radius_server_reject(struct radius_server_data *data,
  800. struct radius_client *client,
  801. struct radius_msg *request,
  802. struct sockaddr *from, socklen_t fromlen,
  803. const char *from_addr, int from_port)
  804. {
  805. struct radius_msg *msg;
  806. int ret = 0;
  807. struct eap_hdr eapfail;
  808. struct wpabuf *buf;
  809. struct radius_hdr *hdr = radius_msg_get_hdr(request);
  810. RADIUS_DEBUG("Reject invalid request from %s:%d",
  811. from_addr, from_port);
  812. msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
  813. if (msg == NULL) {
  814. return -1;
  815. }
  816. os_memset(&eapfail, 0, sizeof(eapfail));
  817. eapfail.code = EAP_CODE_FAILURE;
  818. eapfail.identifier = 0;
  819. eapfail.length = host_to_be16(sizeof(eapfail));
  820. if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
  821. RADIUS_DEBUG("Failed to add EAP-Message attribute");
  822. }
  823. if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
  824. RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
  825. radius_msg_free(msg);
  826. return -1;
  827. }
  828. if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
  829. client->shared_secret_len,
  830. hdr->authenticator) <
  831. 0) {
  832. RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
  833. }
  834. if (wpa_debug_level <= MSG_MSGDUMP) {
  835. radius_msg_dump(msg);
  836. }
  837. data->counters.access_rejects++;
  838. client->counters.access_rejects++;
  839. buf = radius_msg_get_buf(msg);
  840. if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
  841. (struct sockaddr *) from, sizeof(*from)) < 0) {
  842. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
  843. ret = -1;
  844. }
  845. radius_msg_free(msg);
  846. return ret;
  847. }
  848. static int radius_server_request(struct radius_server_data *data,
  849. struct radius_msg *msg,
  850. struct sockaddr *from, socklen_t fromlen,
  851. struct radius_client *client,
  852. const char *from_addr, int from_port,
  853. struct radius_session *force_sess)
  854. {
  855. struct wpabuf *eap = NULL;
  856. int res, state_included = 0;
  857. u8 statebuf[4];
  858. unsigned int state;
  859. struct radius_session *sess;
  860. struct radius_msg *reply;
  861. int is_complete = 0;
  862. if (force_sess)
  863. sess = force_sess;
  864. else {
  865. res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
  866. sizeof(statebuf));
  867. state_included = res >= 0;
  868. if (res == sizeof(statebuf)) {
  869. state = WPA_GET_BE32(statebuf);
  870. sess = radius_server_get_session(client, state);
  871. } else {
  872. sess = NULL;
  873. }
  874. }
  875. if (sess) {
  876. RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
  877. } else if (state_included) {
  878. RADIUS_DEBUG("State attribute included but no session found");
  879. radius_server_reject(data, client, msg, from, fromlen,
  880. from_addr, from_port);
  881. return -1;
  882. } else {
  883. sess = radius_server_get_new_session(data, client, msg,
  884. from_addr);
  885. if (sess == NULL) {
  886. RADIUS_DEBUG("Could not create a new session");
  887. radius_server_reject(data, client, msg, from, fromlen,
  888. from_addr, from_port);
  889. return -1;
  890. }
  891. }
  892. if (sess->last_from_port == from_port &&
  893. sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
  894. os_memcmp(sess->last_authenticator,
  895. radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
  896. RADIUS_DEBUG("Duplicate message from %s", from_addr);
  897. data->counters.dup_access_requests++;
  898. client->counters.dup_access_requests++;
  899. if (sess->last_reply) {
  900. struct wpabuf *buf;
  901. buf = radius_msg_get_buf(sess->last_reply);
  902. res = sendto(data->auth_sock, wpabuf_head(buf),
  903. wpabuf_len(buf), 0,
  904. (struct sockaddr *) from, fromlen);
  905. if (res < 0) {
  906. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
  907. strerror(errno));
  908. }
  909. return 0;
  910. }
  911. RADIUS_DEBUG("No previous reply available for duplicate "
  912. "message");
  913. return -1;
  914. }
  915. eap = radius_msg_get_eap(msg);
  916. if (eap == NULL && sess->macacl) {
  917. reply = radius_server_macacl(data, client, sess, msg);
  918. if (reply == NULL)
  919. return -1;
  920. goto send_reply;
  921. }
  922. if (eap == NULL) {
  923. RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
  924. from_addr);
  925. data->counters.packets_dropped++;
  926. client->counters.packets_dropped++;
  927. return -1;
  928. }
  929. RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
  930. /* FIX: if Code is Request, Success, or Failure, send Access-Reject;
  931. * RFC3579 Sect. 2.6.2.
  932. * Include EAP-Response/Nak with no preferred method if
  933. * code == request.
  934. * If code is not 1-4, discard the packet silently.
  935. * Or is this already done by the EAP state machine? */
  936. wpabuf_free(sess->eap_if->eapRespData);
  937. sess->eap_if->eapRespData = eap;
  938. sess->eap_if->eapResp = TRUE;
  939. eap_server_sm_step(sess->eap);
  940. if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
  941. sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
  942. RADIUS_DUMP("EAP data from the state machine",
  943. wpabuf_head(sess->eap_if->eapReqData),
  944. wpabuf_len(sess->eap_if->eapReqData));
  945. } else if (sess->eap_if->eapFail) {
  946. RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
  947. "set");
  948. } else if (eap_sm_method_pending(sess->eap)) {
  949. radius_msg_free(sess->last_msg);
  950. sess->last_msg = msg;
  951. sess->last_from_port = from_port;
  952. os_free(sess->last_from_addr);
  953. sess->last_from_addr = os_strdup(from_addr);
  954. sess->last_fromlen = fromlen;
  955. os_memcpy(&sess->last_from, from, fromlen);
  956. return -2;
  957. } else {
  958. RADIUS_DEBUG("No EAP data from the state machine - ignore this"
  959. " Access-Request silently (assuming it was a "
  960. "duplicate)");
  961. data->counters.packets_dropped++;
  962. client->counters.packets_dropped++;
  963. return -1;
  964. }
  965. if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
  966. is_complete = 1;
  967. if (sess->eap_if->eapFail)
  968. srv_log(sess, "EAP authentication failed");
  969. else if (sess->eap_if->eapSuccess)
  970. srv_log(sess, "EAP authentication succeeded");
  971. reply = radius_server_encapsulate_eap(data, client, sess, msg);
  972. send_reply:
  973. if (reply) {
  974. struct wpabuf *buf;
  975. struct radius_hdr *hdr;
  976. RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
  977. if (wpa_debug_level <= MSG_MSGDUMP) {
  978. radius_msg_dump(reply);
  979. }
  980. switch (radius_msg_get_hdr(reply)->code) {
  981. case RADIUS_CODE_ACCESS_ACCEPT:
  982. srv_log(sess, "Sending Access-Accept");
  983. data->counters.access_accepts++;
  984. client->counters.access_accepts++;
  985. break;
  986. case RADIUS_CODE_ACCESS_REJECT:
  987. srv_log(sess, "Sending Access-Reject");
  988. data->counters.access_rejects++;
  989. client->counters.access_rejects++;
  990. break;
  991. case RADIUS_CODE_ACCESS_CHALLENGE:
  992. data->counters.access_challenges++;
  993. client->counters.access_challenges++;
  994. break;
  995. }
  996. buf = radius_msg_get_buf(reply);
  997. res = sendto(data->auth_sock, wpabuf_head(buf),
  998. wpabuf_len(buf), 0,
  999. (struct sockaddr *) from, fromlen);
  1000. if (res < 0) {
  1001. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
  1002. strerror(errno));
  1003. }
  1004. radius_msg_free(sess->last_reply);
  1005. sess->last_reply = reply;
  1006. sess->last_from_port = from_port;
  1007. hdr = radius_msg_get_hdr(msg);
  1008. sess->last_identifier = hdr->identifier;
  1009. os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
  1010. } else {
  1011. data->counters.packets_dropped++;
  1012. client->counters.packets_dropped++;
  1013. }
  1014. if (is_complete) {
  1015. RADIUS_DEBUG("Removing completed session 0x%x after timeout",
  1016. sess->sess_id);
  1017. eloop_cancel_timeout(radius_server_session_remove_timeout,
  1018. data, sess);
  1019. eloop_register_timeout(10, 0,
  1020. radius_server_session_remove_timeout,
  1021. data, sess);
  1022. }
  1023. return 0;
  1024. }
  1025. static void radius_server_receive_auth(int sock, void *eloop_ctx,
  1026. void *sock_ctx)
  1027. {
  1028. struct radius_server_data *data = eloop_ctx;
  1029. u8 *buf = NULL;
  1030. union {
  1031. struct sockaddr_storage ss;
  1032. struct sockaddr_in sin;
  1033. #ifdef CONFIG_IPV6
  1034. struct sockaddr_in6 sin6;
  1035. #endif /* CONFIG_IPV6 */
  1036. } from;
  1037. socklen_t fromlen;
  1038. int len;
  1039. struct radius_client *client = NULL;
  1040. struct radius_msg *msg = NULL;
  1041. char abuf[50];
  1042. int from_port = 0;
  1043. buf = os_malloc(RADIUS_MAX_MSG_LEN);
  1044. if (buf == NULL) {
  1045. goto fail;
  1046. }
  1047. fromlen = sizeof(from);
  1048. len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
  1049. (struct sockaddr *) &from.ss, &fromlen);
  1050. if (len < 0) {
  1051. wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
  1052. strerror(errno));
  1053. goto fail;
  1054. }
  1055. #ifdef CONFIG_IPV6
  1056. if (data->ipv6) {
  1057. if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
  1058. sizeof(abuf)) == NULL)
  1059. abuf[0] = '\0';
  1060. from_port = ntohs(from.sin6.sin6_port);
  1061. RADIUS_DEBUG("Received %d bytes from %s:%d",
  1062. len, abuf, from_port);
  1063. client = radius_server_get_client(data,
  1064. (struct in_addr *)
  1065. &from.sin6.sin6_addr, 1);
  1066. }
  1067. #endif /* CONFIG_IPV6 */
  1068. if (!data->ipv6) {
  1069. os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
  1070. from_port = ntohs(from.sin.sin_port);
  1071. RADIUS_DEBUG("Received %d bytes from %s:%d",
  1072. len, abuf, from_port);
  1073. client = radius_server_get_client(data, &from.sin.sin_addr, 0);
  1074. }
  1075. RADIUS_DUMP("Received data", buf, len);
  1076. if (client == NULL) {
  1077. RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
  1078. data->counters.invalid_requests++;
  1079. goto fail;
  1080. }
  1081. msg = radius_msg_parse(buf, len);
  1082. if (msg == NULL) {
  1083. RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
  1084. data->counters.malformed_access_requests++;
  1085. client->counters.malformed_access_requests++;
  1086. goto fail;
  1087. }
  1088. os_free(buf);
  1089. buf = NULL;
  1090. if (wpa_debug_level <= MSG_MSGDUMP) {
  1091. radius_msg_dump(msg);
  1092. }
  1093. if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
  1094. RADIUS_DEBUG("Unexpected RADIUS code %d",
  1095. radius_msg_get_hdr(msg)->code);
  1096. data->counters.unknown_types++;
  1097. client->counters.unknown_types++;
  1098. goto fail;
  1099. }
  1100. data->counters.access_requests++;
  1101. client->counters.access_requests++;
  1102. if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
  1103. client->shared_secret_len, NULL)) {
  1104. RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
  1105. data->counters.bad_authenticators++;
  1106. client->counters.bad_authenticators++;
  1107. goto fail;
  1108. }
  1109. if (radius_server_request(data, msg, (struct sockaddr *) &from,
  1110. fromlen, client, abuf, from_port, NULL) ==
  1111. -2)
  1112. return; /* msg was stored with the session */
  1113. fail:
  1114. radius_msg_free(msg);
  1115. os_free(buf);
  1116. }
  1117. static void radius_server_receive_acct(int sock, void *eloop_ctx,
  1118. void *sock_ctx)
  1119. {
  1120. struct radius_server_data *data = eloop_ctx;
  1121. u8 *buf = NULL;
  1122. union {
  1123. struct sockaddr_storage ss;
  1124. struct sockaddr_in sin;
  1125. #ifdef CONFIG_IPV6
  1126. struct sockaddr_in6 sin6;
  1127. #endif /* CONFIG_IPV6 */
  1128. } from;
  1129. socklen_t fromlen;
  1130. int len, res;
  1131. struct radius_client *client = NULL;
  1132. struct radius_msg *msg = NULL, *resp = NULL;
  1133. char abuf[50];
  1134. int from_port = 0;
  1135. struct radius_hdr *hdr;
  1136. struct wpabuf *rbuf;
  1137. buf = os_malloc(RADIUS_MAX_MSG_LEN);
  1138. if (buf == NULL) {
  1139. goto fail;
  1140. }
  1141. fromlen = sizeof(from);
  1142. len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
  1143. (struct sockaddr *) &from.ss, &fromlen);
  1144. if (len < 0) {
  1145. wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
  1146. strerror(errno));
  1147. goto fail;
  1148. }
  1149. #ifdef CONFIG_IPV6
  1150. if (data->ipv6) {
  1151. if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
  1152. sizeof(abuf)) == NULL)
  1153. abuf[0] = '\0';
  1154. from_port = ntohs(from.sin6.sin6_port);
  1155. RADIUS_DEBUG("Received %d bytes from %s:%d",
  1156. len, abuf, from_port);
  1157. client = radius_server_get_client(data,
  1158. (struct in_addr *)
  1159. &from.sin6.sin6_addr, 1);
  1160. }
  1161. #endif /* CONFIG_IPV6 */
  1162. if (!data->ipv6) {
  1163. os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
  1164. from_port = ntohs(from.sin.sin_port);
  1165. RADIUS_DEBUG("Received %d bytes from %s:%d",
  1166. len, abuf, from_port);
  1167. client = radius_server_get_client(data, &from.sin.sin_addr, 0);
  1168. }
  1169. RADIUS_DUMP("Received data", buf, len);
  1170. if (client == NULL) {
  1171. RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
  1172. data->counters.invalid_acct_requests++;
  1173. goto fail;
  1174. }
  1175. msg = radius_msg_parse(buf, len);
  1176. if (msg == NULL) {
  1177. RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
  1178. data->counters.malformed_acct_requests++;
  1179. client->counters.malformed_acct_requests++;
  1180. goto fail;
  1181. }
  1182. os_free(buf);
  1183. buf = NULL;
  1184. if (wpa_debug_level <= MSG_MSGDUMP) {
  1185. radius_msg_dump(msg);
  1186. }
  1187. if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) {
  1188. RADIUS_DEBUG("Unexpected RADIUS code %d",
  1189. radius_msg_get_hdr(msg)->code);
  1190. data->counters.unknown_acct_types++;
  1191. client->counters.unknown_acct_types++;
  1192. goto fail;
  1193. }
  1194. data->counters.acct_requests++;
  1195. client->counters.acct_requests++;
  1196. if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret,
  1197. client->shared_secret_len)) {
  1198. RADIUS_DEBUG("Invalid Authenticator from %s", abuf);
  1199. data->counters.acct_bad_authenticators++;
  1200. client->counters.acct_bad_authenticators++;
  1201. goto fail;
  1202. }
  1203. /* TODO: Write accounting information to a file or database */
  1204. hdr = radius_msg_get_hdr(msg);
  1205. resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier);
  1206. if (resp == NULL)
  1207. goto fail;
  1208. radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret,
  1209. client->shared_secret_len,
  1210. hdr->authenticator);
  1211. RADIUS_DEBUG("Reply to %s:%d", abuf, from_port);
  1212. if (wpa_debug_level <= MSG_MSGDUMP) {
  1213. radius_msg_dump(resp);
  1214. }
  1215. rbuf = radius_msg_get_buf(resp);
  1216. data->counters.acct_responses++;
  1217. client->counters.acct_responses++;
  1218. res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0,
  1219. (struct sockaddr *) &from.ss, fromlen);
  1220. if (res < 0) {
  1221. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
  1222. strerror(errno));
  1223. }
  1224. fail:
  1225. radius_msg_free(resp);
  1226. radius_msg_free(msg);
  1227. os_free(buf);
  1228. }
  1229. static int radius_server_disable_pmtu_discovery(int s)
  1230. {
  1231. int r = -1;
  1232. #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
  1233. /* Turn off Path MTU discovery on IPv4/UDP sockets. */
  1234. int action = IP_PMTUDISC_DONT;
  1235. r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
  1236. sizeof(action));
  1237. if (r == -1)
  1238. wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
  1239. "%s", strerror(errno));
  1240. #endif
  1241. return r;
  1242. }
  1243. static int radius_server_open_socket(int port)
  1244. {
  1245. int s;
  1246. struct sockaddr_in addr;
  1247. s = socket(PF_INET, SOCK_DGRAM, 0);
  1248. if (s < 0) {
  1249. wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
  1250. return -1;
  1251. }
  1252. radius_server_disable_pmtu_discovery(s);
  1253. os_memset(&addr, 0, sizeof(addr));
  1254. addr.sin_family = AF_INET;
  1255. addr.sin_port = htons(port);
  1256. if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  1257. wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
  1258. close(s);
  1259. return -1;
  1260. }
  1261. return s;
  1262. }
  1263. #ifdef CONFIG_IPV6
  1264. static int radius_server_open_socket6(int port)
  1265. {
  1266. int s;
  1267. struct sockaddr_in6 addr;
  1268. s = socket(PF_INET6, SOCK_DGRAM, 0);
  1269. if (s < 0) {
  1270. wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
  1271. strerror(errno));
  1272. return -1;
  1273. }
  1274. os_memset(&addr, 0, sizeof(addr));
  1275. addr.sin6_family = AF_INET6;
  1276. os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
  1277. addr.sin6_port = htons(port);
  1278. if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  1279. wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
  1280. close(s);
  1281. return -1;
  1282. }
  1283. return s;
  1284. }
  1285. #endif /* CONFIG_IPV6 */
  1286. static void radius_server_free_sessions(struct radius_server_data *data,
  1287. struct radius_session *sessions)
  1288. {
  1289. struct radius_session *session, *prev;
  1290. session = sessions;
  1291. while (session) {
  1292. prev = session;
  1293. session = session->next;
  1294. radius_server_session_free(data, prev);
  1295. }
  1296. }
  1297. static void radius_server_free_clients(struct radius_server_data *data,
  1298. struct radius_client *clients)
  1299. {
  1300. struct radius_client *client, *prev;
  1301. client = clients;
  1302. while (client) {
  1303. prev = client;
  1304. client = client->next;
  1305. radius_server_free_sessions(data, prev->sessions);
  1306. os_free(prev->shared_secret);
  1307. os_free(prev);
  1308. }
  1309. }
  1310. static struct radius_client *
  1311. radius_server_read_clients(const char *client_file, int ipv6)
  1312. {
  1313. FILE *f;
  1314. const int buf_size = 1024;
  1315. char *buf, *pos;
  1316. struct radius_client *clients, *tail, *entry;
  1317. int line = 0, mask, failed = 0, i;
  1318. struct in_addr addr;
  1319. #ifdef CONFIG_IPV6
  1320. struct in6_addr addr6;
  1321. #endif /* CONFIG_IPV6 */
  1322. unsigned int val;
  1323. f = fopen(client_file, "r");
  1324. if (f == NULL) {
  1325. RADIUS_ERROR("Could not open client file '%s'", client_file);
  1326. return NULL;
  1327. }
  1328. buf = os_malloc(buf_size);
  1329. if (buf == NULL) {
  1330. fclose(f);
  1331. return NULL;
  1332. }
  1333. clients = tail = NULL;
  1334. while (fgets(buf, buf_size, f)) {
  1335. /* Configuration file format:
  1336. * 192.168.1.0/24 secret
  1337. * 192.168.1.2 secret
  1338. * fe80::211:22ff:fe33:4455/64 secretipv6
  1339. */
  1340. line++;
  1341. buf[buf_size - 1] = '\0';
  1342. pos = buf;
  1343. while (*pos != '\0' && *pos != '\n')
  1344. pos++;
  1345. if (*pos == '\n')
  1346. *pos = '\0';
  1347. if (*buf == '\0' || *buf == '#')
  1348. continue;
  1349. pos = buf;
  1350. while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
  1351. (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
  1352. (*pos >= 'A' && *pos <= 'F')) {
  1353. pos++;
  1354. }
  1355. if (*pos == '\0') {
  1356. failed = 1;
  1357. break;
  1358. }
  1359. if (*pos == '/') {
  1360. char *end;
  1361. *pos++ = '\0';
  1362. mask = strtol(pos, &end, 10);
  1363. if ((pos == end) ||
  1364. (mask < 0 || mask > (ipv6 ? 128 : 32))) {
  1365. failed = 1;
  1366. break;
  1367. }
  1368. pos = end;
  1369. } else {
  1370. mask = ipv6 ? 128 : 32;
  1371. *pos++ = '\0';
  1372. }
  1373. if (!ipv6 && inet_aton(buf, &addr) == 0) {
  1374. failed = 1;
  1375. break;
  1376. }
  1377. #ifdef CONFIG_IPV6
  1378. if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
  1379. if (inet_pton(AF_INET, buf, &addr) <= 0) {
  1380. failed = 1;
  1381. break;
  1382. }
  1383. /* Convert IPv4 address to IPv6 */
  1384. if (mask <= 32)
  1385. mask += (128 - 32);
  1386. os_memset(addr6.s6_addr, 0, 10);
  1387. addr6.s6_addr[10] = 0xff;
  1388. addr6.s6_addr[11] = 0xff;
  1389. os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
  1390. 4);
  1391. }
  1392. #endif /* CONFIG_IPV6 */
  1393. while (*pos == ' ' || *pos == '\t') {
  1394. pos++;
  1395. }
  1396. if (*pos == '\0') {
  1397. failed = 1;
  1398. break;
  1399. }
  1400. entry = os_zalloc(sizeof(*entry));
  1401. if (entry == NULL) {
  1402. failed = 1;
  1403. break;
  1404. }
  1405. entry->shared_secret = os_strdup(pos);
  1406. if (entry->shared_secret == NULL) {
  1407. failed = 1;
  1408. os_free(entry);
  1409. break;
  1410. }
  1411. entry->shared_secret_len = os_strlen(entry->shared_secret);
  1412. if (!ipv6) {
  1413. entry->addr.s_addr = addr.s_addr;
  1414. val = 0;
  1415. for (i = 0; i < mask; i++)
  1416. val |= 1 << (31 - i);
  1417. entry->mask.s_addr = htonl(val);
  1418. }
  1419. #ifdef CONFIG_IPV6
  1420. if (ipv6) {
  1421. int offset = mask / 8;
  1422. os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
  1423. os_memset(entry->mask6.s6_addr, 0xff, offset);
  1424. val = 0;
  1425. for (i = 0; i < (mask % 8); i++)
  1426. val |= 1 << (7 - i);
  1427. if (offset < 16)
  1428. entry->mask6.s6_addr[offset] = val;
  1429. }
  1430. #endif /* CONFIG_IPV6 */
  1431. if (tail == NULL) {
  1432. clients = tail = entry;
  1433. } else {
  1434. tail->next = entry;
  1435. tail = entry;
  1436. }
  1437. }
  1438. if (failed) {
  1439. RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
  1440. radius_server_free_clients(NULL, clients);
  1441. clients = NULL;
  1442. }
  1443. os_free(buf);
  1444. fclose(f);
  1445. return clients;
  1446. }
  1447. /**
  1448. * radius_server_init - Initialize RADIUS server
  1449. * @conf: Configuration for the RADIUS server
  1450. * Returns: Pointer to private RADIUS server context or %NULL on failure
  1451. *
  1452. * This initializes a RADIUS server instance and returns a context pointer that
  1453. * will be used in other calls to the RADIUS server module. The server can be
  1454. * deinitialize by calling radius_server_deinit().
  1455. */
  1456. struct radius_server_data *
  1457. radius_server_init(struct radius_server_conf *conf)
  1458. {
  1459. struct radius_server_data *data;
  1460. #ifndef CONFIG_IPV6
  1461. if (conf->ipv6) {
  1462. wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
  1463. return NULL;
  1464. }
  1465. #endif /* CONFIG_IPV6 */
  1466. data = os_zalloc(sizeof(*data));
  1467. if (data == NULL)
  1468. return NULL;
  1469. dl_list_init(&data->erp_keys);
  1470. os_get_reltime(&data->start_time);
  1471. data->conf_ctx = conf->conf_ctx;
  1472. data->eap_sim_db_priv = conf->eap_sim_db_priv;
  1473. data->ssl_ctx = conf->ssl_ctx;
  1474. data->msg_ctx = conf->msg_ctx;
  1475. data->ipv6 = conf->ipv6;
  1476. if (conf->pac_opaque_encr_key) {
  1477. data->pac_opaque_encr_key = os_malloc(16);
  1478. if (data->pac_opaque_encr_key) {
  1479. os_memcpy(data->pac_opaque_encr_key,
  1480. conf->pac_opaque_encr_key, 16);
  1481. }
  1482. }
  1483. if (conf->eap_fast_a_id) {
  1484. data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
  1485. if (data->eap_fast_a_id) {
  1486. os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id,
  1487. conf->eap_fast_a_id_len);
  1488. data->eap_fast_a_id_len = conf->eap_fast_a_id_len;
  1489. }
  1490. }
  1491. if (conf->eap_fast_a_id_info)
  1492. data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
  1493. data->eap_fast_prov = conf->eap_fast_prov;
  1494. data->pac_key_lifetime = conf->pac_key_lifetime;
  1495. data->pac_key_refresh_time = conf->pac_key_refresh_time;
  1496. data->get_eap_user = conf->get_eap_user;
  1497. data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
  1498. data->tnc = conf->tnc;
  1499. data->wps = conf->wps;
  1500. data->pwd_group = conf->pwd_group;
  1501. data->server_id = conf->server_id;
  1502. if (conf->eap_req_id_text) {
  1503. data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
  1504. if (data->eap_req_id_text) {
  1505. os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
  1506. conf->eap_req_id_text_len);
  1507. data->eap_req_id_text_len = conf->eap_req_id_text_len;
  1508. }
  1509. }
  1510. data->erp = conf->erp;
  1511. data->erp_domain = conf->erp_domain;
  1512. data->tls_session_lifetime = conf->tls_session_lifetime;
  1513. if (conf->subscr_remediation_url) {
  1514. data->subscr_remediation_url =
  1515. os_strdup(conf->subscr_remediation_url);
  1516. }
  1517. data->subscr_remediation_method = conf->subscr_remediation_method;
  1518. #ifdef CONFIG_SQLITE
  1519. if (conf->sqlite_file) {
  1520. if (sqlite3_open(conf->sqlite_file, &data->db)) {
  1521. RADIUS_ERROR("Could not open SQLite file '%s'",
  1522. conf->sqlite_file);
  1523. radius_server_deinit(data);
  1524. return NULL;
  1525. }
  1526. }
  1527. #endif /* CONFIG_SQLITE */
  1528. #ifdef CONFIG_RADIUS_TEST
  1529. if (conf->dump_msk_file)
  1530. data->dump_msk_file = os_strdup(conf->dump_msk_file);
  1531. #endif /* CONFIG_RADIUS_TEST */
  1532. data->clients = radius_server_read_clients(conf->client_file,
  1533. conf->ipv6);
  1534. if (data->clients == NULL) {
  1535. wpa_printf(MSG_ERROR, "No RADIUS clients configured");
  1536. radius_server_deinit(data);
  1537. return NULL;
  1538. }
  1539. #ifdef CONFIG_IPV6
  1540. if (conf->ipv6)
  1541. data->auth_sock = radius_server_open_socket6(conf->auth_port);
  1542. else
  1543. #endif /* CONFIG_IPV6 */
  1544. data->auth_sock = radius_server_open_socket(conf->auth_port);
  1545. if (data->auth_sock < 0) {
  1546. wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
  1547. radius_server_deinit(data);
  1548. return NULL;
  1549. }
  1550. if (eloop_register_read_sock(data->auth_sock,
  1551. radius_server_receive_auth,
  1552. data, NULL)) {
  1553. radius_server_deinit(data);
  1554. return NULL;
  1555. }
  1556. if (conf->acct_port) {
  1557. #ifdef CONFIG_IPV6
  1558. if (conf->ipv6)
  1559. data->acct_sock = radius_server_open_socket6(
  1560. conf->acct_port);
  1561. else
  1562. #endif /* CONFIG_IPV6 */
  1563. data->acct_sock = radius_server_open_socket(conf->acct_port);
  1564. if (data->acct_sock < 0) {
  1565. wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server");
  1566. radius_server_deinit(data);
  1567. return NULL;
  1568. }
  1569. if (eloop_register_read_sock(data->acct_sock,
  1570. radius_server_receive_acct,
  1571. data, NULL)) {
  1572. radius_server_deinit(data);
  1573. return NULL;
  1574. }
  1575. } else {
  1576. data->acct_sock = -1;
  1577. }
  1578. return data;
  1579. }
  1580. /**
  1581. * radius_server_erp_flush - Flush all ERP keys
  1582. * @data: RADIUS server context from radius_server_init()
  1583. */
  1584. void radius_server_erp_flush(struct radius_server_data *data)
  1585. {
  1586. struct eap_server_erp_key *erp;
  1587. if (data == NULL)
  1588. return;
  1589. while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key,
  1590. list)) != NULL) {
  1591. dl_list_del(&erp->list);
  1592. bin_clear_free(erp, sizeof(*erp));
  1593. }
  1594. }
  1595. /**
  1596. * radius_server_deinit - Deinitialize RADIUS server
  1597. * @data: RADIUS server context from radius_server_init()
  1598. */
  1599. void radius_server_deinit(struct radius_server_data *data)
  1600. {
  1601. if (data == NULL)
  1602. return;
  1603. if (data->auth_sock >= 0) {
  1604. eloop_unregister_read_sock(data->auth_sock);
  1605. close(data->auth_sock);
  1606. }
  1607. if (data->acct_sock >= 0) {
  1608. eloop_unregister_read_sock(data->acct_sock);
  1609. close(data->acct_sock);
  1610. }
  1611. radius_server_free_clients(data, data->clients);
  1612. os_free(data->pac_opaque_encr_key);
  1613. os_free(data->eap_fast_a_id);
  1614. os_free(data->eap_fast_a_id_info);
  1615. os_free(data->eap_req_id_text);
  1616. #ifdef CONFIG_RADIUS_TEST
  1617. os_free(data->dump_msk_file);
  1618. #endif /* CONFIG_RADIUS_TEST */
  1619. os_free(data->subscr_remediation_url);
  1620. #ifdef CONFIG_SQLITE
  1621. if (data->db)
  1622. sqlite3_close(data->db);
  1623. #endif /* CONFIG_SQLITE */
  1624. radius_server_erp_flush(data);
  1625. os_free(data);
  1626. }
  1627. /**
  1628. * radius_server_get_mib - Get RADIUS server MIB information
  1629. * @data: RADIUS server context from radius_server_init()
  1630. * @buf: Buffer for returning the MIB data in text format
  1631. * @buflen: buf length in octets
  1632. * Returns: Number of octets written into buf
  1633. */
  1634. int radius_server_get_mib(struct radius_server_data *data, char *buf,
  1635. size_t buflen)
  1636. {
  1637. int ret, uptime;
  1638. unsigned int idx;
  1639. char *end, *pos;
  1640. struct os_reltime now;
  1641. struct radius_client *cli;
  1642. /* RFC 2619 - RADIUS Authentication Server MIB */
  1643. if (data == NULL || buflen == 0)
  1644. return 0;
  1645. pos = buf;
  1646. end = buf + buflen;
  1647. os_get_reltime(&now);
  1648. uptime = (now.sec - data->start_time.sec) * 100 +
  1649. ((now.usec - data->start_time.usec) / 10000) % 100;
  1650. ret = os_snprintf(pos, end - pos,
  1651. "RADIUS-AUTH-SERVER-MIB\n"
  1652. "radiusAuthServIdent=hostapd\n"
  1653. "radiusAuthServUpTime=%d\n"
  1654. "radiusAuthServResetTime=0\n"
  1655. "radiusAuthServConfigReset=4\n",
  1656. uptime);
  1657. if (os_snprintf_error(end - pos, ret)) {
  1658. *pos = '\0';
  1659. return pos - buf;
  1660. }
  1661. pos += ret;
  1662. ret = os_snprintf(pos, end - pos,
  1663. "radiusAuthServTotalAccessRequests=%u\n"
  1664. "radiusAuthServTotalInvalidRequests=%u\n"
  1665. "radiusAuthServTotalDupAccessRequests=%u\n"
  1666. "radiusAuthServTotalAccessAccepts=%u\n"
  1667. "radiusAuthServTotalAccessRejects=%u\n"
  1668. "radiusAuthServTotalAccessChallenges=%u\n"
  1669. "radiusAuthServTotalMalformedAccessRequests=%u\n"
  1670. "radiusAuthServTotalBadAuthenticators=%u\n"
  1671. "radiusAuthServTotalPacketsDropped=%u\n"
  1672. "radiusAuthServTotalUnknownTypes=%u\n"
  1673. "radiusAccServTotalRequests=%u\n"
  1674. "radiusAccServTotalInvalidRequests=%u\n"
  1675. "radiusAccServTotalResponses=%u\n"
  1676. "radiusAccServTotalMalformedRequests=%u\n"
  1677. "radiusAccServTotalBadAuthenticators=%u\n"
  1678. "radiusAccServTotalUnknownTypes=%u\n",
  1679. data->counters.access_requests,
  1680. data->counters.invalid_requests,
  1681. data->counters.dup_access_requests,
  1682. data->counters.access_accepts,
  1683. data->counters.access_rejects,
  1684. data->counters.access_challenges,
  1685. data->counters.malformed_access_requests,
  1686. data->counters.bad_authenticators,
  1687. data->counters.packets_dropped,
  1688. data->counters.unknown_types,
  1689. data->counters.acct_requests,
  1690. data->counters.invalid_acct_requests,
  1691. data->counters.acct_responses,
  1692. data->counters.malformed_acct_requests,
  1693. data->counters.acct_bad_authenticators,
  1694. data->counters.unknown_acct_types);
  1695. if (os_snprintf_error(end - pos, ret)) {
  1696. *pos = '\0';
  1697. return pos - buf;
  1698. }
  1699. pos += ret;
  1700. for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
  1701. char abuf[50], mbuf[50];
  1702. #ifdef CONFIG_IPV6
  1703. if (data->ipv6) {
  1704. if (inet_ntop(AF_INET6, &cli->addr6, abuf,
  1705. sizeof(abuf)) == NULL)
  1706. abuf[0] = '\0';
  1707. if (inet_ntop(AF_INET6, &cli->mask6, mbuf,
  1708. sizeof(mbuf)) == NULL)
  1709. mbuf[0] = '\0';
  1710. }
  1711. #endif /* CONFIG_IPV6 */
  1712. if (!data->ipv6) {
  1713. os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
  1714. os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
  1715. }
  1716. ret = os_snprintf(pos, end - pos,
  1717. "radiusAuthClientIndex=%u\n"
  1718. "radiusAuthClientAddress=%s/%s\n"
  1719. "radiusAuthServAccessRequests=%u\n"
  1720. "radiusAuthServDupAccessRequests=%u\n"
  1721. "radiusAuthServAccessAccepts=%u\n"
  1722. "radiusAuthServAccessRejects=%u\n"
  1723. "radiusAuthServAccessChallenges=%u\n"
  1724. "radiusAuthServMalformedAccessRequests=%u\n"
  1725. "radiusAuthServBadAuthenticators=%u\n"
  1726. "radiusAuthServPacketsDropped=%u\n"
  1727. "radiusAuthServUnknownTypes=%u\n"
  1728. "radiusAccServTotalRequests=%u\n"
  1729. "radiusAccServTotalInvalidRequests=%u\n"
  1730. "radiusAccServTotalResponses=%u\n"
  1731. "radiusAccServTotalMalformedRequests=%u\n"
  1732. "radiusAccServTotalBadAuthenticators=%u\n"
  1733. "radiusAccServTotalUnknownTypes=%u\n",
  1734. idx,
  1735. abuf, mbuf,
  1736. cli->counters.access_requests,
  1737. cli->counters.dup_access_requests,
  1738. cli->counters.access_accepts,
  1739. cli->counters.access_rejects,
  1740. cli->counters.access_challenges,
  1741. cli->counters.malformed_access_requests,
  1742. cli->counters.bad_authenticators,
  1743. cli->counters.packets_dropped,
  1744. cli->counters.unknown_types,
  1745. cli->counters.acct_requests,
  1746. cli->counters.invalid_acct_requests,
  1747. cli->counters.acct_responses,
  1748. cli->counters.malformed_acct_requests,
  1749. cli->counters.acct_bad_authenticators,
  1750. cli->counters.unknown_acct_types);
  1751. if (os_snprintf_error(end - pos, ret)) {
  1752. *pos = '\0';
  1753. return pos - buf;
  1754. }
  1755. pos += ret;
  1756. }
  1757. return pos - buf;
  1758. }
  1759. static int radius_server_get_eap_user(void *ctx, const u8 *identity,
  1760. size_t identity_len, int phase2,
  1761. struct eap_user *user)
  1762. {
  1763. struct radius_session *sess = ctx;
  1764. struct radius_server_data *data = sess->server;
  1765. int ret;
  1766. ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
  1767. phase2, user);
  1768. if (ret == 0 && user) {
  1769. sess->accept_attr = user->accept_attr;
  1770. sess->remediation = user->remediation;
  1771. sess->macacl = user->macacl;
  1772. }
  1773. if (ret) {
  1774. RADIUS_DEBUG("%s: User-Name not found from user database",
  1775. __func__);
  1776. }
  1777. return ret;
  1778. }
  1779. static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
  1780. {
  1781. struct radius_session *sess = ctx;
  1782. struct radius_server_data *data = sess->server;
  1783. *len = data->eap_req_id_text_len;
  1784. return data->eap_req_id_text;
  1785. }
  1786. static void radius_server_log_msg(void *ctx, const char *msg)
  1787. {
  1788. struct radius_session *sess = ctx;
  1789. srv_log(sess, "EAP: %s", msg);
  1790. }
  1791. #ifdef CONFIG_ERP
  1792. static const char * radius_server_get_erp_domain(void *ctx)
  1793. {
  1794. struct radius_session *sess = ctx;
  1795. struct radius_server_data *data = sess->server;
  1796. return data->erp_domain;
  1797. }
  1798. static struct eap_server_erp_key *
  1799. radius_server_erp_get_key(void *ctx, const char *keyname)
  1800. {
  1801. struct radius_session *sess = ctx;
  1802. struct radius_server_data *data = sess->server;
  1803. struct eap_server_erp_key *erp;
  1804. dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key,
  1805. list) {
  1806. if (os_strcmp(erp->keyname_nai, keyname) == 0)
  1807. return erp;
  1808. }
  1809. return NULL;
  1810. }
  1811. static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
  1812. {
  1813. struct radius_session *sess = ctx;
  1814. struct radius_server_data *data = sess->server;
  1815. dl_list_add(&data->erp_keys, &erp->list);
  1816. return 0;
  1817. }
  1818. #endif /* CONFIG_ERP */
  1819. static const struct eapol_callbacks radius_server_eapol_cb =
  1820. {
  1821. .get_eap_user = radius_server_get_eap_user,
  1822. .get_eap_req_id_text = radius_server_get_eap_req_id_text,
  1823. .log_msg = radius_server_log_msg,
  1824. #ifdef CONFIG_ERP
  1825. .get_erp_send_reauth_start = NULL,
  1826. .get_erp_domain = radius_server_get_erp_domain,
  1827. .erp_get_key = radius_server_erp_get_key,
  1828. .erp_add_key = radius_server_erp_add_key,
  1829. #endif /* CONFIG_ERP */
  1830. };
  1831. /**
  1832. * radius_server_eap_pending_cb - Pending EAP data notification
  1833. * @data: RADIUS server context from radius_server_init()
  1834. * @ctx: Pending EAP context pointer
  1835. *
  1836. * This function is used to notify EAP server module that a pending operation
  1837. * has been completed and processing of the EAP session can proceed.
  1838. */
  1839. void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
  1840. {
  1841. struct radius_client *cli;
  1842. struct radius_session *s, *sess = NULL;
  1843. struct radius_msg *msg;
  1844. if (data == NULL)
  1845. return;
  1846. for (cli = data->clients; cli; cli = cli->next) {
  1847. for (s = cli->sessions; s; s = s->next) {
  1848. if (s->eap == ctx && s->last_msg) {
  1849. sess = s;
  1850. break;
  1851. }
  1852. }
  1853. if (sess)
  1854. break;
  1855. }
  1856. if (sess == NULL) {
  1857. RADIUS_DEBUG("No session matched callback ctx");
  1858. return;
  1859. }
  1860. msg = sess->last_msg;
  1861. sess->last_msg = NULL;
  1862. eap_sm_pending_cb(sess->eap);
  1863. if (radius_server_request(data, msg,
  1864. (struct sockaddr *) &sess->last_from,
  1865. sess->last_fromlen, cli,
  1866. sess->last_from_addr,
  1867. sess->last_from_port, sess) == -2)
  1868. return; /* msg was stored with the session */
  1869. radius_msg_free(msg);
  1870. }