radius_server.c 55 KB

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