radius_server.c 55 KB

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