radius_server.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. /*
  2. * RADIUS authentication server
  3. * Copyright (c) 2005-2009, 2011, 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. #include "common.h"
  11. #include "radius.h"
  12. #include "eloop.h"
  13. #include "eap_server/eap.h"
  14. #include "radius_server.h"
  15. /**
  16. * RADIUS_SESSION_TIMEOUT - Session timeout in seconds
  17. */
  18. #define RADIUS_SESSION_TIMEOUT 60
  19. /**
  20. * RADIUS_MAX_SESSION - Maximum number of active sessions
  21. */
  22. #define RADIUS_MAX_SESSION 100
  23. /**
  24. * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
  25. */
  26. #define RADIUS_MAX_MSG_LEN 3000
  27. static struct eapol_callbacks radius_server_eapol_cb;
  28. struct radius_client;
  29. struct radius_server_data;
  30. /**
  31. * struct radius_server_counters - RADIUS server statistics counters
  32. */
  33. struct radius_server_counters {
  34. u32 access_requests;
  35. u32 invalid_requests;
  36. u32 dup_access_requests;
  37. u32 access_accepts;
  38. u32 access_rejects;
  39. u32 access_challenges;
  40. u32 malformed_access_requests;
  41. u32 bad_authenticators;
  42. u32 packets_dropped;
  43. u32 unknown_types;
  44. };
  45. /**
  46. * struct radius_session - Internal RADIUS server data for a session
  47. */
  48. struct radius_session {
  49. struct radius_session *next;
  50. struct radius_client *client;
  51. struct radius_server_data *server;
  52. unsigned int sess_id;
  53. struct eap_sm *eap;
  54. struct eap_eapol_interface *eap_if;
  55. struct radius_msg *last_msg;
  56. char *last_from_addr;
  57. int last_from_port;
  58. struct sockaddr_storage last_from;
  59. socklen_t last_fromlen;
  60. u8 last_identifier;
  61. struct radius_msg *last_reply;
  62. u8 last_authenticator[16];
  63. };
  64. /**
  65. * struct radius_client - Internal RADIUS server data for a client
  66. */
  67. struct radius_client {
  68. struct radius_client *next;
  69. struct in_addr addr;
  70. struct in_addr mask;
  71. #ifdef CONFIG_IPV6
  72. struct in6_addr addr6;
  73. struct in6_addr mask6;
  74. #endif /* CONFIG_IPV6 */
  75. char *shared_secret;
  76. int shared_secret_len;
  77. struct radius_session *sessions;
  78. struct radius_server_counters counters;
  79. };
  80. /**
  81. * struct radius_server_data - Internal RADIUS server data
  82. */
  83. struct radius_server_data {
  84. /**
  85. * auth_sock - Socket for RADIUS authentication messages
  86. */
  87. int auth_sock;
  88. /**
  89. * clients - List of authorized RADIUS clients
  90. */
  91. struct radius_client *clients;
  92. /**
  93. * next_sess_id - Next session identifier
  94. */
  95. unsigned int next_sess_id;
  96. /**
  97. * conf_ctx - Context pointer for callbacks
  98. *
  99. * This is used as the ctx argument in get_eap_user() calls.
  100. */
  101. void *conf_ctx;
  102. /**
  103. * num_sess - Number of active sessions
  104. */
  105. int num_sess;
  106. /**
  107. * eap_sim_db_priv - EAP-SIM/AKA database context
  108. *
  109. * This is passed to the EAP-SIM/AKA server implementation as a
  110. * callback context.
  111. */
  112. void *eap_sim_db_priv;
  113. /**
  114. * ssl_ctx - TLS context
  115. *
  116. * This is passed to the EAP server implementation as a callback
  117. * context for TLS operations.
  118. */
  119. void *ssl_ctx;
  120. /**
  121. * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST
  122. *
  123. * This parameter is used to set a key for EAP-FAST to encrypt the
  124. * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If
  125. * set, must point to a 16-octet key.
  126. */
  127. u8 *pac_opaque_encr_key;
  128. /**
  129. * eap_fast_a_id - EAP-FAST authority identity (A-ID)
  130. *
  131. * If EAP-FAST is not used, this can be set to %NULL. In theory, this
  132. * is a variable length field, but due to some existing implementations
  133. * requiring A-ID to be 16 octets in length, it is recommended to use
  134. * that length for the field to provide interoperability with deployed
  135. * peer implementations.
  136. */
  137. u8 *eap_fast_a_id;
  138. /**
  139. * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets
  140. */
  141. size_t eap_fast_a_id_len;
  142. /**
  143. * eap_fast_a_id_info - EAP-FAST authority identifier information
  144. *
  145. * This A-ID-Info contains a user-friendly name for the A-ID. For
  146. * example, this could be the enterprise and server names in
  147. * human-readable format. This field is encoded as UTF-8. If EAP-FAST
  148. * is not used, this can be set to %NULL.
  149. */
  150. char *eap_fast_a_id_info;
  151. /**
  152. * eap_fast_prov - EAP-FAST provisioning modes
  153. *
  154. * 0 = provisioning disabled, 1 = only anonymous provisioning allowed,
  155. * 2 = only authenticated provisioning allowed, 3 = both provisioning
  156. * modes allowed.
  157. */
  158. int eap_fast_prov;
  159. /**
  160. * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds
  161. *
  162. * This is the hard limit on how long a provisioned PAC-Key can be
  163. * used.
  164. */
  165. int pac_key_lifetime;
  166. /**
  167. * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds
  168. *
  169. * This is a soft limit on the PAC-Key. The server will automatically
  170. * generate a new PAC-Key when this number of seconds (or fewer) of the
  171. * lifetime remains.
  172. */
  173. int pac_key_refresh_time;
  174. /**
  175. * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
  176. *
  177. * This controls whether the protected success/failure indication
  178. * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA.
  179. */
  180. int eap_sim_aka_result_ind;
  181. /**
  182. * tnc - Trusted Network Connect (TNC)
  183. *
  184. * This controls whether TNC is enabled and will be required before the
  185. * peer is allowed to connect. Note: This is only used with EAP-TTLS
  186. * and EAP-FAST. If any other EAP method is enabled, the peer will be
  187. * allowed to connect without TNC.
  188. */
  189. int tnc;
  190. /**
  191. * pwd_group - The D-H group assigned for EAP-pwd
  192. *
  193. * If EAP-pwd is not used it can be set to zero.
  194. */
  195. u16 pwd_group;
  196. /**
  197. * server_id - Server identity
  198. */
  199. const char *server_id;
  200. /**
  201. * wps - Wi-Fi Protected Setup context
  202. *
  203. * If WPS is used with an external RADIUS server (which is quite
  204. * unlikely configuration), this is used to provide a pointer to WPS
  205. * context data. Normally, this can be set to %NULL.
  206. */
  207. struct wps_context *wps;
  208. /**
  209. * ipv6 - Whether to enable IPv6 support in the RADIUS server
  210. */
  211. int ipv6;
  212. /**
  213. * start_time - Timestamp of server start
  214. */
  215. struct os_time start_time;
  216. /**
  217. * counters - Statistics counters for server operations
  218. *
  219. * These counters are the sum over all clients.
  220. */
  221. struct radius_server_counters counters;
  222. /**
  223. * get_eap_user - Callback for fetching EAP user information
  224. * @ctx: Context data from conf_ctx
  225. * @identity: User identity
  226. * @identity_len: identity buffer length in octets
  227. * @phase2: Whether this is for Phase 2 identity
  228. * @user: Data structure for filling in the user information
  229. * Returns: 0 on success, -1 on failure
  230. *
  231. * This is used to fetch information from user database. The callback
  232. * will fill in information about allowed EAP methods and the user
  233. * password. The password field will be an allocated copy of the
  234. * password data and RADIUS server will free it after use.
  235. */
  236. int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
  237. int phase2, struct eap_user *user);
  238. /**
  239. * eap_req_id_text - Optional data for EAP-Request/Identity
  240. *
  241. * This can be used to configure an optional, displayable message that
  242. * will be sent in EAP-Request/Identity. This string can contain an
  243. * ASCII-0 character (nul) to separate network infromation per RFC
  244. * 4284. The actual string length is explicit provided in
  245. * eap_req_id_text_len since nul character will not be used as a string
  246. * terminator.
  247. */
  248. char *eap_req_id_text;
  249. /**
  250. * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
  251. */
  252. size_t eap_req_id_text_len;
  253. /*
  254. * msg_ctx - Context data for wpa_msg() calls
  255. */
  256. void *msg_ctx;
  257. #ifdef CONFIG_RADIUS_TEST
  258. char *dump_msk_file;
  259. #endif /* CONFIG_RADIUS_TEST */
  260. };
  261. extern int wpa_debug_level;
  262. #define RADIUS_DEBUG(args...) \
  263. wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
  264. #define RADIUS_ERROR(args...) \
  265. wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
  266. #define RADIUS_DUMP(args...) \
  267. wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
  268. #define RADIUS_DUMP_ASCII(args...) \
  269. wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
  270. static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
  271. static void radius_server_session_remove_timeout(void *eloop_ctx,
  272. void *timeout_ctx);
  273. static struct radius_client *
  274. radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
  275. int ipv6)
  276. {
  277. struct radius_client *client = data->clients;
  278. while (client) {
  279. #ifdef CONFIG_IPV6
  280. if (ipv6) {
  281. struct in6_addr *addr6;
  282. int i;
  283. addr6 = (struct in6_addr *) addr;
  284. for (i = 0; i < 16; i++) {
  285. if ((addr6->s6_addr[i] &
  286. client->mask6.s6_addr[i]) !=
  287. (client->addr6.s6_addr[i] &
  288. client->mask6.s6_addr[i])) {
  289. i = 17;
  290. break;
  291. }
  292. }
  293. if (i == 16) {
  294. break;
  295. }
  296. }
  297. #endif /* CONFIG_IPV6 */
  298. if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
  299. (addr->s_addr & client->mask.s_addr)) {
  300. break;
  301. }
  302. client = client->next;
  303. }
  304. return client;
  305. }
  306. static struct radius_session *
  307. radius_server_get_session(struct radius_client *client, unsigned int sess_id)
  308. {
  309. struct radius_session *sess = client->sessions;
  310. while (sess) {
  311. if (sess->sess_id == sess_id) {
  312. break;
  313. }
  314. sess = sess->next;
  315. }
  316. return sess;
  317. }
  318. static void radius_server_session_free(struct radius_server_data *data,
  319. struct radius_session *sess)
  320. {
  321. eloop_cancel_timeout(radius_server_session_timeout, data, sess);
  322. eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
  323. eap_server_sm_deinit(sess->eap);
  324. radius_msg_free(sess->last_msg);
  325. os_free(sess->last_from_addr);
  326. radius_msg_free(sess->last_reply);
  327. os_free(sess);
  328. data->num_sess--;
  329. }
  330. static void radius_server_session_remove(struct radius_server_data *data,
  331. struct radius_session *sess)
  332. {
  333. struct radius_client *client = sess->client;
  334. struct radius_session *session, *prev;
  335. eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
  336. prev = NULL;
  337. session = client->sessions;
  338. while (session) {
  339. if (session == sess) {
  340. if (prev == NULL) {
  341. client->sessions = sess->next;
  342. } else {
  343. prev->next = sess->next;
  344. }
  345. radius_server_session_free(data, sess);
  346. break;
  347. }
  348. prev = session;
  349. session = session->next;
  350. }
  351. }
  352. static void radius_server_session_remove_timeout(void *eloop_ctx,
  353. void *timeout_ctx)
  354. {
  355. struct radius_server_data *data = eloop_ctx;
  356. struct radius_session *sess = timeout_ctx;
  357. RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
  358. radius_server_session_remove(data, sess);
  359. }
  360. static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
  361. {
  362. struct radius_server_data *data = eloop_ctx;
  363. struct radius_session *sess = timeout_ctx;
  364. RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
  365. radius_server_session_remove(data, sess);
  366. }
  367. static struct radius_session *
  368. radius_server_new_session(struct radius_server_data *data,
  369. struct radius_client *client)
  370. {
  371. struct radius_session *sess;
  372. if (data->num_sess >= RADIUS_MAX_SESSION) {
  373. RADIUS_DEBUG("Maximum number of existing session - no room "
  374. "for a new session");
  375. return NULL;
  376. }
  377. sess = os_zalloc(sizeof(*sess));
  378. if (sess == NULL)
  379. return NULL;
  380. sess->server = data;
  381. sess->client = client;
  382. sess->sess_id = data->next_sess_id++;
  383. sess->next = client->sessions;
  384. client->sessions = sess;
  385. eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
  386. radius_server_session_timeout, data, sess);
  387. data->num_sess++;
  388. return sess;
  389. }
  390. static struct radius_session *
  391. radius_server_get_new_session(struct radius_server_data *data,
  392. struct radius_client *client,
  393. struct radius_msg *msg)
  394. {
  395. u8 *user;
  396. size_t user_len;
  397. int res;
  398. struct radius_session *sess;
  399. struct eap_config eap_conf;
  400. RADIUS_DEBUG("Creating a new session");
  401. user = os_malloc(256);
  402. if (user == NULL) {
  403. return NULL;
  404. }
  405. res = radius_msg_get_attr(msg, RADIUS_ATTR_USER_NAME, user, 256);
  406. if (res < 0 || res > 256) {
  407. RADIUS_DEBUG("Could not get User-Name");
  408. os_free(user);
  409. return NULL;
  410. }
  411. user_len = res;
  412. RADIUS_DUMP_ASCII("User-Name", user, user_len);
  413. res = data->get_eap_user(data->conf_ctx, user, user_len, 0, NULL);
  414. os_free(user);
  415. if (res == 0) {
  416. RADIUS_DEBUG("Matching user entry found");
  417. sess = radius_server_new_session(data, client);
  418. if (sess == NULL) {
  419. RADIUS_DEBUG("Failed to create a new session");
  420. return NULL;
  421. }
  422. } else {
  423. RADIUS_DEBUG("User-Name not found from user database");
  424. return NULL;
  425. }
  426. os_memset(&eap_conf, 0, sizeof(eap_conf));
  427. eap_conf.ssl_ctx = data->ssl_ctx;
  428. eap_conf.msg_ctx = data->msg_ctx;
  429. eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
  430. eap_conf.backend_auth = TRUE;
  431. eap_conf.eap_server = 1;
  432. eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
  433. eap_conf.eap_fast_a_id = data->eap_fast_a_id;
  434. eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len;
  435. eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info;
  436. eap_conf.eap_fast_prov = data->eap_fast_prov;
  437. eap_conf.pac_key_lifetime = data->pac_key_lifetime;
  438. eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
  439. eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
  440. eap_conf.tnc = data->tnc;
  441. eap_conf.wps = data->wps;
  442. eap_conf.pwd_group = data->pwd_group;
  443. eap_conf.server_id = (const u8 *) data->server_id;
  444. eap_conf.server_id_len = os_strlen(data->server_id);
  445. sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
  446. &eap_conf);
  447. if (sess->eap == NULL) {
  448. RADIUS_DEBUG("Failed to initialize EAP state machine for the "
  449. "new session");
  450. radius_server_session_free(data, sess);
  451. return NULL;
  452. }
  453. sess->eap_if = eap_get_interface(sess->eap);
  454. sess->eap_if->eapRestart = TRUE;
  455. sess->eap_if->portEnabled = TRUE;
  456. RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
  457. return sess;
  458. }
  459. static struct radius_msg *
  460. radius_server_encapsulate_eap(struct radius_server_data *data,
  461. struct radius_client *client,
  462. struct radius_session *sess,
  463. struct radius_msg *request)
  464. {
  465. struct radius_msg *msg;
  466. int code;
  467. unsigned int sess_id;
  468. struct radius_hdr *hdr = radius_msg_get_hdr(request);
  469. if (sess->eap_if->eapFail) {
  470. sess->eap_if->eapFail = FALSE;
  471. code = RADIUS_CODE_ACCESS_REJECT;
  472. } else if (sess->eap_if->eapSuccess) {
  473. sess->eap_if->eapSuccess = FALSE;
  474. code = RADIUS_CODE_ACCESS_ACCEPT;
  475. } else {
  476. sess->eap_if->eapReq = FALSE;
  477. code = RADIUS_CODE_ACCESS_CHALLENGE;
  478. }
  479. msg = radius_msg_new(code, hdr->identifier);
  480. if (msg == NULL) {
  481. RADIUS_DEBUG("Failed to allocate reply message");
  482. return NULL;
  483. }
  484. sess_id = htonl(sess->sess_id);
  485. if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
  486. !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
  487. (u8 *) &sess_id, sizeof(sess_id))) {
  488. RADIUS_DEBUG("Failed to add State attribute");
  489. }
  490. if (sess->eap_if->eapReqData &&
  491. !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
  492. wpabuf_len(sess->eap_if->eapReqData))) {
  493. RADIUS_DEBUG("Failed to add EAP-Message attribute");
  494. }
  495. if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
  496. int len;
  497. #ifdef CONFIG_RADIUS_TEST
  498. if (data->dump_msk_file) {
  499. FILE *f;
  500. char buf[2 * 64 + 1];
  501. f = fopen(data->dump_msk_file, "a");
  502. if (f) {
  503. len = sess->eap_if->eapKeyDataLen;
  504. if (len > 64)
  505. len = 64;
  506. len = wpa_snprintf_hex(
  507. buf, sizeof(buf),
  508. sess->eap_if->eapKeyData, len);
  509. buf[len] = '\0';
  510. fprintf(f, "%s\n", buf);
  511. fclose(f);
  512. }
  513. }
  514. #endif /* CONFIG_RADIUS_TEST */
  515. if (sess->eap_if->eapKeyDataLen > 64) {
  516. len = 32;
  517. } else {
  518. len = sess->eap_if->eapKeyDataLen / 2;
  519. }
  520. if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
  521. (u8 *) client->shared_secret,
  522. client->shared_secret_len,
  523. sess->eap_if->eapKeyData + len,
  524. len, sess->eap_if->eapKeyData,
  525. len)) {
  526. RADIUS_DEBUG("Failed to add MPPE key attributes");
  527. }
  528. }
  529. if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
  530. RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
  531. radius_msg_free(msg);
  532. return NULL;
  533. }
  534. if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
  535. client->shared_secret_len,
  536. hdr->authenticator) < 0) {
  537. RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
  538. }
  539. return msg;
  540. }
  541. static int radius_server_reject(struct radius_server_data *data,
  542. struct radius_client *client,
  543. struct radius_msg *request,
  544. struct sockaddr *from, socklen_t fromlen,
  545. const char *from_addr, int from_port)
  546. {
  547. struct radius_msg *msg;
  548. int ret = 0;
  549. struct eap_hdr eapfail;
  550. struct wpabuf *buf;
  551. struct radius_hdr *hdr = radius_msg_get_hdr(request);
  552. RADIUS_DEBUG("Reject invalid request from %s:%d",
  553. from_addr, from_port);
  554. msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
  555. if (msg == NULL) {
  556. return -1;
  557. }
  558. os_memset(&eapfail, 0, sizeof(eapfail));
  559. eapfail.code = EAP_CODE_FAILURE;
  560. eapfail.identifier = 0;
  561. eapfail.length = host_to_be16(sizeof(eapfail));
  562. if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
  563. RADIUS_DEBUG("Failed to add EAP-Message attribute");
  564. }
  565. if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
  566. RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
  567. radius_msg_free(msg);
  568. return -1;
  569. }
  570. if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
  571. client->shared_secret_len,
  572. hdr->authenticator) <
  573. 0) {
  574. RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
  575. }
  576. if (wpa_debug_level <= MSG_MSGDUMP) {
  577. radius_msg_dump(msg);
  578. }
  579. data->counters.access_rejects++;
  580. client->counters.access_rejects++;
  581. buf = radius_msg_get_buf(msg);
  582. if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
  583. (struct sockaddr *) from, sizeof(*from)) < 0) {
  584. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
  585. ret = -1;
  586. }
  587. radius_msg_free(msg);
  588. return ret;
  589. }
  590. static int radius_server_request(struct radius_server_data *data,
  591. struct radius_msg *msg,
  592. struct sockaddr *from, socklen_t fromlen,
  593. struct radius_client *client,
  594. const char *from_addr, int from_port,
  595. struct radius_session *force_sess)
  596. {
  597. struct wpabuf *eap = NULL;
  598. int res, state_included = 0;
  599. u8 statebuf[4];
  600. unsigned int state;
  601. struct radius_session *sess;
  602. struct radius_msg *reply;
  603. int is_complete = 0;
  604. if (force_sess)
  605. sess = force_sess;
  606. else {
  607. res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
  608. sizeof(statebuf));
  609. state_included = res >= 0;
  610. if (res == sizeof(statebuf)) {
  611. state = WPA_GET_BE32(statebuf);
  612. sess = radius_server_get_session(client, state);
  613. } else {
  614. sess = NULL;
  615. }
  616. }
  617. if (sess) {
  618. RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
  619. } else if (state_included) {
  620. RADIUS_DEBUG("State attribute included but no session found");
  621. radius_server_reject(data, client, msg, from, fromlen,
  622. from_addr, from_port);
  623. return -1;
  624. } else {
  625. sess = radius_server_get_new_session(data, client, msg);
  626. if (sess == NULL) {
  627. RADIUS_DEBUG("Could not create a new session");
  628. radius_server_reject(data, client, msg, from, fromlen,
  629. from_addr, from_port);
  630. return -1;
  631. }
  632. }
  633. if (sess->last_from_port == from_port &&
  634. sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
  635. os_memcmp(sess->last_authenticator,
  636. radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
  637. RADIUS_DEBUG("Duplicate message from %s", from_addr);
  638. data->counters.dup_access_requests++;
  639. client->counters.dup_access_requests++;
  640. if (sess->last_reply) {
  641. struct wpabuf *buf;
  642. buf = radius_msg_get_buf(sess->last_reply);
  643. res = sendto(data->auth_sock, wpabuf_head(buf),
  644. wpabuf_len(buf), 0,
  645. (struct sockaddr *) from, fromlen);
  646. if (res < 0) {
  647. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
  648. strerror(errno));
  649. }
  650. return 0;
  651. }
  652. RADIUS_DEBUG("No previous reply available for duplicate "
  653. "message");
  654. return -1;
  655. }
  656. eap = radius_msg_get_eap(msg);
  657. if (eap == NULL) {
  658. RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
  659. from_addr);
  660. data->counters.packets_dropped++;
  661. client->counters.packets_dropped++;
  662. return -1;
  663. }
  664. RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
  665. /* FIX: if Code is Request, Success, or Failure, send Access-Reject;
  666. * RFC3579 Sect. 2.6.2.
  667. * Include EAP-Response/Nak with no preferred method if
  668. * code == request.
  669. * If code is not 1-4, discard the packet silently.
  670. * Or is this already done by the EAP state machine? */
  671. wpabuf_free(sess->eap_if->eapRespData);
  672. sess->eap_if->eapRespData = eap;
  673. sess->eap_if->eapResp = TRUE;
  674. eap_server_sm_step(sess->eap);
  675. if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
  676. sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
  677. RADIUS_DUMP("EAP data from the state machine",
  678. wpabuf_head(sess->eap_if->eapReqData),
  679. wpabuf_len(sess->eap_if->eapReqData));
  680. } else if (sess->eap_if->eapFail) {
  681. RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
  682. "set");
  683. } else if (eap_sm_method_pending(sess->eap)) {
  684. radius_msg_free(sess->last_msg);
  685. sess->last_msg = msg;
  686. sess->last_from_port = from_port;
  687. os_free(sess->last_from_addr);
  688. sess->last_from_addr = os_strdup(from_addr);
  689. sess->last_fromlen = fromlen;
  690. os_memcpy(&sess->last_from, from, fromlen);
  691. return -2;
  692. } else {
  693. RADIUS_DEBUG("No EAP data from the state machine - ignore this"
  694. " Access-Request silently (assuming it was a "
  695. "duplicate)");
  696. data->counters.packets_dropped++;
  697. client->counters.packets_dropped++;
  698. return -1;
  699. }
  700. if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
  701. is_complete = 1;
  702. reply = radius_server_encapsulate_eap(data, client, sess, msg);
  703. if (reply) {
  704. struct wpabuf *buf;
  705. struct radius_hdr *hdr;
  706. RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
  707. if (wpa_debug_level <= MSG_MSGDUMP) {
  708. radius_msg_dump(reply);
  709. }
  710. switch (radius_msg_get_hdr(reply)->code) {
  711. case RADIUS_CODE_ACCESS_ACCEPT:
  712. data->counters.access_accepts++;
  713. client->counters.access_accepts++;
  714. break;
  715. case RADIUS_CODE_ACCESS_REJECT:
  716. data->counters.access_rejects++;
  717. client->counters.access_rejects++;
  718. break;
  719. case RADIUS_CODE_ACCESS_CHALLENGE:
  720. data->counters.access_challenges++;
  721. client->counters.access_challenges++;
  722. break;
  723. }
  724. buf = radius_msg_get_buf(reply);
  725. res = sendto(data->auth_sock, wpabuf_head(buf),
  726. wpabuf_len(buf), 0,
  727. (struct sockaddr *) from, fromlen);
  728. if (res < 0) {
  729. wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
  730. strerror(errno));
  731. }
  732. radius_msg_free(sess->last_reply);
  733. sess->last_reply = reply;
  734. sess->last_from_port = from_port;
  735. hdr = radius_msg_get_hdr(msg);
  736. sess->last_identifier = hdr->identifier;
  737. os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
  738. } else {
  739. data->counters.packets_dropped++;
  740. client->counters.packets_dropped++;
  741. }
  742. if (is_complete) {
  743. RADIUS_DEBUG("Removing completed session 0x%x after timeout",
  744. sess->sess_id);
  745. eloop_cancel_timeout(radius_server_session_remove_timeout,
  746. data, sess);
  747. eloop_register_timeout(10, 0,
  748. radius_server_session_remove_timeout,
  749. data, sess);
  750. }
  751. return 0;
  752. }
  753. static void radius_server_receive_auth(int sock, void *eloop_ctx,
  754. void *sock_ctx)
  755. {
  756. struct radius_server_data *data = eloop_ctx;
  757. u8 *buf = NULL;
  758. union {
  759. struct sockaddr_storage ss;
  760. struct sockaddr_in sin;
  761. #ifdef CONFIG_IPV6
  762. struct sockaddr_in6 sin6;
  763. #endif /* CONFIG_IPV6 */
  764. } from;
  765. socklen_t fromlen;
  766. int len;
  767. struct radius_client *client = NULL;
  768. struct radius_msg *msg = NULL;
  769. char abuf[50];
  770. int from_port = 0;
  771. buf = os_malloc(RADIUS_MAX_MSG_LEN);
  772. if (buf == NULL) {
  773. goto fail;
  774. }
  775. fromlen = sizeof(from);
  776. len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
  777. (struct sockaddr *) &from.ss, &fromlen);
  778. if (len < 0) {
  779. wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
  780. strerror(errno));
  781. goto fail;
  782. }
  783. #ifdef CONFIG_IPV6
  784. if (data->ipv6) {
  785. if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
  786. sizeof(abuf)) == NULL)
  787. abuf[0] = '\0';
  788. from_port = ntohs(from.sin6.sin6_port);
  789. RADIUS_DEBUG("Received %d bytes from %s:%d",
  790. len, abuf, from_port);
  791. client = radius_server_get_client(data,
  792. (struct in_addr *)
  793. &from.sin6.sin6_addr, 1);
  794. }
  795. #endif /* CONFIG_IPV6 */
  796. if (!data->ipv6) {
  797. os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
  798. from_port = ntohs(from.sin.sin_port);
  799. RADIUS_DEBUG("Received %d bytes from %s:%d",
  800. len, abuf, from_port);
  801. client = radius_server_get_client(data, &from.sin.sin_addr, 0);
  802. }
  803. RADIUS_DUMP("Received data", buf, len);
  804. if (client == NULL) {
  805. RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
  806. data->counters.invalid_requests++;
  807. goto fail;
  808. }
  809. msg = radius_msg_parse(buf, len);
  810. if (msg == NULL) {
  811. RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
  812. data->counters.malformed_access_requests++;
  813. client->counters.malformed_access_requests++;
  814. goto fail;
  815. }
  816. os_free(buf);
  817. buf = NULL;
  818. if (wpa_debug_level <= MSG_MSGDUMP) {
  819. radius_msg_dump(msg);
  820. }
  821. if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
  822. RADIUS_DEBUG("Unexpected RADIUS code %d",
  823. radius_msg_get_hdr(msg)->code);
  824. data->counters.unknown_types++;
  825. client->counters.unknown_types++;
  826. goto fail;
  827. }
  828. data->counters.access_requests++;
  829. client->counters.access_requests++;
  830. if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
  831. client->shared_secret_len, NULL)) {
  832. RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
  833. data->counters.bad_authenticators++;
  834. client->counters.bad_authenticators++;
  835. goto fail;
  836. }
  837. if (radius_server_request(data, msg, (struct sockaddr *) &from,
  838. fromlen, client, abuf, from_port, NULL) ==
  839. -2)
  840. return; /* msg was stored with the session */
  841. fail:
  842. radius_msg_free(msg);
  843. os_free(buf);
  844. }
  845. static int radius_server_disable_pmtu_discovery(int s)
  846. {
  847. int r = -1;
  848. #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
  849. /* Turn off Path MTU discovery on IPv4/UDP sockets. */
  850. int action = IP_PMTUDISC_DONT;
  851. r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
  852. sizeof(action));
  853. if (r == -1)
  854. wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
  855. "%s", strerror(errno));
  856. #endif
  857. return r;
  858. }
  859. static int radius_server_open_socket(int port)
  860. {
  861. int s;
  862. struct sockaddr_in addr;
  863. s = socket(PF_INET, SOCK_DGRAM, 0);
  864. if (s < 0) {
  865. wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
  866. return -1;
  867. }
  868. radius_server_disable_pmtu_discovery(s);
  869. os_memset(&addr, 0, sizeof(addr));
  870. addr.sin_family = AF_INET;
  871. addr.sin_port = htons(port);
  872. if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  873. wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
  874. close(s);
  875. return -1;
  876. }
  877. return s;
  878. }
  879. #ifdef CONFIG_IPV6
  880. static int radius_server_open_socket6(int port)
  881. {
  882. int s;
  883. struct sockaddr_in6 addr;
  884. s = socket(PF_INET6, SOCK_DGRAM, 0);
  885. if (s < 0) {
  886. wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
  887. strerror(errno));
  888. return -1;
  889. }
  890. os_memset(&addr, 0, sizeof(addr));
  891. addr.sin6_family = AF_INET6;
  892. os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
  893. addr.sin6_port = htons(port);
  894. if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  895. wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
  896. close(s);
  897. return -1;
  898. }
  899. return s;
  900. }
  901. #endif /* CONFIG_IPV6 */
  902. static void radius_server_free_sessions(struct radius_server_data *data,
  903. struct radius_session *sessions)
  904. {
  905. struct radius_session *session, *prev;
  906. session = sessions;
  907. while (session) {
  908. prev = session;
  909. session = session->next;
  910. radius_server_session_free(data, prev);
  911. }
  912. }
  913. static void radius_server_free_clients(struct radius_server_data *data,
  914. struct radius_client *clients)
  915. {
  916. struct radius_client *client, *prev;
  917. client = clients;
  918. while (client) {
  919. prev = client;
  920. client = client->next;
  921. radius_server_free_sessions(data, prev->sessions);
  922. os_free(prev->shared_secret);
  923. os_free(prev);
  924. }
  925. }
  926. static struct radius_client *
  927. radius_server_read_clients(const char *client_file, int ipv6)
  928. {
  929. FILE *f;
  930. const int buf_size = 1024;
  931. char *buf, *pos;
  932. struct radius_client *clients, *tail, *entry;
  933. int line = 0, mask, failed = 0, i;
  934. struct in_addr addr;
  935. #ifdef CONFIG_IPV6
  936. struct in6_addr addr6;
  937. #endif /* CONFIG_IPV6 */
  938. unsigned int val;
  939. f = fopen(client_file, "r");
  940. if (f == NULL) {
  941. RADIUS_ERROR("Could not open client file '%s'", client_file);
  942. return NULL;
  943. }
  944. buf = os_malloc(buf_size);
  945. if (buf == NULL) {
  946. fclose(f);
  947. return NULL;
  948. }
  949. clients = tail = NULL;
  950. while (fgets(buf, buf_size, f)) {
  951. /* Configuration file format:
  952. * 192.168.1.0/24 secret
  953. * 192.168.1.2 secret
  954. * fe80::211:22ff:fe33:4455/64 secretipv6
  955. */
  956. line++;
  957. buf[buf_size - 1] = '\0';
  958. pos = buf;
  959. while (*pos != '\0' && *pos != '\n')
  960. pos++;
  961. if (*pos == '\n')
  962. *pos = '\0';
  963. if (*buf == '\0' || *buf == '#')
  964. continue;
  965. pos = buf;
  966. while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
  967. (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
  968. (*pos >= 'A' && *pos <= 'F')) {
  969. pos++;
  970. }
  971. if (*pos == '\0') {
  972. failed = 1;
  973. break;
  974. }
  975. if (*pos == '/') {
  976. char *end;
  977. *pos++ = '\0';
  978. mask = strtol(pos, &end, 10);
  979. if ((pos == end) ||
  980. (mask < 0 || mask > (ipv6 ? 128 : 32))) {
  981. failed = 1;
  982. break;
  983. }
  984. pos = end;
  985. } else {
  986. mask = ipv6 ? 128 : 32;
  987. *pos++ = '\0';
  988. }
  989. if (!ipv6 && inet_aton(buf, &addr) == 0) {
  990. failed = 1;
  991. break;
  992. }
  993. #ifdef CONFIG_IPV6
  994. if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
  995. if (inet_pton(AF_INET, buf, &addr) <= 0) {
  996. failed = 1;
  997. break;
  998. }
  999. /* Convert IPv4 address to IPv6 */
  1000. if (mask <= 32)
  1001. mask += (128 - 32);
  1002. os_memset(addr6.s6_addr, 0, 10);
  1003. addr6.s6_addr[10] = 0xff;
  1004. addr6.s6_addr[11] = 0xff;
  1005. os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
  1006. 4);
  1007. }
  1008. #endif /* CONFIG_IPV6 */
  1009. while (*pos == ' ' || *pos == '\t') {
  1010. pos++;
  1011. }
  1012. if (*pos == '\0') {
  1013. failed = 1;
  1014. break;
  1015. }
  1016. entry = os_zalloc(sizeof(*entry));
  1017. if (entry == NULL) {
  1018. failed = 1;
  1019. break;
  1020. }
  1021. entry->shared_secret = os_strdup(pos);
  1022. if (entry->shared_secret == NULL) {
  1023. failed = 1;
  1024. os_free(entry);
  1025. break;
  1026. }
  1027. entry->shared_secret_len = os_strlen(entry->shared_secret);
  1028. entry->addr.s_addr = addr.s_addr;
  1029. if (!ipv6) {
  1030. val = 0;
  1031. for (i = 0; i < mask; i++)
  1032. val |= 1 << (31 - i);
  1033. entry->mask.s_addr = htonl(val);
  1034. }
  1035. #ifdef CONFIG_IPV6
  1036. if (ipv6) {
  1037. int offset = mask / 8;
  1038. os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
  1039. os_memset(entry->mask6.s6_addr, 0xff, offset);
  1040. val = 0;
  1041. for (i = 0; i < (mask % 8); i++)
  1042. val |= 1 << (7 - i);
  1043. if (offset < 16)
  1044. entry->mask6.s6_addr[offset] = val;
  1045. }
  1046. #endif /* CONFIG_IPV6 */
  1047. if (tail == NULL) {
  1048. clients = tail = entry;
  1049. } else {
  1050. tail->next = entry;
  1051. tail = entry;
  1052. }
  1053. }
  1054. if (failed) {
  1055. RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
  1056. radius_server_free_clients(NULL, clients);
  1057. clients = NULL;
  1058. }
  1059. os_free(buf);
  1060. fclose(f);
  1061. return clients;
  1062. }
  1063. /**
  1064. * radius_server_init - Initialize RADIUS server
  1065. * @conf: Configuration for the RADIUS server
  1066. * Returns: Pointer to private RADIUS server context or %NULL on failure
  1067. *
  1068. * This initializes a RADIUS server instance and returns a context pointer that
  1069. * will be used in other calls to the RADIUS server module. The server can be
  1070. * deinitialize by calling radius_server_deinit().
  1071. */
  1072. struct radius_server_data *
  1073. radius_server_init(struct radius_server_conf *conf)
  1074. {
  1075. struct radius_server_data *data;
  1076. #ifndef CONFIG_IPV6
  1077. if (conf->ipv6) {
  1078. wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
  1079. return NULL;
  1080. }
  1081. #endif /* CONFIG_IPV6 */
  1082. data = os_zalloc(sizeof(*data));
  1083. if (data == NULL)
  1084. return NULL;
  1085. os_get_time(&data->start_time);
  1086. data->conf_ctx = conf->conf_ctx;
  1087. data->eap_sim_db_priv = conf->eap_sim_db_priv;
  1088. data->ssl_ctx = conf->ssl_ctx;
  1089. data->msg_ctx = conf->msg_ctx;
  1090. data->ipv6 = conf->ipv6;
  1091. if (conf->pac_opaque_encr_key) {
  1092. data->pac_opaque_encr_key = os_malloc(16);
  1093. os_memcpy(data->pac_opaque_encr_key, conf->pac_opaque_encr_key,
  1094. 16);
  1095. }
  1096. if (conf->eap_fast_a_id) {
  1097. data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
  1098. if (data->eap_fast_a_id) {
  1099. os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id,
  1100. conf->eap_fast_a_id_len);
  1101. data->eap_fast_a_id_len = conf->eap_fast_a_id_len;
  1102. }
  1103. }
  1104. if (conf->eap_fast_a_id_info)
  1105. data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
  1106. data->eap_fast_prov = conf->eap_fast_prov;
  1107. data->pac_key_lifetime = conf->pac_key_lifetime;
  1108. data->pac_key_refresh_time = conf->pac_key_refresh_time;
  1109. data->get_eap_user = conf->get_eap_user;
  1110. data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
  1111. data->tnc = conf->tnc;
  1112. data->wps = conf->wps;
  1113. data->pwd_group = conf->pwd_group;
  1114. data->server_id = conf->server_id;
  1115. if (conf->eap_req_id_text) {
  1116. data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
  1117. if (data->eap_req_id_text) {
  1118. os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
  1119. conf->eap_req_id_text_len);
  1120. data->eap_req_id_text_len = conf->eap_req_id_text_len;
  1121. }
  1122. }
  1123. #ifdef CONFIG_RADIUS_TEST
  1124. if (conf->dump_msk_file)
  1125. data->dump_msk_file = os_strdup(conf->dump_msk_file);
  1126. #endif /* CONFIG_RADIUS_TEST */
  1127. data->clients = radius_server_read_clients(conf->client_file,
  1128. conf->ipv6);
  1129. if (data->clients == NULL) {
  1130. wpa_printf(MSG_ERROR, "No RADIUS clients configured");
  1131. radius_server_deinit(data);
  1132. return NULL;
  1133. }
  1134. #ifdef CONFIG_IPV6
  1135. if (conf->ipv6)
  1136. data->auth_sock = radius_server_open_socket6(conf->auth_port);
  1137. else
  1138. #endif /* CONFIG_IPV6 */
  1139. data->auth_sock = radius_server_open_socket(conf->auth_port);
  1140. if (data->auth_sock < 0) {
  1141. wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
  1142. radius_server_deinit(data);
  1143. return NULL;
  1144. }
  1145. if (eloop_register_read_sock(data->auth_sock,
  1146. radius_server_receive_auth,
  1147. data, NULL)) {
  1148. radius_server_deinit(data);
  1149. return NULL;
  1150. }
  1151. return data;
  1152. }
  1153. /**
  1154. * radius_server_deinit - Deinitialize RADIUS server
  1155. * @data: RADIUS server context from radius_server_init()
  1156. */
  1157. void radius_server_deinit(struct radius_server_data *data)
  1158. {
  1159. if (data == NULL)
  1160. return;
  1161. if (data->auth_sock >= 0) {
  1162. eloop_unregister_read_sock(data->auth_sock);
  1163. close(data->auth_sock);
  1164. }
  1165. radius_server_free_clients(data, data->clients);
  1166. os_free(data->pac_opaque_encr_key);
  1167. os_free(data->eap_fast_a_id);
  1168. os_free(data->eap_fast_a_id_info);
  1169. os_free(data->eap_req_id_text);
  1170. #ifdef CONFIG_RADIUS_TEST
  1171. os_free(data->dump_msk_file);
  1172. #endif /* CONFIG_RADIUS_TEST */
  1173. os_free(data);
  1174. }
  1175. /**
  1176. * radius_server_get_mib - Get RADIUS server MIB information
  1177. * @data: RADIUS server context from radius_server_init()
  1178. * @buf: Buffer for returning the MIB data in text format
  1179. * @buflen: buf length in octets
  1180. * Returns: Number of octets written into buf
  1181. */
  1182. int radius_server_get_mib(struct radius_server_data *data, char *buf,
  1183. size_t buflen)
  1184. {
  1185. int ret, uptime;
  1186. unsigned int idx;
  1187. char *end, *pos;
  1188. struct os_time now;
  1189. struct radius_client *cli;
  1190. /* RFC 2619 - RADIUS Authentication Server MIB */
  1191. if (data == NULL || buflen == 0)
  1192. return 0;
  1193. pos = buf;
  1194. end = buf + buflen;
  1195. os_get_time(&now);
  1196. uptime = (now.sec - data->start_time.sec) * 100 +
  1197. ((now.usec - data->start_time.usec) / 10000) % 100;
  1198. ret = os_snprintf(pos, end - pos,
  1199. "RADIUS-AUTH-SERVER-MIB\n"
  1200. "radiusAuthServIdent=hostapd\n"
  1201. "radiusAuthServUpTime=%d\n"
  1202. "radiusAuthServResetTime=0\n"
  1203. "radiusAuthServConfigReset=4\n",
  1204. uptime);
  1205. if (ret < 0 || ret >= end - pos) {
  1206. *pos = '\0';
  1207. return pos - buf;
  1208. }
  1209. pos += ret;
  1210. ret = os_snprintf(pos, end - pos,
  1211. "radiusAuthServTotalAccessRequests=%u\n"
  1212. "radiusAuthServTotalInvalidRequests=%u\n"
  1213. "radiusAuthServTotalDupAccessRequests=%u\n"
  1214. "radiusAuthServTotalAccessAccepts=%u\n"
  1215. "radiusAuthServTotalAccessRejects=%u\n"
  1216. "radiusAuthServTotalAccessChallenges=%u\n"
  1217. "radiusAuthServTotalMalformedAccessRequests=%u\n"
  1218. "radiusAuthServTotalBadAuthenticators=%u\n"
  1219. "radiusAuthServTotalPacketsDropped=%u\n"
  1220. "radiusAuthServTotalUnknownTypes=%u\n",
  1221. data->counters.access_requests,
  1222. data->counters.invalid_requests,
  1223. data->counters.dup_access_requests,
  1224. data->counters.access_accepts,
  1225. data->counters.access_rejects,
  1226. data->counters.access_challenges,
  1227. data->counters.malformed_access_requests,
  1228. data->counters.bad_authenticators,
  1229. data->counters.packets_dropped,
  1230. data->counters.unknown_types);
  1231. if (ret < 0 || ret >= end - pos) {
  1232. *pos = '\0';
  1233. return pos - buf;
  1234. }
  1235. pos += ret;
  1236. for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
  1237. char abuf[50], mbuf[50];
  1238. #ifdef CONFIG_IPV6
  1239. if (data->ipv6) {
  1240. if (inet_ntop(AF_INET6, &cli->addr6, abuf,
  1241. sizeof(abuf)) == NULL)
  1242. abuf[0] = '\0';
  1243. if (inet_ntop(AF_INET6, &cli->mask6, abuf,
  1244. sizeof(mbuf)) == NULL)
  1245. mbuf[0] = '\0';
  1246. }
  1247. #endif /* CONFIG_IPV6 */
  1248. if (!data->ipv6) {
  1249. os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
  1250. os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
  1251. }
  1252. ret = os_snprintf(pos, end - pos,
  1253. "radiusAuthClientIndex=%u\n"
  1254. "radiusAuthClientAddress=%s/%s\n"
  1255. "radiusAuthServAccessRequests=%u\n"
  1256. "radiusAuthServDupAccessRequests=%u\n"
  1257. "radiusAuthServAccessAccepts=%u\n"
  1258. "radiusAuthServAccessRejects=%u\n"
  1259. "radiusAuthServAccessChallenges=%u\n"
  1260. "radiusAuthServMalformedAccessRequests=%u\n"
  1261. "radiusAuthServBadAuthenticators=%u\n"
  1262. "radiusAuthServPacketsDropped=%u\n"
  1263. "radiusAuthServUnknownTypes=%u\n",
  1264. idx,
  1265. abuf, mbuf,
  1266. cli->counters.access_requests,
  1267. cli->counters.dup_access_requests,
  1268. cli->counters.access_accepts,
  1269. cli->counters.access_rejects,
  1270. cli->counters.access_challenges,
  1271. cli->counters.malformed_access_requests,
  1272. cli->counters.bad_authenticators,
  1273. cli->counters.packets_dropped,
  1274. cli->counters.unknown_types);
  1275. if (ret < 0 || ret >= end - pos) {
  1276. *pos = '\0';
  1277. return pos - buf;
  1278. }
  1279. pos += ret;
  1280. }
  1281. return pos - buf;
  1282. }
  1283. static int radius_server_get_eap_user(void *ctx, const u8 *identity,
  1284. size_t identity_len, int phase2,
  1285. struct eap_user *user)
  1286. {
  1287. struct radius_session *sess = ctx;
  1288. struct radius_server_data *data = sess->server;
  1289. return data->get_eap_user(data->conf_ctx, identity, identity_len,
  1290. phase2, user);
  1291. }
  1292. static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
  1293. {
  1294. struct radius_session *sess = ctx;
  1295. struct radius_server_data *data = sess->server;
  1296. *len = data->eap_req_id_text_len;
  1297. return data->eap_req_id_text;
  1298. }
  1299. static struct eapol_callbacks radius_server_eapol_cb =
  1300. {
  1301. .get_eap_user = radius_server_get_eap_user,
  1302. .get_eap_req_id_text = radius_server_get_eap_req_id_text,
  1303. };
  1304. /**
  1305. * radius_server_eap_pending_cb - Pending EAP data notification
  1306. * @data: RADIUS server context from radius_server_init()
  1307. * @ctx: Pending EAP context pointer
  1308. *
  1309. * This function is used to notify EAP server module that a pending operation
  1310. * has been completed and processing of the EAP session can proceed.
  1311. */
  1312. void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
  1313. {
  1314. struct radius_client *cli;
  1315. struct radius_session *s, *sess = NULL;
  1316. struct radius_msg *msg;
  1317. if (data == NULL)
  1318. return;
  1319. for (cli = data->clients; cli; cli = cli->next) {
  1320. for (s = cli->sessions; s; s = s->next) {
  1321. if (s->eap == ctx && s->last_msg) {
  1322. sess = s;
  1323. break;
  1324. }
  1325. if (sess)
  1326. break;
  1327. }
  1328. if (sess)
  1329. break;
  1330. }
  1331. if (sess == NULL) {
  1332. RADIUS_DEBUG("No session matched callback ctx");
  1333. return;
  1334. }
  1335. msg = sess->last_msg;
  1336. sess->last_msg = NULL;
  1337. eap_sm_pending_cb(sess->eap);
  1338. if (radius_server_request(data, msg,
  1339. (struct sockaddr *) &sess->last_from,
  1340. sess->last_fromlen, cli,
  1341. sess->last_from_addr,
  1342. sess->last_from_port, sess) == -2)
  1343. return; /* msg was stored with the session */
  1344. radius_msg_free(msg);
  1345. }