config.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  1. /*
  2. * WPA Supplicant / Configuration parser and common functions
  3. * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "wpa.h"
  17. #include "sha1.h"
  18. #include "eap_peer/eap.h"
  19. #include "config.h"
  20. #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
  21. #define NO_CONFIG_WRITE
  22. #endif
  23. /*
  24. * Structure for network configuration parsing. This data is used to implement
  25. * a generic parser for each network block variable. The table of configuration
  26. * variables is defined below in this file (ssid_fields[]).
  27. */
  28. struct parse_data {
  29. /* Configuration variable name */
  30. char *name;
  31. /* Parser function for this variable */
  32. int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
  33. int line, const char *value);
  34. #ifndef NO_CONFIG_WRITE
  35. /* Writer function (i.e., to get the variable in text format from
  36. * internal presentation). */
  37. char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
  38. #endif /* NO_CONFIG_WRITE */
  39. /* Variable specific parameters for the parser. */
  40. void *param1, *param2, *param3, *param4;
  41. /* 0 = this variable can be included in debug output and ctrl_iface
  42. * 1 = this variable contains key/private data and it must not be
  43. * included in debug output unless explicitly requested. In
  44. * addition, this variable will not be readable through the
  45. * ctrl_iface.
  46. */
  47. int key_data;
  48. };
  49. static char * wpa_config_parse_string(const char *value, size_t *len)
  50. {
  51. if (*value == '"') {
  52. char *pos;
  53. value++;
  54. pos = os_strrchr(value, '"');
  55. if (pos == NULL || pos[1] != '\0')
  56. return NULL;
  57. *pos = '\0';
  58. *len = os_strlen(value);
  59. return os_strdup(value);
  60. } else {
  61. u8 *str;
  62. size_t tlen, hlen = os_strlen(value);
  63. if (hlen & 1)
  64. return NULL;
  65. tlen = hlen / 2;
  66. str = os_malloc(tlen + 1);
  67. if (str == NULL)
  68. return NULL;
  69. if (hexstr2bin(value, str, tlen)) {
  70. os_free(str);
  71. return NULL;
  72. }
  73. str[tlen] = '\0';
  74. *len = tlen;
  75. return (char *) str;
  76. }
  77. }
  78. static int wpa_config_parse_str(const struct parse_data *data,
  79. struct wpa_ssid *ssid,
  80. int line, const char *value)
  81. {
  82. size_t res_len, *dst_len;
  83. char **dst, *tmp;
  84. tmp = wpa_config_parse_string(value, &res_len);
  85. if (tmp == NULL) {
  86. wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
  87. line, data->name,
  88. data->key_data ? "[KEY DATA REMOVED]" : value);
  89. return -1;
  90. }
  91. if (data->key_data) {
  92. wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
  93. (u8 *) tmp, res_len);
  94. } else {
  95. wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
  96. (u8 *) tmp, res_len);
  97. }
  98. if (data->param3 && res_len < (size_t) data->param3) {
  99. wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
  100. "min_len=%ld)", line, data->name,
  101. (unsigned long) res_len, (long) data->param3);
  102. os_free(tmp);
  103. return -1;
  104. }
  105. if (data->param4 && res_len > (size_t) data->param4) {
  106. wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
  107. "max_len=%ld)", line, data->name,
  108. (unsigned long) res_len, (long) data->param4);
  109. os_free(tmp);
  110. return -1;
  111. }
  112. dst = (char **) (((u8 *) ssid) + (long) data->param1);
  113. dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
  114. os_free(*dst);
  115. *dst = tmp;
  116. if (data->param2)
  117. *dst_len = res_len;
  118. return 0;
  119. }
  120. #ifndef NO_CONFIG_WRITE
  121. static int is_hex(const u8 *data, size_t len)
  122. {
  123. size_t i;
  124. for (i = 0; i < len; i++) {
  125. if (data[i] < 32 || data[i] >= 127)
  126. return 1;
  127. }
  128. return 0;
  129. }
  130. static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
  131. {
  132. char *buf;
  133. buf = os_malloc(len + 3);
  134. if (buf == NULL)
  135. return NULL;
  136. buf[0] = '"';
  137. os_memcpy(buf + 1, value, len);
  138. buf[len + 1] = '"';
  139. buf[len + 2] = '\0';
  140. return buf;
  141. }
  142. static char * wpa_config_write_string_hex(const u8 *value, size_t len)
  143. {
  144. char *buf;
  145. buf = os_zalloc(2 * len + 1);
  146. if (buf == NULL)
  147. return NULL;
  148. wpa_snprintf_hex(buf, 2 * len + 1, value, len);
  149. return buf;
  150. }
  151. static char * wpa_config_write_string(const u8 *value, size_t len)
  152. {
  153. if (value == NULL)
  154. return NULL;
  155. if (is_hex(value, len))
  156. return wpa_config_write_string_hex(value, len);
  157. else
  158. return wpa_config_write_string_ascii(value, len);
  159. }
  160. static char * wpa_config_write_str(const struct parse_data *data,
  161. struct wpa_ssid *ssid)
  162. {
  163. size_t len;
  164. char **src;
  165. src = (char **) (((u8 *) ssid) + (long) data->param1);
  166. if (*src == NULL)
  167. return NULL;
  168. if (data->param2)
  169. len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
  170. else
  171. len = os_strlen(*src);
  172. return wpa_config_write_string((const u8 *) *src, len);
  173. }
  174. #endif /* NO_CONFIG_WRITE */
  175. static int wpa_config_parse_int(const struct parse_data *data,
  176. struct wpa_ssid *ssid,
  177. int line, const char *value)
  178. {
  179. int *dst;
  180. dst = (int *) (((u8 *) ssid) + (long) data->param1);
  181. *dst = atoi(value);
  182. wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
  183. if (data->param3 && *dst < (long) data->param3) {
  184. wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
  185. "min_value=%ld)", line, data->name, *dst,
  186. (long) data->param3);
  187. *dst = (long) data->param3;
  188. return -1;
  189. }
  190. if (data->param4 && *dst > (long) data->param4) {
  191. wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
  192. "max_value=%ld)", line, data->name, *dst,
  193. (long) data->param4);
  194. *dst = (long) data->param4;
  195. return -1;
  196. }
  197. return 0;
  198. }
  199. #ifndef NO_CONFIG_WRITE
  200. static char * wpa_config_write_int(const struct parse_data *data,
  201. struct wpa_ssid *ssid)
  202. {
  203. int *src, res;
  204. char *value;
  205. src = (int *) (((u8 *) ssid) + (long) data->param1);
  206. value = os_malloc(20);
  207. if (value == NULL)
  208. return NULL;
  209. res = os_snprintf(value, 20, "%d", *src);
  210. if (res < 0 || res >= 20) {
  211. os_free(value);
  212. return NULL;
  213. }
  214. value[20 - 1] = '\0';
  215. return value;
  216. }
  217. #endif /* NO_CONFIG_WRITE */
  218. static int wpa_config_parse_bssid(const struct parse_data *data,
  219. struct wpa_ssid *ssid, int line,
  220. const char *value)
  221. {
  222. if (hwaddr_aton(value, ssid->bssid)) {
  223. wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
  224. line, value);
  225. return -1;
  226. }
  227. ssid->bssid_set = 1;
  228. wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
  229. return 0;
  230. }
  231. #ifndef NO_CONFIG_WRITE
  232. static char * wpa_config_write_bssid(const struct parse_data *data,
  233. struct wpa_ssid *ssid)
  234. {
  235. char *value;
  236. int res;
  237. if (!ssid->bssid_set)
  238. return NULL;
  239. value = os_malloc(20);
  240. if (value == NULL)
  241. return NULL;
  242. res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
  243. if (res < 0 || res >= 20) {
  244. os_free(value);
  245. return NULL;
  246. }
  247. value[20 - 1] = '\0';
  248. return value;
  249. }
  250. #endif /* NO_CONFIG_WRITE */
  251. static int wpa_config_parse_psk(const struct parse_data *data,
  252. struct wpa_ssid *ssid, int line,
  253. const char *value)
  254. {
  255. if (*value == '"') {
  256. #ifndef CONFIG_NO_PBKDF2
  257. const char *pos;
  258. size_t len;
  259. value++;
  260. pos = os_strrchr(value, '"');
  261. if (pos)
  262. len = pos - value;
  263. else
  264. len = os_strlen(value);
  265. if (len < 8 || len > 63) {
  266. wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
  267. "length %lu (expected: 8..63) '%s'.",
  268. line, (unsigned long) len, value);
  269. return -1;
  270. }
  271. wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
  272. (u8 *) value, len);
  273. if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
  274. os_memcmp(ssid->passphrase, value, len) == 0)
  275. return 0;
  276. ssid->psk_set = 0;
  277. os_free(ssid->passphrase);
  278. ssid->passphrase = os_malloc(len + 1);
  279. if (ssid->passphrase == NULL)
  280. return -1;
  281. os_memcpy(ssid->passphrase, value, len);
  282. ssid->passphrase[len] = '\0';
  283. return 0;
  284. #else /* CONFIG_NO_PBKDF2 */
  285. wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
  286. "supported.", line);
  287. return -1;
  288. #endif /* CONFIG_NO_PBKDF2 */
  289. }
  290. if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
  291. value[PMK_LEN * 2] != '\0') {
  292. wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
  293. line, value);
  294. return -1;
  295. }
  296. os_free(ssid->passphrase);
  297. ssid->passphrase = NULL;
  298. ssid->psk_set = 1;
  299. wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
  300. return 0;
  301. }
  302. #ifndef NO_CONFIG_WRITE
  303. static char * wpa_config_write_psk(const struct parse_data *data,
  304. struct wpa_ssid *ssid)
  305. {
  306. if (ssid->passphrase)
  307. return wpa_config_write_string_ascii(
  308. (const u8 *) ssid->passphrase,
  309. os_strlen(ssid->passphrase));
  310. if (ssid->psk_set)
  311. return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
  312. return NULL;
  313. }
  314. #endif /* NO_CONFIG_WRITE */
  315. static int wpa_config_parse_proto(const struct parse_data *data,
  316. struct wpa_ssid *ssid, int line,
  317. const char *value)
  318. {
  319. int val = 0, last, errors = 0;
  320. char *start, *end, *buf;
  321. buf = os_strdup(value);
  322. if (buf == NULL)
  323. return -1;
  324. start = buf;
  325. while (*start != '\0') {
  326. while (*start == ' ' || *start == '\t')
  327. start++;
  328. if (*start == '\0')
  329. break;
  330. end = start;
  331. while (*end != ' ' && *end != '\t' && *end != '\0')
  332. end++;
  333. last = *end == '\0';
  334. *end = '\0';
  335. if (os_strcmp(start, "WPA") == 0)
  336. val |= WPA_PROTO_WPA;
  337. else if (os_strcmp(start, "RSN") == 0 ||
  338. os_strcmp(start, "WPA2") == 0)
  339. val |= WPA_PROTO_RSN;
  340. else {
  341. wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
  342. line, start);
  343. errors++;
  344. }
  345. if (last)
  346. break;
  347. start = end + 1;
  348. }
  349. os_free(buf);
  350. if (val == 0) {
  351. wpa_printf(MSG_ERROR,
  352. "Line %d: no proto values configured.", line);
  353. errors++;
  354. }
  355. wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
  356. ssid->proto = val;
  357. return errors ? -1 : 0;
  358. }
  359. #ifndef NO_CONFIG_WRITE
  360. static char * wpa_config_write_proto(const struct parse_data *data,
  361. struct wpa_ssid *ssid)
  362. {
  363. int first = 1, ret;
  364. char *buf, *pos, *end;
  365. pos = buf = os_zalloc(10);
  366. if (buf == NULL)
  367. return NULL;
  368. end = buf + 10;
  369. if (ssid->proto & WPA_PROTO_WPA) {
  370. ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
  371. if (ret < 0 || ret >= end - pos)
  372. return buf;
  373. pos += ret;
  374. first = 0;
  375. }
  376. if (ssid->proto & WPA_PROTO_RSN) {
  377. ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
  378. if (ret < 0 || ret >= end - pos)
  379. return buf;
  380. pos += ret;
  381. first = 0;
  382. }
  383. return buf;
  384. }
  385. #endif /* NO_CONFIG_WRITE */
  386. static int wpa_config_parse_key_mgmt(const struct parse_data *data,
  387. struct wpa_ssid *ssid, int line,
  388. const char *value)
  389. {
  390. int val = 0, last, errors = 0;
  391. char *start, *end, *buf;
  392. buf = os_strdup(value);
  393. if (buf == NULL)
  394. return -1;
  395. start = buf;
  396. while (*start != '\0') {
  397. while (*start == ' ' || *start == '\t')
  398. start++;
  399. if (*start == '\0')
  400. break;
  401. end = start;
  402. while (*end != ' ' && *end != '\t' && *end != '\0')
  403. end++;
  404. last = *end == '\0';
  405. *end = '\0';
  406. if (os_strcmp(start, "WPA-PSK") == 0)
  407. val |= WPA_KEY_MGMT_PSK;
  408. else if (os_strcmp(start, "WPA-EAP") == 0)
  409. val |= WPA_KEY_MGMT_IEEE8021X;
  410. else if (os_strcmp(start, "IEEE8021X") == 0)
  411. val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
  412. else if (os_strcmp(start, "NONE") == 0)
  413. val |= WPA_KEY_MGMT_NONE;
  414. else if (os_strcmp(start, "WPA-NONE") == 0)
  415. val |= WPA_KEY_MGMT_WPA_NONE;
  416. #ifdef CONFIG_IEEE80211R
  417. else if (os_strcmp(start, "FT-PSK") == 0)
  418. val |= WPA_KEY_MGMT_FT_PSK;
  419. else if (os_strcmp(start, "FT-EAP") == 0)
  420. val |= WPA_KEY_MGMT_FT_IEEE8021X;
  421. #endif /* CONFIG_IEEE80211R */
  422. #ifdef CONFIG_IEEE80211W
  423. else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
  424. val |= WPA_KEY_MGMT_PSK_SHA256;
  425. else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
  426. val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
  427. #endif /* CONFIG_IEEE80211W */
  428. else {
  429. wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
  430. line, start);
  431. errors++;
  432. }
  433. if (last)
  434. break;
  435. start = end + 1;
  436. }
  437. os_free(buf);
  438. if (val == 0) {
  439. wpa_printf(MSG_ERROR,
  440. "Line %d: no key_mgmt values configured.", line);
  441. errors++;
  442. }
  443. wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
  444. ssid->key_mgmt = val;
  445. return errors ? -1 : 0;
  446. }
  447. #ifndef NO_CONFIG_WRITE
  448. static char * wpa_config_write_key_mgmt(const struct parse_data *data,
  449. struct wpa_ssid *ssid)
  450. {
  451. char *buf, *pos, *end;
  452. int ret;
  453. pos = buf = os_zalloc(50);
  454. if (buf == NULL)
  455. return NULL;
  456. end = buf + 50;
  457. if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
  458. ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
  459. pos == buf ? "" : " ");
  460. if (ret < 0 || ret >= end - pos) {
  461. end[-1] = '\0';
  462. return buf;
  463. }
  464. pos += ret;
  465. }
  466. if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
  467. ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
  468. pos == buf ? "" : " ");
  469. if (ret < 0 || ret >= end - pos) {
  470. end[-1] = '\0';
  471. return buf;
  472. }
  473. pos += ret;
  474. }
  475. if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
  476. ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
  477. pos == buf ? "" : " ");
  478. if (ret < 0 || ret >= end - pos) {
  479. end[-1] = '\0';
  480. return buf;
  481. }
  482. pos += ret;
  483. }
  484. if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
  485. ret = os_snprintf(pos, end - pos, "%sNONE",
  486. pos == buf ? "" : " ");
  487. if (ret < 0 || ret >= end - pos) {
  488. end[-1] = '\0';
  489. return buf;
  490. }
  491. pos += ret;
  492. }
  493. if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
  494. ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
  495. pos == buf ? "" : " ");
  496. if (ret < 0 || ret >= end - pos) {
  497. end[-1] = '\0';
  498. return buf;
  499. }
  500. pos += ret;
  501. }
  502. #ifdef CONFIG_IEEE80211R
  503. if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK)
  504. pos += os_snprintf(pos, end - pos, "%sFT-PSK",
  505. pos == buf ? "" : " ");
  506. if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
  507. pos += os_snprintf(pos, end - pos, "%sFT-EAP",
  508. pos == buf ? "" : " ");
  509. #endif /* CONFIG_IEEE80211R */
  510. #ifdef CONFIG_IEEE80211W
  511. if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
  512. pos += os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
  513. pos == buf ? "" : " ");
  514. if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
  515. pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
  516. pos == buf ? "" : " ");
  517. #endif /* CONFIG_IEEE80211W */
  518. return buf;
  519. }
  520. #endif /* NO_CONFIG_WRITE */
  521. static int wpa_config_parse_cipher(int line, const char *value)
  522. {
  523. int val = 0, last;
  524. char *start, *end, *buf;
  525. buf = os_strdup(value);
  526. if (buf == NULL)
  527. return -1;
  528. start = buf;
  529. while (*start != '\0') {
  530. while (*start == ' ' || *start == '\t')
  531. start++;
  532. if (*start == '\0')
  533. break;
  534. end = start;
  535. while (*end != ' ' && *end != '\t' && *end != '\0')
  536. end++;
  537. last = *end == '\0';
  538. *end = '\0';
  539. if (os_strcmp(start, "CCMP") == 0)
  540. val |= WPA_CIPHER_CCMP;
  541. else if (os_strcmp(start, "TKIP") == 0)
  542. val |= WPA_CIPHER_TKIP;
  543. else if (os_strcmp(start, "WEP104") == 0)
  544. val |= WPA_CIPHER_WEP104;
  545. else if (os_strcmp(start, "WEP40") == 0)
  546. val |= WPA_CIPHER_WEP40;
  547. else if (os_strcmp(start, "NONE") == 0)
  548. val |= WPA_CIPHER_NONE;
  549. else {
  550. wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
  551. line, start);
  552. os_free(buf);
  553. return -1;
  554. }
  555. if (last)
  556. break;
  557. start = end + 1;
  558. }
  559. os_free(buf);
  560. if (val == 0) {
  561. wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
  562. line);
  563. return -1;
  564. }
  565. return val;
  566. }
  567. #ifndef NO_CONFIG_WRITE
  568. static char * wpa_config_write_cipher(int cipher)
  569. {
  570. char *buf, *pos, *end;
  571. int ret;
  572. pos = buf = os_zalloc(50);
  573. if (buf == NULL)
  574. return NULL;
  575. end = buf + 50;
  576. if (cipher & WPA_CIPHER_CCMP) {
  577. ret = os_snprintf(pos, end - pos, "%sCCMP",
  578. pos == buf ? "" : " ");
  579. if (ret < 0 || ret >= end - pos) {
  580. end[-1] = '\0';
  581. return buf;
  582. }
  583. pos += ret;
  584. }
  585. if (cipher & WPA_CIPHER_TKIP) {
  586. ret = os_snprintf(pos, end - pos, "%sTKIP",
  587. pos == buf ? "" : " ");
  588. if (ret < 0 || ret >= end - pos) {
  589. end[-1] = '\0';
  590. return buf;
  591. }
  592. pos += ret;
  593. }
  594. if (cipher & WPA_CIPHER_WEP104) {
  595. ret = os_snprintf(pos, end - pos, "%sWEP104",
  596. pos == buf ? "" : " ");
  597. if (ret < 0 || ret >= end - pos) {
  598. end[-1] = '\0';
  599. return buf;
  600. }
  601. pos += ret;
  602. }
  603. if (cipher & WPA_CIPHER_WEP40) {
  604. ret = os_snprintf(pos, end - pos, "%sWEP40",
  605. pos == buf ? "" : " ");
  606. if (ret < 0 || ret >= end - pos) {
  607. end[-1] = '\0';
  608. return buf;
  609. }
  610. pos += ret;
  611. }
  612. if (cipher & WPA_CIPHER_NONE) {
  613. ret = os_snprintf(pos, end - pos, "%sNONE",
  614. pos == buf ? "" : " ");
  615. if (ret < 0 || ret >= end - pos) {
  616. end[-1] = '\0';
  617. return buf;
  618. }
  619. pos += ret;
  620. }
  621. return buf;
  622. }
  623. #endif /* NO_CONFIG_WRITE */
  624. static int wpa_config_parse_pairwise(const struct parse_data *data,
  625. struct wpa_ssid *ssid, int line,
  626. const char *value)
  627. {
  628. int val;
  629. val = wpa_config_parse_cipher(line, value);
  630. if (val == -1)
  631. return -1;
  632. if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
  633. wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
  634. "(0x%x).", line, val);
  635. return -1;
  636. }
  637. wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
  638. ssid->pairwise_cipher = val;
  639. return 0;
  640. }
  641. #ifndef NO_CONFIG_WRITE
  642. static char * wpa_config_write_pairwise(const struct parse_data *data,
  643. struct wpa_ssid *ssid)
  644. {
  645. return wpa_config_write_cipher(ssid->pairwise_cipher);
  646. }
  647. #endif /* NO_CONFIG_WRITE */
  648. static int wpa_config_parse_group(const struct parse_data *data,
  649. struct wpa_ssid *ssid, int line,
  650. const char *value)
  651. {
  652. int val;
  653. val = wpa_config_parse_cipher(line, value);
  654. if (val == -1)
  655. return -1;
  656. if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
  657. WPA_CIPHER_WEP40)) {
  658. wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
  659. "(0x%x).", line, val);
  660. return -1;
  661. }
  662. wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
  663. ssid->group_cipher = val;
  664. return 0;
  665. }
  666. #ifndef NO_CONFIG_WRITE
  667. static char * wpa_config_write_group(const struct parse_data *data,
  668. struct wpa_ssid *ssid)
  669. {
  670. return wpa_config_write_cipher(ssid->group_cipher);
  671. }
  672. #endif /* NO_CONFIG_WRITE */
  673. static int wpa_config_parse_auth_alg(const struct parse_data *data,
  674. struct wpa_ssid *ssid, int line,
  675. const char *value)
  676. {
  677. int val = 0, last, errors = 0;
  678. char *start, *end, *buf;
  679. buf = os_strdup(value);
  680. if (buf == NULL)
  681. return -1;
  682. start = buf;
  683. while (*start != '\0') {
  684. while (*start == ' ' || *start == '\t')
  685. start++;
  686. if (*start == '\0')
  687. break;
  688. end = start;
  689. while (*end != ' ' && *end != '\t' && *end != '\0')
  690. end++;
  691. last = *end == '\0';
  692. *end = '\0';
  693. if (os_strcmp(start, "OPEN") == 0)
  694. val |= WPA_AUTH_ALG_OPEN;
  695. else if (os_strcmp(start, "SHARED") == 0)
  696. val |= WPA_AUTH_ALG_SHARED;
  697. else if (os_strcmp(start, "LEAP") == 0)
  698. val |= WPA_AUTH_ALG_LEAP;
  699. else {
  700. wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
  701. line, start);
  702. errors++;
  703. }
  704. if (last)
  705. break;
  706. start = end + 1;
  707. }
  708. os_free(buf);
  709. if (val == 0) {
  710. wpa_printf(MSG_ERROR,
  711. "Line %d: no auth_alg values configured.", line);
  712. errors++;
  713. }
  714. wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
  715. ssid->auth_alg = val;
  716. return errors ? -1 : 0;
  717. }
  718. #ifndef NO_CONFIG_WRITE
  719. static char * wpa_config_write_auth_alg(const struct parse_data *data,
  720. struct wpa_ssid *ssid)
  721. {
  722. char *buf, *pos, *end;
  723. int ret;
  724. pos = buf = os_zalloc(30);
  725. if (buf == NULL)
  726. return NULL;
  727. end = buf + 30;
  728. if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
  729. ret = os_snprintf(pos, end - pos, "%sOPEN",
  730. pos == buf ? "" : " ");
  731. if (ret < 0 || ret >= end - pos) {
  732. end[-1] = '\0';
  733. return buf;
  734. }
  735. pos += ret;
  736. }
  737. if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
  738. ret = os_snprintf(pos, end - pos, "%sSHARED",
  739. pos == buf ? "" : " ");
  740. if (ret < 0 || ret >= end - pos) {
  741. end[-1] = '\0';
  742. return buf;
  743. }
  744. pos += ret;
  745. }
  746. if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
  747. ret = os_snprintf(pos, end - pos, "%sLEAP",
  748. pos == buf ? "" : " ");
  749. if (ret < 0 || ret >= end - pos) {
  750. end[-1] = '\0';
  751. return buf;
  752. }
  753. pos += ret;
  754. }
  755. return buf;
  756. }
  757. #endif /* NO_CONFIG_WRITE */
  758. #ifdef IEEE8021X_EAPOL
  759. static int wpa_config_parse_eap(const struct parse_data *data,
  760. struct wpa_ssid *ssid, int line,
  761. const char *value)
  762. {
  763. int last, errors = 0;
  764. char *start, *end, *buf;
  765. struct eap_method_type *methods = NULL, *tmp;
  766. size_t num_methods = 0;
  767. buf = os_strdup(value);
  768. if (buf == NULL)
  769. return -1;
  770. start = buf;
  771. while (*start != '\0') {
  772. while (*start == ' ' || *start == '\t')
  773. start++;
  774. if (*start == '\0')
  775. break;
  776. end = start;
  777. while (*end != ' ' && *end != '\t' && *end != '\0')
  778. end++;
  779. last = *end == '\0';
  780. *end = '\0';
  781. tmp = methods;
  782. methods = os_realloc(methods,
  783. (num_methods + 1) * sizeof(*methods));
  784. if (methods == NULL) {
  785. os_free(tmp);
  786. os_free(buf);
  787. return -1;
  788. }
  789. methods[num_methods].method = eap_peer_get_type(
  790. start, &methods[num_methods].vendor);
  791. if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
  792. methods[num_methods].method == EAP_TYPE_NONE) {
  793. wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
  794. "'%s'", line, start);
  795. wpa_printf(MSG_ERROR, "You may need to add support for"
  796. " this EAP method during wpa_supplicant\n"
  797. "build time configuration.\n"
  798. "See README for more information.");
  799. errors++;
  800. } else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
  801. methods[num_methods].method == EAP_TYPE_LEAP)
  802. ssid->leap++;
  803. else
  804. ssid->non_leap++;
  805. num_methods++;
  806. if (last)
  807. break;
  808. start = end + 1;
  809. }
  810. os_free(buf);
  811. tmp = methods;
  812. methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods));
  813. if (methods == NULL) {
  814. os_free(tmp);
  815. return -1;
  816. }
  817. methods[num_methods].vendor = EAP_VENDOR_IETF;
  818. methods[num_methods].method = EAP_TYPE_NONE;
  819. num_methods++;
  820. wpa_hexdump(MSG_MSGDUMP, "eap methods",
  821. (u8 *) methods, num_methods * sizeof(*methods));
  822. ssid->eap.eap_methods = methods;
  823. return errors ? -1 : 0;
  824. }
  825. static char * wpa_config_write_eap(const struct parse_data *data,
  826. struct wpa_ssid *ssid)
  827. {
  828. int i, ret;
  829. char *buf, *pos, *end;
  830. const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
  831. const char *name;
  832. if (eap_methods == NULL)
  833. return NULL;
  834. pos = buf = os_zalloc(100);
  835. if (buf == NULL)
  836. return NULL;
  837. end = buf + 100;
  838. for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
  839. eap_methods[i].method != EAP_TYPE_NONE; i++) {
  840. name = eap_get_name(eap_methods[i].vendor,
  841. eap_methods[i].method);
  842. if (name) {
  843. ret = os_snprintf(pos, end - pos, "%s%s",
  844. pos == buf ? "" : " ", name);
  845. if (ret < 0 || ret >= end - pos)
  846. break;
  847. pos += ret;
  848. }
  849. }
  850. end[-1] = '\0';
  851. return buf;
  852. }
  853. static int wpa_config_parse_password(const struct parse_data *data,
  854. struct wpa_ssid *ssid, int line,
  855. const char *value)
  856. {
  857. u8 *hash;
  858. if (os_strncmp(value, "hash:", 5) != 0) {
  859. char *tmp;
  860. size_t res_len;
  861. tmp = wpa_config_parse_string(value, &res_len);
  862. if (tmp == NULL) {
  863. wpa_printf(MSG_ERROR, "Line %d: failed to parse "
  864. "password.", line);
  865. return -1;
  866. }
  867. wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
  868. (u8 *) tmp, res_len);
  869. os_free(ssid->eap.password);
  870. ssid->eap.password = (u8 *) tmp;
  871. ssid->eap.password_len = res_len;
  872. ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
  873. return 0;
  874. }
  875. /* NtPasswordHash: hash:<32 hex digits> */
  876. if (os_strlen(value + 5) != 2 * 16) {
  877. wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length "
  878. "(expected 32 hex digits)", line);
  879. return -1;
  880. }
  881. hash = os_malloc(16);
  882. if (hash == NULL)
  883. return -1;
  884. if (hexstr2bin(value + 5, hash, 16)) {
  885. os_free(hash);
  886. wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
  887. return -1;
  888. }
  889. wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
  890. os_free(ssid->eap.password);
  891. ssid->eap.password = hash;
  892. ssid->eap.password_len = 16;
  893. ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
  894. return 0;
  895. }
  896. static char * wpa_config_write_password(const struct parse_data *data,
  897. struct wpa_ssid *ssid)
  898. {
  899. char *buf;
  900. if (ssid->eap.password == NULL)
  901. return NULL;
  902. if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
  903. return wpa_config_write_string(
  904. ssid->eap.password, ssid->eap.password_len);
  905. }
  906. buf = os_malloc(5 + 32 + 1);
  907. if (buf == NULL)
  908. return NULL;
  909. os_memcpy(buf, "hash:", 5);
  910. wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16);
  911. return buf;
  912. }
  913. #endif /* IEEE8021X_EAPOL */
  914. static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
  915. const char *value, int idx)
  916. {
  917. char *buf, title[20];
  918. int res;
  919. buf = wpa_config_parse_string(value, len);
  920. if (buf == NULL) {
  921. wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
  922. line, idx, value);
  923. return -1;
  924. }
  925. if (*len > MAX_WEP_KEY_LEN) {
  926. wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
  927. line, idx, value);
  928. os_free(buf);
  929. return -1;
  930. }
  931. os_memcpy(key, buf, *len);
  932. os_free(buf);
  933. res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
  934. if (res >= 0 && (size_t) res < sizeof(title))
  935. wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
  936. return 0;
  937. }
  938. static int wpa_config_parse_wep_key0(const struct parse_data *data,
  939. struct wpa_ssid *ssid, int line,
  940. const char *value)
  941. {
  942. return wpa_config_parse_wep_key(ssid->wep_key[0],
  943. &ssid->wep_key_len[0], line,
  944. value, 0);
  945. }
  946. static int wpa_config_parse_wep_key1(const struct parse_data *data,
  947. struct wpa_ssid *ssid, int line,
  948. const char *value)
  949. {
  950. return wpa_config_parse_wep_key(ssid->wep_key[1],
  951. &ssid->wep_key_len[1], line,
  952. value, 1);
  953. }
  954. static int wpa_config_parse_wep_key2(const struct parse_data *data,
  955. struct wpa_ssid *ssid, int line,
  956. const char *value)
  957. {
  958. return wpa_config_parse_wep_key(ssid->wep_key[2],
  959. &ssid->wep_key_len[2], line,
  960. value, 2);
  961. }
  962. static int wpa_config_parse_wep_key3(const struct parse_data *data,
  963. struct wpa_ssid *ssid, int line,
  964. const char *value)
  965. {
  966. return wpa_config_parse_wep_key(ssid->wep_key[3],
  967. &ssid->wep_key_len[3], line,
  968. value, 3);
  969. }
  970. #ifndef NO_CONFIG_WRITE
  971. static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
  972. {
  973. if (ssid->wep_key_len[idx] == 0)
  974. return NULL;
  975. return wpa_config_write_string(ssid->wep_key[idx],
  976. ssid->wep_key_len[idx]);
  977. }
  978. static char * wpa_config_write_wep_key0(const struct parse_data *data,
  979. struct wpa_ssid *ssid)
  980. {
  981. return wpa_config_write_wep_key(ssid, 0);
  982. }
  983. static char * wpa_config_write_wep_key1(const struct parse_data *data,
  984. struct wpa_ssid *ssid)
  985. {
  986. return wpa_config_write_wep_key(ssid, 1);
  987. }
  988. static char * wpa_config_write_wep_key2(const struct parse_data *data,
  989. struct wpa_ssid *ssid)
  990. {
  991. return wpa_config_write_wep_key(ssid, 2);
  992. }
  993. static char * wpa_config_write_wep_key3(const struct parse_data *data,
  994. struct wpa_ssid *ssid)
  995. {
  996. return wpa_config_write_wep_key(ssid, 3);
  997. }
  998. #endif /* NO_CONFIG_WRITE */
  999. /* Helper macros for network block parser */
  1000. #ifdef OFFSET
  1001. #undef OFFSET
  1002. #endif /* OFFSET */
  1003. /* OFFSET: Get offset of a variable within the wpa_ssid structure */
  1004. #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
  1005. /* STR: Define a string variable for an ASCII string; f = field name */
  1006. #ifdef NO_CONFIG_WRITE
  1007. #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
  1008. #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
  1009. #else /* NO_CONFIG_WRITE */
  1010. #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
  1011. #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
  1012. #endif /* NO_CONFIG_WRITE */
  1013. #define STR(f) _STR(f), NULL, NULL, NULL, 0
  1014. #define STRe(f) _STRe(f), NULL, NULL, NULL, 0
  1015. #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
  1016. #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
  1017. /* STR_LEN: Define a string variable with a separate variable for storing the
  1018. * data length. Unlike STR(), this can be used to store arbitrary binary data
  1019. * (i.e., even nul termination character). */
  1020. #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
  1021. #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
  1022. #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
  1023. #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
  1024. #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
  1025. /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
  1026. * explicitly specified. */
  1027. #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
  1028. #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
  1029. #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
  1030. #ifdef NO_CONFIG_WRITE
  1031. #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
  1032. #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
  1033. #else /* NO_CONFIG_WRITE */
  1034. #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
  1035. OFFSET(f), (void *) 0
  1036. #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
  1037. OFFSET(eap.f), (void *) 0
  1038. #endif /* NO_CONFIG_WRITE */
  1039. /* INT: Define an integer variable */
  1040. #define INT(f) _INT(f), NULL, NULL, 0
  1041. #define INTe(f) _INTe(f), NULL, NULL, 0
  1042. /* INT_RANGE: Define an integer variable with allowed value range */
  1043. #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
  1044. /* FUNC: Define a configuration variable that uses a custom function for
  1045. * parsing and writing the value. */
  1046. #ifdef NO_CONFIG_WRITE
  1047. #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
  1048. #else /* NO_CONFIG_WRITE */
  1049. #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
  1050. NULL, NULL, NULL, NULL
  1051. #endif /* NO_CONFIG_WRITE */
  1052. #define FUNC(f) _FUNC(f), 0
  1053. #define FUNC_KEY(f) _FUNC(f), 1
  1054. /*
  1055. * Table of network configuration variables. This table is used to parse each
  1056. * network configuration variable, e.g., each line in wpa_supplicant.conf file
  1057. * that is inside a network block.
  1058. *
  1059. * This table is generated using the helper macros defined above and with
  1060. * generous help from the C pre-processor. The field name is stored as a string
  1061. * into .name and for STR and INT types, the offset of the target buffer within
  1062. * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
  1063. * offset to the field containing the length of the configuration variable.
  1064. * .param3 and .param4 can be used to mark the allowed range (length for STR
  1065. * and value for INT).
  1066. *
  1067. * For each configuration line in wpa_supplicant.conf, the parser goes through
  1068. * this table and select the entry that matches with the field name. The parser
  1069. * function (.parser) is then called to parse the actual value of the field.
  1070. *
  1071. * This kind of mechanism makes it easy to add new configuration parameters,
  1072. * since only one line needs to be added into this table and into the
  1073. * struct wpa_ssid definition if the new variable is either a string or
  1074. * integer. More complex types will need to use their own parser and writer
  1075. * functions.
  1076. */
  1077. static const struct parse_data ssid_fields[] = {
  1078. { STR_RANGE(ssid, 0, MAX_SSID_LEN) },
  1079. { INT_RANGE(scan_ssid, 0, 1) },
  1080. { FUNC(bssid) },
  1081. { FUNC_KEY(psk) },
  1082. { FUNC(proto) },
  1083. { FUNC(key_mgmt) },
  1084. { FUNC(pairwise) },
  1085. { FUNC(group) },
  1086. { FUNC(auth_alg) },
  1087. #ifdef IEEE8021X_EAPOL
  1088. { FUNC(eap) },
  1089. { STR_LENe(identity) },
  1090. { STR_LENe(anonymous_identity) },
  1091. { FUNC(password) },
  1092. { STRe(ca_cert) },
  1093. { STRe(ca_path) },
  1094. { STRe(client_cert) },
  1095. { STRe(private_key) },
  1096. { STR_KEYe(private_key_passwd) },
  1097. { STRe(dh_file) },
  1098. { STRe(subject_match) },
  1099. { STRe(altsubject_match) },
  1100. { STRe(ca_cert2) },
  1101. { STRe(ca_path2) },
  1102. { STRe(client_cert2) },
  1103. { STRe(private_key2) },
  1104. { STR_KEYe(private_key2_passwd) },
  1105. { STRe(dh_file2) },
  1106. { STRe(subject_match2) },
  1107. { STRe(altsubject_match2) },
  1108. { STRe(phase1) },
  1109. { STRe(phase2) },
  1110. { STRe(pcsc) },
  1111. { STR_KEYe(pin) },
  1112. { STRe(engine_id) },
  1113. { STRe(key_id) },
  1114. { STRe(cert_id) },
  1115. { STRe(ca_cert_id) },
  1116. { STRe(key2_id) },
  1117. { STRe(cert2_id) },
  1118. { STRe(ca_cert2_id) },
  1119. { INTe(engine) },
  1120. { INT(eapol_flags) },
  1121. #endif /* IEEE8021X_EAPOL */
  1122. { FUNC_KEY(wep_key0) },
  1123. { FUNC_KEY(wep_key1) },
  1124. { FUNC_KEY(wep_key2) },
  1125. { FUNC_KEY(wep_key3) },
  1126. { INT(wep_tx_keyidx) },
  1127. { INT(priority) },
  1128. #ifdef IEEE8021X_EAPOL
  1129. { INT(eap_workaround) },
  1130. { STRe(pac_file) },
  1131. { INTe(fragment_size) },
  1132. #endif /* IEEE8021X_EAPOL */
  1133. { INT_RANGE(mode, 0, 1) },
  1134. { INT_RANGE(proactive_key_caching, 0, 1) },
  1135. { INT_RANGE(disabled, 0, 1) },
  1136. { STR(id_str) },
  1137. #ifdef CONFIG_IEEE80211W
  1138. { INT_RANGE(ieee80211w, 0, 2) },
  1139. #endif /* CONFIG_IEEE80211W */
  1140. { INT_RANGE(peerkey, 0, 1) },
  1141. { INT_RANGE(mixed_cell, 0, 1) },
  1142. { INT_RANGE(frequency, 0, 10000) }
  1143. };
  1144. #undef OFFSET
  1145. #undef _STR
  1146. #undef STR
  1147. #undef STR_KEY
  1148. #undef _STR_LEN
  1149. #undef STR_LEN
  1150. #undef STR_LEN_KEY
  1151. #undef _STR_RANGE
  1152. #undef STR_RANGE
  1153. #undef STR_RANGE_KEY
  1154. #undef _INT
  1155. #undef INT
  1156. #undef INT_RANGE
  1157. #undef _FUNC
  1158. #undef FUNC
  1159. #undef FUNC_KEY
  1160. #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
  1161. /**
  1162. * wpa_config_add_prio_network - Add a network to priority lists
  1163. * @config: Configuration data from wpa_config_read()
  1164. * @ssid: Pointer to the network configuration to be added to the list
  1165. * Returns: 0 on success, -1 on failure
  1166. *
  1167. * This function is used to add a network block to the priority list of
  1168. * networks. This must be called for each network when reading in the full
  1169. * configuration. In addition, this can be used indirectly when updating
  1170. * priorities by calling wpa_config_update_prio_list().
  1171. */
  1172. int wpa_config_add_prio_network(struct wpa_config *config,
  1173. struct wpa_ssid *ssid)
  1174. {
  1175. int prio;
  1176. struct wpa_ssid *prev, **nlist;
  1177. /*
  1178. * Add to an existing priority list if one is available for the
  1179. * configured priority level for this network.
  1180. */
  1181. for (prio = 0; prio < config->num_prio; prio++) {
  1182. prev = config->pssid[prio];
  1183. if (prev->priority == ssid->priority) {
  1184. while (prev->pnext)
  1185. prev = prev->pnext;
  1186. prev->pnext = ssid;
  1187. return 0;
  1188. }
  1189. }
  1190. /* First network for this priority - add a new priority list */
  1191. nlist = os_realloc(config->pssid,
  1192. (config->num_prio + 1) * sizeof(struct wpa_ssid *));
  1193. if (nlist == NULL)
  1194. return -1;
  1195. for (prio = 0; prio < config->num_prio; prio++) {
  1196. if (nlist[prio]->priority < ssid->priority)
  1197. break;
  1198. }
  1199. os_memmove(&nlist[prio + 1], &nlist[prio],
  1200. (config->num_prio - prio) * sizeof(struct wpa_ssid *));
  1201. nlist[prio] = ssid;
  1202. config->num_prio++;
  1203. config->pssid = nlist;
  1204. return 0;
  1205. }
  1206. /**
  1207. * wpa_config_update_prio_list - Update network priority list
  1208. * @config: Configuration data from wpa_config_read()
  1209. * Returns: 0 on success, -1 on failure
  1210. *
  1211. * This function is called to update the priority list of networks in the
  1212. * configuration when a network is being added or removed. This is also called
  1213. * if a priority for a network is changed.
  1214. */
  1215. static int wpa_config_update_prio_list(struct wpa_config *config)
  1216. {
  1217. struct wpa_ssid *ssid;
  1218. int ret = 0;
  1219. os_free(config->pssid);
  1220. config->pssid = NULL;
  1221. config->num_prio = 0;
  1222. ssid = config->ssid;
  1223. while (ssid) {
  1224. ssid->pnext = NULL;
  1225. if (wpa_config_add_prio_network(config, ssid) < 0)
  1226. ret = -1;
  1227. ssid = ssid->next;
  1228. }
  1229. return ret;
  1230. }
  1231. #ifdef IEEE8021X_EAPOL
  1232. static void eap_peer_config_free(struct eap_peer_config *eap)
  1233. {
  1234. os_free(eap->eap_methods);
  1235. os_free(eap->identity);
  1236. os_free(eap->anonymous_identity);
  1237. os_free(eap->password);
  1238. os_free(eap->ca_cert);
  1239. os_free(eap->ca_path);
  1240. os_free(eap->client_cert);
  1241. os_free(eap->private_key);
  1242. os_free(eap->private_key_passwd);
  1243. os_free(eap->dh_file);
  1244. os_free(eap->subject_match);
  1245. os_free(eap->altsubject_match);
  1246. os_free(eap->ca_cert2);
  1247. os_free(eap->ca_path2);
  1248. os_free(eap->client_cert2);
  1249. os_free(eap->private_key2);
  1250. os_free(eap->private_key2_passwd);
  1251. os_free(eap->dh_file2);
  1252. os_free(eap->subject_match2);
  1253. os_free(eap->altsubject_match2);
  1254. os_free(eap->phase1);
  1255. os_free(eap->phase2);
  1256. os_free(eap->pcsc);
  1257. os_free(eap->pin);
  1258. os_free(eap->engine_id);
  1259. os_free(eap->key_id);
  1260. os_free(eap->cert_id);
  1261. os_free(eap->ca_cert_id);
  1262. os_free(eap->key2_id);
  1263. os_free(eap->cert2_id);
  1264. os_free(eap->ca_cert2_id);
  1265. os_free(eap->otp);
  1266. os_free(eap->pending_req_otp);
  1267. os_free(eap->pac_file);
  1268. os_free(eap->new_password);
  1269. }
  1270. #endif /* IEEE8021X_EAPOL */
  1271. /**
  1272. * wpa_config_free_ssid - Free network/ssid configuration data
  1273. * @ssid: Configuration data for the network
  1274. *
  1275. * This function frees all resources allocated for the network configuration
  1276. * data.
  1277. */
  1278. void wpa_config_free_ssid(struct wpa_ssid *ssid)
  1279. {
  1280. os_free(ssid->ssid);
  1281. os_free(ssid->passphrase);
  1282. #ifdef IEEE8021X_EAPOL
  1283. eap_peer_config_free(&ssid->eap);
  1284. #endif /* IEEE8021X_EAPOL */
  1285. os_free(ssid->id_str);
  1286. os_free(ssid);
  1287. }
  1288. /**
  1289. * wpa_config_free - Free configuration data
  1290. * @config: Configuration data from wpa_config_read()
  1291. *
  1292. * This function frees all resources allocated for the configuration data by
  1293. * wpa_config_read().
  1294. */
  1295. void wpa_config_free(struct wpa_config *config)
  1296. {
  1297. #ifndef CONFIG_NO_CONFIG_BLOBS
  1298. struct wpa_config_blob *blob, *prevblob;
  1299. #endif /* CONFIG_NO_CONFIG_BLOBS */
  1300. struct wpa_ssid *ssid, *prev = NULL;
  1301. ssid = config->ssid;
  1302. while (ssid) {
  1303. prev = ssid;
  1304. ssid = ssid->next;
  1305. wpa_config_free_ssid(prev);
  1306. }
  1307. #ifndef CONFIG_NO_CONFIG_BLOBS
  1308. blob = config->blobs;
  1309. prevblob = NULL;
  1310. while (blob) {
  1311. prevblob = blob;
  1312. blob = blob->next;
  1313. wpa_config_free_blob(prevblob);
  1314. }
  1315. #endif /* CONFIG_NO_CONFIG_BLOBS */
  1316. os_free(config->ctrl_interface);
  1317. os_free(config->ctrl_interface_group);
  1318. #ifdef EAP_TLS_OPENSSL
  1319. os_free(config->opensc_engine_path);
  1320. os_free(config->pkcs11_engine_path);
  1321. os_free(config->pkcs11_module_path);
  1322. #endif /* EAP_TLS_OPENSSL */
  1323. os_free(config->driver_param);
  1324. os_free(config->pssid);
  1325. os_free(config);
  1326. }
  1327. /**
  1328. * wpa_config_get_network - Get configured network based on id
  1329. * @config: Configuration data from wpa_config_read()
  1330. * @id: Unique network id to search for
  1331. * Returns: Network configuration or %NULL if not found
  1332. */
  1333. struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
  1334. {
  1335. struct wpa_ssid *ssid;
  1336. ssid = config->ssid;
  1337. while (ssid) {
  1338. if (id == ssid->id)
  1339. break;
  1340. ssid = ssid->next;
  1341. }
  1342. return ssid;
  1343. }
  1344. /**
  1345. * wpa_config_add_network - Add a new network with empty configuration
  1346. * @config: Configuration data from wpa_config_read()
  1347. * Returns: The new network configuration or %NULL if operation failed
  1348. */
  1349. struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
  1350. {
  1351. int id;
  1352. struct wpa_ssid *ssid, *last = NULL;
  1353. id = -1;
  1354. ssid = config->ssid;
  1355. while (ssid) {
  1356. if (ssid->id > id)
  1357. id = ssid->id;
  1358. last = ssid;
  1359. ssid = ssid->next;
  1360. }
  1361. id++;
  1362. ssid = os_zalloc(sizeof(*ssid));
  1363. if (ssid == NULL)
  1364. return NULL;
  1365. ssid->id = id;
  1366. if (last)
  1367. last->next = ssid;
  1368. else
  1369. config->ssid = ssid;
  1370. wpa_config_update_prio_list(config);
  1371. return ssid;
  1372. }
  1373. /**
  1374. * wpa_config_remove_network - Remove a configured network based on id
  1375. * @config: Configuration data from wpa_config_read()
  1376. * @id: Unique network id to search for
  1377. * Returns: 0 on success, or -1 if the network was not found
  1378. */
  1379. int wpa_config_remove_network(struct wpa_config *config, int id)
  1380. {
  1381. struct wpa_ssid *ssid, *prev = NULL;
  1382. ssid = config->ssid;
  1383. while (ssid) {
  1384. if (id == ssid->id)
  1385. break;
  1386. prev = ssid;
  1387. ssid = ssid->next;
  1388. }
  1389. if (ssid == NULL)
  1390. return -1;
  1391. if (prev)
  1392. prev->next = ssid->next;
  1393. else
  1394. config->ssid = ssid->next;
  1395. wpa_config_update_prio_list(config);
  1396. wpa_config_free_ssid(ssid);
  1397. return 0;
  1398. }
  1399. /**
  1400. * wpa_config_set_network_defaults - Set network default values
  1401. * @ssid: Pointer to network configuration data
  1402. */
  1403. void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
  1404. {
  1405. ssid->proto = DEFAULT_PROTO;
  1406. ssid->pairwise_cipher = DEFAULT_PAIRWISE;
  1407. ssid->group_cipher = DEFAULT_GROUP;
  1408. ssid->key_mgmt = DEFAULT_KEY_MGMT;
  1409. #ifdef IEEE8021X_EAPOL
  1410. ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
  1411. ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
  1412. ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
  1413. #endif /* IEEE8021X_EAPOL */
  1414. }
  1415. /**
  1416. * wpa_config_set - Set a variable in network configuration
  1417. * @ssid: Pointer to network configuration data
  1418. * @var: Variable name, e.g., "ssid"
  1419. * @value: Variable value
  1420. * @line: Line number in configuration file or 0 if not used
  1421. * Returns: 0 on success, -1 on failure
  1422. *
  1423. * This function can be used to set network configuration variables based on
  1424. * both the configuration file and management interface input. The value
  1425. * parameter must be in the same format as the text-based configuration file is
  1426. * using. For example, strings are using double quotation marks.
  1427. */
  1428. int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
  1429. int line)
  1430. {
  1431. size_t i;
  1432. int ret = 0;
  1433. if (ssid == NULL || var == NULL || value == NULL)
  1434. return -1;
  1435. for (i = 0; i < NUM_SSID_FIELDS; i++) {
  1436. const struct parse_data *field = &ssid_fields[i];
  1437. if (os_strcmp(var, field->name) != 0)
  1438. continue;
  1439. if (field->parser(field, ssid, line, value)) {
  1440. if (line) {
  1441. wpa_printf(MSG_ERROR, "Line %d: failed to "
  1442. "parse %s '%s'.", line, var, value);
  1443. }
  1444. ret = -1;
  1445. }
  1446. break;
  1447. }
  1448. if (i == NUM_SSID_FIELDS) {
  1449. if (line) {
  1450. wpa_printf(MSG_ERROR, "Line %d: unknown network field "
  1451. "'%s'.", line, var);
  1452. }
  1453. ret = -1;
  1454. }
  1455. return ret;
  1456. }
  1457. #ifndef NO_CONFIG_WRITE
  1458. /**
  1459. * wpa_config_get - Get a variable in network configuration
  1460. * @ssid: Pointer to network configuration data
  1461. * @var: Variable name, e.g., "ssid"
  1462. * Returns: Value of the variable or %NULL on failure
  1463. *
  1464. * This function can be used to get network configuration variables. The
  1465. * returned value is a copy of the configuration variable in text format, i.e,.
  1466. * the same format that the text-based configuration file and wpa_config_set()
  1467. * are using for the value. The caller is responsible for freeing the returned
  1468. * value.
  1469. */
  1470. char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
  1471. {
  1472. size_t i;
  1473. if (ssid == NULL || var == NULL)
  1474. return NULL;
  1475. for (i = 0; i < NUM_SSID_FIELDS; i++) {
  1476. const struct parse_data *field = &ssid_fields[i];
  1477. if (os_strcmp(var, field->name) == 0)
  1478. return field->writer(field, ssid);
  1479. }
  1480. return NULL;
  1481. }
  1482. /**
  1483. * wpa_config_get_no_key - Get a variable in network configuration (no keys)
  1484. * @ssid: Pointer to network configuration data
  1485. * @var: Variable name, e.g., "ssid"
  1486. * Returns: Value of the variable or %NULL on failure
  1487. *
  1488. * This function can be used to get network configuration variable like
  1489. * wpa_config_get(). The only difference is that this functions does not expose
  1490. * key/password material from the configuration. In case a key/password field
  1491. * is requested, the returned value is an empty string or %NULL if the variable
  1492. * is not set or "*" if the variable is set (regardless of its value). The
  1493. * returned value is a copy of the configuration variable in text format, i.e,.
  1494. * the same format that the text-based configuration file and wpa_config_set()
  1495. * are using for the value. The caller is responsible for freeing the returned
  1496. * value.
  1497. */
  1498. char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
  1499. {
  1500. size_t i;
  1501. if (ssid == NULL || var == NULL)
  1502. return NULL;
  1503. for (i = 0; i < NUM_SSID_FIELDS; i++) {
  1504. const struct parse_data *field = &ssid_fields[i];
  1505. if (os_strcmp(var, field->name) == 0) {
  1506. char *res = field->writer(field, ssid);
  1507. if (field->key_data) {
  1508. if (res && res[0]) {
  1509. wpa_printf(MSG_DEBUG, "Do not allow "
  1510. "key_data field to be "
  1511. "exposed");
  1512. os_free(res);
  1513. return os_strdup("*");
  1514. }
  1515. os_free(res);
  1516. return NULL;
  1517. }
  1518. return res;
  1519. }
  1520. }
  1521. return NULL;
  1522. }
  1523. #endif /* NO_CONFIG_WRITE */
  1524. /**
  1525. * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
  1526. * @ssid: Pointer to network configuration data
  1527. *
  1528. * This function must be called to update WPA PSK when either SSID or the
  1529. * passphrase has changed for the network configuration.
  1530. */
  1531. void wpa_config_update_psk(struct wpa_ssid *ssid)
  1532. {
  1533. #ifndef CONFIG_NO_PBKDF2
  1534. pbkdf2_sha1(ssid->passphrase,
  1535. (char *) ssid->ssid, ssid->ssid_len, 4096,
  1536. ssid->psk, PMK_LEN);
  1537. wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
  1538. ssid->psk, PMK_LEN);
  1539. ssid->psk_set = 1;
  1540. #endif /* CONFIG_NO_PBKDF2 */
  1541. }
  1542. #ifndef CONFIG_NO_CONFIG_BLOBS
  1543. /**
  1544. * wpa_config_get_blob - Get a named configuration blob
  1545. * @config: Configuration data from wpa_config_read()
  1546. * @name: Name of the blob
  1547. * Returns: Pointer to blob data or %NULL if not found
  1548. */
  1549. const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
  1550. const char *name)
  1551. {
  1552. struct wpa_config_blob *blob = config->blobs;
  1553. while (blob) {
  1554. if (os_strcmp(blob->name, name) == 0)
  1555. return blob;
  1556. blob = blob->next;
  1557. }
  1558. return NULL;
  1559. }
  1560. /**
  1561. * wpa_config_set_blob - Set or add a named configuration blob
  1562. * @config: Configuration data from wpa_config_read()
  1563. * @blob: New value for the blob
  1564. *
  1565. * Adds a new configuration blob or replaces the current value of an existing
  1566. * blob.
  1567. */
  1568. void wpa_config_set_blob(struct wpa_config *config,
  1569. struct wpa_config_blob *blob)
  1570. {
  1571. wpa_config_remove_blob(config, blob->name);
  1572. blob->next = config->blobs;
  1573. config->blobs = blob;
  1574. }
  1575. /**
  1576. * wpa_config_free_blob - Free blob data
  1577. * @blob: Pointer to blob to be freed
  1578. */
  1579. void wpa_config_free_blob(struct wpa_config_blob *blob)
  1580. {
  1581. if (blob) {
  1582. os_free(blob->name);
  1583. os_free(blob->data);
  1584. os_free(blob);
  1585. }
  1586. }
  1587. /**
  1588. * wpa_config_remove_blob - Remove a named configuration blob
  1589. * @config: Configuration data from wpa_config_read()
  1590. * @name: Name of the blob to remove
  1591. * Returns: 0 if blob was removed or -1 if blob was not found
  1592. */
  1593. int wpa_config_remove_blob(struct wpa_config *config, const char *name)
  1594. {
  1595. struct wpa_config_blob *pos = config->blobs, *prev = NULL;
  1596. while (pos) {
  1597. if (os_strcmp(pos->name, name) == 0) {
  1598. if (prev)
  1599. prev->next = pos->next;
  1600. else
  1601. config->blobs = pos->next;
  1602. wpa_config_free_blob(pos);
  1603. return 0;
  1604. }
  1605. prev = pos;
  1606. pos = pos->next;
  1607. }
  1608. return -1;
  1609. }
  1610. #endif /* CONFIG_NO_CONFIG_BLOBS */
  1611. /**
  1612. * wpa_config_alloc_empty - Allocate an empty configuration
  1613. * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
  1614. * socket
  1615. * @driver_param: Driver parameters
  1616. * Returns: Pointer to allocated configuration data or %NULL on failure
  1617. */
  1618. struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
  1619. const char *driver_param)
  1620. {
  1621. struct wpa_config *config;
  1622. config = os_zalloc(sizeof(*config));
  1623. if (config == NULL)
  1624. return NULL;
  1625. config->eapol_version = DEFAULT_EAPOL_VERSION;
  1626. config->ap_scan = DEFAULT_AP_SCAN;
  1627. config->fast_reauth = DEFAULT_FAST_REAUTH;
  1628. if (ctrl_interface)
  1629. config->ctrl_interface = os_strdup(ctrl_interface);
  1630. if (driver_param)
  1631. config->driver_param = os_strdup(driver_param);
  1632. return config;
  1633. }
  1634. #ifndef CONFIG_NO_STDOUT_DEBUG
  1635. /**
  1636. * wpa_config_debug_dump_networks - Debug dump of configured networks
  1637. * @config: Configuration data from wpa_config_read()
  1638. */
  1639. void wpa_config_debug_dump_networks(struct wpa_config *config)
  1640. {
  1641. int prio;
  1642. struct wpa_ssid *ssid;
  1643. for (prio = 0; prio < config->num_prio; prio++) {
  1644. ssid = config->pssid[prio];
  1645. wpa_printf(MSG_DEBUG, "Priority group %d",
  1646. ssid->priority);
  1647. while (ssid) {
  1648. wpa_printf(MSG_DEBUG, " id=%d ssid='%s'",
  1649. ssid->id,
  1650. wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
  1651. ssid = ssid->pnext;
  1652. }
  1653. }
  1654. }
  1655. #endif /* CONFIG_NO_STDOUT_DEBUG */