radius_server.c 39 KB

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