config.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289
  1. /*
  2. * hostapd / Configuration file
  3. * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2007-2008, Intel Corporation
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Alternatively, this software may be distributed under the terms of BSD
  11. * license.
  12. *
  13. * See README and COPYING for more details.
  14. */
  15. #include "includes.h"
  16. #ifndef CONFIG_NATIVE_WINDOWS
  17. #include <grp.h>
  18. #endif /* CONFIG_NATIVE_WINDOWS */
  19. #include "hostapd.h"
  20. #include "driver.h"
  21. #include "sha1.h"
  22. #include "eap_server/eap.h"
  23. #include "radius/radius_client.h"
  24. #include "wpa_common.h"
  25. #include "wpa.h"
  26. #include "uuid.h"
  27. #define MAX_STA_COUNT 2007
  28. extern struct wpa_driver_ops *hostapd_drivers[];
  29. static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
  30. const char *fname)
  31. {
  32. FILE *f;
  33. char buf[128], *pos, *pos2;
  34. int line = 0, vlan_id;
  35. struct hostapd_vlan *vlan;
  36. f = fopen(fname, "r");
  37. if (!f) {
  38. printf("VLAN file '%s' not readable.\n", fname);
  39. return -1;
  40. }
  41. while (fgets(buf, sizeof(buf), f)) {
  42. line++;
  43. if (buf[0] == '#')
  44. continue;
  45. pos = buf;
  46. while (*pos != '\0') {
  47. if (*pos == '\n') {
  48. *pos = '\0';
  49. break;
  50. }
  51. pos++;
  52. }
  53. if (buf[0] == '\0')
  54. continue;
  55. if (buf[0] == '*') {
  56. vlan_id = VLAN_ID_WILDCARD;
  57. pos = buf + 1;
  58. } else {
  59. vlan_id = strtol(buf, &pos, 10);
  60. if (buf == pos || vlan_id < 1 ||
  61. vlan_id > MAX_VLAN_ID) {
  62. printf("Invalid VLAN ID at line %d in '%s'\n",
  63. line, fname);
  64. fclose(f);
  65. return -1;
  66. }
  67. }
  68. while (*pos == ' ' || *pos == '\t')
  69. pos++;
  70. pos2 = pos;
  71. while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
  72. pos2++;
  73. *pos2 = '\0';
  74. if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
  75. printf("Invalid VLAN ifname at line %d in '%s'\n",
  76. line, fname);
  77. fclose(f);
  78. return -1;
  79. }
  80. vlan = os_malloc(sizeof(*vlan));
  81. if (vlan == NULL) {
  82. printf("Out of memory while reading VLAN interfaces "
  83. "from '%s'\n", fname);
  84. fclose(f);
  85. return -1;
  86. }
  87. os_memset(vlan, 0, sizeof(*vlan));
  88. vlan->vlan_id = vlan_id;
  89. os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
  90. if (bss->vlan_tail)
  91. bss->vlan_tail->next = vlan;
  92. else
  93. bss->vlan = vlan;
  94. bss->vlan_tail = vlan;
  95. }
  96. fclose(f);
  97. return 0;
  98. }
  99. static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
  100. {
  101. struct hostapd_vlan *vlan, *prev;
  102. vlan = bss->vlan;
  103. prev = NULL;
  104. while (vlan) {
  105. prev = vlan;
  106. vlan = vlan->next;
  107. os_free(prev);
  108. }
  109. bss->vlan = NULL;
  110. }
  111. /* convert floats with one decimal place to value*10 int, i.e.,
  112. * "1.5" will return 15 */
  113. static int hostapd_config_read_int10(const char *value)
  114. {
  115. int i, d;
  116. char *pos;
  117. i = atoi(value);
  118. pos = os_strchr(value, '.');
  119. d = 0;
  120. if (pos) {
  121. pos++;
  122. if (*pos >= '0' && *pos <= '9')
  123. d = *pos - '0';
  124. }
  125. return i * 10 + d;
  126. }
  127. static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
  128. {
  129. bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
  130. bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
  131. bss->logger_syslog = (unsigned int) -1;
  132. bss->logger_stdout = (unsigned int) -1;
  133. bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
  134. bss->wep_rekeying_period = 300;
  135. /* use key0 in individual key and key1 in broadcast key */
  136. bss->broadcast_key_idx_min = 1;
  137. bss->broadcast_key_idx_max = 2;
  138. bss->eap_reauth_period = 3600;
  139. bss->wpa_group_rekey = 600;
  140. bss->wpa_gmk_rekey = 86400;
  141. bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
  142. bss->wpa_pairwise = WPA_CIPHER_TKIP;
  143. bss->wpa_group = WPA_CIPHER_TKIP;
  144. bss->rsn_pairwise = 0;
  145. bss->max_num_sta = MAX_STA_COUNT;
  146. bss->dtim_period = 2;
  147. bss->radius_server_auth_port = 1812;
  148. bss->ap_max_inactivity = AP_MAX_INACTIVITY;
  149. bss->eapol_version = EAPOL_VERSION;
  150. bss->max_listen_interval = 65535;
  151. }
  152. static struct hostapd_config * hostapd_config_defaults(void)
  153. {
  154. struct hostapd_config *conf;
  155. struct hostapd_bss_config *bss;
  156. int i;
  157. const int aCWmin = 15, aCWmax = 1024;
  158. const struct hostapd_wme_ac_params ac_bk =
  159. { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
  160. const struct hostapd_wme_ac_params ac_be =
  161. { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
  162. const struct hostapd_wme_ac_params ac_vi = /* video traffic */
  163. { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
  164. const struct hostapd_wme_ac_params ac_vo = /* voice traffic */
  165. { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
  166. conf = os_zalloc(sizeof(*conf));
  167. bss = os_zalloc(sizeof(*bss));
  168. if (conf == NULL || bss == NULL) {
  169. printf("Failed to allocate memory for configuration data.\n");
  170. os_free(conf);
  171. os_free(bss);
  172. return NULL;
  173. }
  174. /* set default driver based on configuration */
  175. conf->driver = hostapd_drivers[0];
  176. if (conf->driver == NULL) {
  177. printf("No driver wrappers registered!\n");
  178. os_free(conf);
  179. os_free(bss);
  180. return NULL;
  181. }
  182. bss->radius = os_zalloc(sizeof(*bss->radius));
  183. if (bss->radius == NULL) {
  184. os_free(conf);
  185. os_free(bss);
  186. return NULL;
  187. }
  188. hostapd_config_defaults_bss(bss);
  189. conf->num_bss = 1;
  190. conf->bss = bss;
  191. conf->beacon_int = 100;
  192. conf->rts_threshold = -1; /* use driver default: 2347 */
  193. conf->fragm_threshold = -1; /* user driver default: 2346 */
  194. conf->send_probe_response = 1;
  195. conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL;
  196. os_memcpy(conf->country, "US ", 3);
  197. for (i = 0; i < NUM_TX_QUEUES; i++)
  198. conf->tx_queue[i].aifs = -1; /* use hw default */
  199. conf->wme_ac_params[0] = ac_be;
  200. conf->wme_ac_params[1] = ac_bk;
  201. conf->wme_ac_params[2] = ac_vi;
  202. conf->wme_ac_params[3] = ac_vo;
  203. #ifdef CONFIG_IEEE80211N
  204. SET_2BIT_LE16(&conf->ht_capab,
  205. HT_CAP_INFO_MIMO_PWR_SAVE_OFFSET,
  206. MIMO_PWR_NO_LIMIT_ON_MIMO_SEQS);
  207. conf->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
  208. #endif /* CONFIG_IEEE80211N */
  209. return conf;
  210. }
  211. int hostapd_mac_comp(const void *a, const void *b)
  212. {
  213. return os_memcmp(a, b, sizeof(macaddr));
  214. }
  215. int hostapd_mac_comp_empty(const void *a)
  216. {
  217. macaddr empty = { 0 };
  218. return os_memcmp(a, empty, sizeof(macaddr));
  219. }
  220. static int hostapd_acl_comp(const void *a, const void *b)
  221. {
  222. const struct mac_acl_entry *aa = a;
  223. const struct mac_acl_entry *bb = b;
  224. return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
  225. }
  226. static int hostapd_config_read_maclist(const char *fname,
  227. struct mac_acl_entry **acl, int *num)
  228. {
  229. FILE *f;
  230. char buf[128], *pos;
  231. int line = 0;
  232. u8 addr[ETH_ALEN];
  233. struct mac_acl_entry *newacl;
  234. int vlan_id;
  235. if (!fname)
  236. return 0;
  237. f = fopen(fname, "r");
  238. if (!f) {
  239. printf("MAC list file '%s' not found.\n", fname);
  240. return -1;
  241. }
  242. while (fgets(buf, sizeof(buf), f)) {
  243. line++;
  244. if (buf[0] == '#')
  245. continue;
  246. pos = buf;
  247. while (*pos != '\0') {
  248. if (*pos == '\n') {
  249. *pos = '\0';
  250. break;
  251. }
  252. pos++;
  253. }
  254. if (buf[0] == '\0')
  255. continue;
  256. if (hwaddr_aton(buf, addr)) {
  257. printf("Invalid MAC address '%s' at line %d in '%s'\n",
  258. buf, line, fname);
  259. fclose(f);
  260. return -1;
  261. }
  262. vlan_id = 0;
  263. pos = buf;
  264. while (*pos != '\0' && *pos != ' ' && *pos != '\t')
  265. pos++;
  266. while (*pos == ' ' || *pos == '\t')
  267. pos++;
  268. if (*pos != '\0')
  269. vlan_id = atoi(pos);
  270. newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl));
  271. if (newacl == NULL) {
  272. printf("MAC list reallocation failed\n");
  273. fclose(f);
  274. return -1;
  275. }
  276. *acl = newacl;
  277. os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
  278. (*acl)[*num].vlan_id = vlan_id;
  279. (*num)++;
  280. }
  281. fclose(f);
  282. qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
  283. return 0;
  284. }
  285. static int hostapd_config_read_wpa_psk(const char *fname,
  286. struct hostapd_ssid *ssid)
  287. {
  288. FILE *f;
  289. char buf[128], *pos;
  290. int line = 0, ret = 0, len, ok;
  291. u8 addr[ETH_ALEN];
  292. struct hostapd_wpa_psk *psk;
  293. if (!fname)
  294. return 0;
  295. f = fopen(fname, "r");
  296. if (!f) {
  297. printf("WPA PSK file '%s' not found.\n", fname);
  298. return -1;
  299. }
  300. while (fgets(buf, sizeof(buf), f)) {
  301. line++;
  302. if (buf[0] == '#')
  303. continue;
  304. pos = buf;
  305. while (*pos != '\0') {
  306. if (*pos == '\n') {
  307. *pos = '\0';
  308. break;
  309. }
  310. pos++;
  311. }
  312. if (buf[0] == '\0')
  313. continue;
  314. if (hwaddr_aton(buf, addr)) {
  315. printf("Invalid MAC address '%s' on line %d in '%s'\n",
  316. buf, line, fname);
  317. ret = -1;
  318. break;
  319. }
  320. psk = os_zalloc(sizeof(*psk));
  321. if (psk == NULL) {
  322. printf("WPA PSK allocation failed\n");
  323. ret = -1;
  324. break;
  325. }
  326. if (is_zero_ether_addr(addr))
  327. psk->group = 1;
  328. else
  329. os_memcpy(psk->addr, addr, ETH_ALEN);
  330. pos = buf + 17;
  331. if (pos == '\0') {
  332. printf("No PSK on line %d in '%s'\n", line, fname);
  333. os_free(psk);
  334. ret = -1;
  335. break;
  336. }
  337. pos++;
  338. ok = 0;
  339. len = os_strlen(pos);
  340. if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
  341. ok = 1;
  342. else if (len >= 8 && len < 64) {
  343. pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
  344. 4096, psk->psk, PMK_LEN);
  345. ok = 1;
  346. }
  347. if (!ok) {
  348. printf("Invalid PSK '%s' on line %d in '%s'\n",
  349. pos, line, fname);
  350. os_free(psk);
  351. ret = -1;
  352. break;
  353. }
  354. psk->next = ssid->wpa_psk;
  355. ssid->wpa_psk = psk;
  356. }
  357. fclose(f);
  358. return ret;
  359. }
  360. int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
  361. {
  362. struct hostapd_ssid *ssid = &conf->ssid;
  363. if (ssid->wpa_passphrase != NULL) {
  364. if (ssid->wpa_psk != NULL) {
  365. printf("Warning: both WPA PSK and passphrase set. "
  366. "Using passphrase.\n");
  367. os_free(ssid->wpa_psk);
  368. }
  369. ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
  370. if (ssid->wpa_psk == NULL) {
  371. printf("Unable to alloc space for PSK\n");
  372. return -1;
  373. }
  374. wpa_hexdump_ascii(MSG_DEBUG, "SSID",
  375. (u8 *) ssid->ssid, ssid->ssid_len);
  376. wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
  377. (u8 *) ssid->wpa_passphrase,
  378. os_strlen(ssid->wpa_passphrase));
  379. pbkdf2_sha1(ssid->wpa_passphrase,
  380. ssid->ssid, ssid->ssid_len,
  381. 4096, ssid->wpa_psk->psk, PMK_LEN);
  382. wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
  383. ssid->wpa_psk->psk, PMK_LEN);
  384. ssid->wpa_psk->group = 1;
  385. os_memset(ssid->wpa_passphrase, 0,
  386. os_strlen(ssid->wpa_passphrase));
  387. os_free(ssid->wpa_passphrase);
  388. ssid->wpa_passphrase = NULL;
  389. }
  390. if (ssid->wpa_psk_file) {
  391. if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
  392. &conf->ssid))
  393. return -1;
  394. }
  395. return 0;
  396. }
  397. #ifdef EAP_SERVER
  398. static int hostapd_config_read_eap_user(const char *fname,
  399. struct hostapd_bss_config *conf)
  400. {
  401. FILE *f;
  402. char buf[512], *pos, *start, *pos2;
  403. int line = 0, ret = 0, num_methods;
  404. struct hostapd_eap_user *user, *tail = NULL;
  405. if (!fname)
  406. return 0;
  407. f = fopen(fname, "r");
  408. if (!f) {
  409. printf("EAP user file '%s' not found.\n", fname);
  410. return -1;
  411. }
  412. /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
  413. while (fgets(buf, sizeof(buf), f)) {
  414. line++;
  415. if (buf[0] == '#')
  416. continue;
  417. pos = buf;
  418. while (*pos != '\0') {
  419. if (*pos == '\n') {
  420. *pos = '\0';
  421. break;
  422. }
  423. pos++;
  424. }
  425. if (buf[0] == '\0')
  426. continue;
  427. user = NULL;
  428. if (buf[0] != '"' && buf[0] != '*') {
  429. printf("Invalid EAP identity (no \" in start) on "
  430. "line %d in '%s'\n", line, fname);
  431. goto failed;
  432. }
  433. user = os_zalloc(sizeof(*user));
  434. if (user == NULL) {
  435. printf("EAP user allocation failed\n");
  436. goto failed;
  437. }
  438. user->force_version = -1;
  439. if (buf[0] == '*') {
  440. pos = buf;
  441. } else {
  442. pos = buf + 1;
  443. start = pos;
  444. while (*pos != '"' && *pos != '\0')
  445. pos++;
  446. if (*pos == '\0') {
  447. printf("Invalid EAP identity (no \" in end) on"
  448. " line %d in '%s'\n", line, fname);
  449. goto failed;
  450. }
  451. user->identity = os_malloc(pos - start);
  452. if (user->identity == NULL) {
  453. printf("Failed to allocate memory for EAP "
  454. "identity\n");
  455. goto failed;
  456. }
  457. os_memcpy(user->identity, start, pos - start);
  458. user->identity_len = pos - start;
  459. if (pos[0] == '"' && pos[1] == '*') {
  460. user->wildcard_prefix = 1;
  461. pos++;
  462. }
  463. }
  464. pos++;
  465. while (*pos == ' ' || *pos == '\t')
  466. pos++;
  467. if (*pos == '\0') {
  468. printf("No EAP method on line %d in '%s'\n",
  469. line, fname);
  470. goto failed;
  471. }
  472. start = pos;
  473. while (*pos != ' ' && *pos != '\t' && *pos != '\0')
  474. pos++;
  475. if (*pos == '\0') {
  476. pos = NULL;
  477. } else {
  478. *pos = '\0';
  479. pos++;
  480. }
  481. num_methods = 0;
  482. while (*start) {
  483. char *pos3 = os_strchr(start, ',');
  484. if (pos3) {
  485. *pos3++ = '\0';
  486. }
  487. user->methods[num_methods].method =
  488. eap_server_get_type(
  489. start,
  490. &user->methods[num_methods].vendor);
  491. if (user->methods[num_methods].vendor ==
  492. EAP_VENDOR_IETF &&
  493. user->methods[num_methods].method == EAP_TYPE_NONE)
  494. {
  495. if (os_strcmp(start, "TTLS-PAP") == 0) {
  496. user->ttls_auth |= EAP_TTLS_AUTH_PAP;
  497. goto skip_eap;
  498. }
  499. if (os_strcmp(start, "TTLS-CHAP") == 0) {
  500. user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
  501. goto skip_eap;
  502. }
  503. if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
  504. user->ttls_auth |=
  505. EAP_TTLS_AUTH_MSCHAP;
  506. goto skip_eap;
  507. }
  508. if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
  509. user->ttls_auth |=
  510. EAP_TTLS_AUTH_MSCHAPV2;
  511. goto skip_eap;
  512. }
  513. printf("Unsupported EAP type '%s' on line %d "
  514. "in '%s'\n", start, line, fname);
  515. goto failed;
  516. }
  517. num_methods++;
  518. if (num_methods >= EAP_USER_MAX_METHODS)
  519. break;
  520. skip_eap:
  521. if (pos3 == NULL)
  522. break;
  523. start = pos3;
  524. }
  525. if (num_methods == 0 && user->ttls_auth == 0) {
  526. printf("No EAP types configured on line %d in '%s'\n",
  527. line, fname);
  528. goto failed;
  529. }
  530. if (pos == NULL)
  531. goto done;
  532. while (*pos == ' ' || *pos == '\t')
  533. pos++;
  534. if (*pos == '\0')
  535. goto done;
  536. if (os_strncmp(pos, "[ver=0]", 7) == 0) {
  537. user->force_version = 0;
  538. goto done;
  539. }
  540. if (os_strncmp(pos, "[ver=1]", 7) == 0) {
  541. user->force_version = 1;
  542. goto done;
  543. }
  544. if (os_strncmp(pos, "[2]", 3) == 0) {
  545. user->phase2 = 1;
  546. goto done;
  547. }
  548. if (*pos == '"') {
  549. pos++;
  550. start = pos;
  551. while (*pos != '"' && *pos != '\0')
  552. pos++;
  553. if (*pos == '\0') {
  554. printf("Invalid EAP password (no \" in end) "
  555. "on line %d in '%s'\n", line, fname);
  556. goto failed;
  557. }
  558. user->password = os_malloc(pos - start);
  559. if (user->password == NULL) {
  560. printf("Failed to allocate memory for EAP "
  561. "password\n");
  562. goto failed;
  563. }
  564. os_memcpy(user->password, start, pos - start);
  565. user->password_len = pos - start;
  566. pos++;
  567. } else if (os_strncmp(pos, "hash:", 5) == 0) {
  568. pos += 5;
  569. pos2 = pos;
  570. while (*pos2 != '\0' && *pos2 != ' ' &&
  571. *pos2 != '\t' && *pos2 != '#')
  572. pos2++;
  573. if (pos2 - pos != 32) {
  574. printf("Invalid password hash on line %d in "
  575. "'%s'\n", line, fname);
  576. goto failed;
  577. }
  578. user->password = os_malloc(16);
  579. if (user->password == NULL) {
  580. printf("Failed to allocate memory for EAP "
  581. "password hash\n");
  582. goto failed;
  583. }
  584. if (hexstr2bin(pos, user->password, 16) < 0) {
  585. printf("Invalid hash password on line %d in "
  586. "'%s'\n", line, fname);
  587. goto failed;
  588. }
  589. user->password_len = 16;
  590. user->password_hash = 1;
  591. pos = pos2;
  592. } else {
  593. pos2 = pos;
  594. while (*pos2 != '\0' && *pos2 != ' ' &&
  595. *pos2 != '\t' && *pos2 != '#')
  596. pos2++;
  597. if ((pos2 - pos) & 1) {
  598. printf("Invalid hex password on line %d in "
  599. "'%s'\n", line, fname);
  600. goto failed;
  601. }
  602. user->password = os_malloc((pos2 - pos) / 2);
  603. if (user->password == NULL) {
  604. printf("Failed to allocate memory for EAP "
  605. "password\n");
  606. goto failed;
  607. }
  608. if (hexstr2bin(pos, user->password,
  609. (pos2 - pos) / 2) < 0) {
  610. printf("Invalid hex password on line %d in "
  611. "'%s'\n", line, fname);
  612. goto failed;
  613. }
  614. user->password_len = (pos2 - pos) / 2;
  615. pos = pos2;
  616. }
  617. while (*pos == ' ' || *pos == '\t')
  618. pos++;
  619. if (os_strncmp(pos, "[2]", 3) == 0) {
  620. user->phase2 = 1;
  621. }
  622. done:
  623. if (tail == NULL) {
  624. tail = conf->eap_user = user;
  625. } else {
  626. tail->next = user;
  627. tail = user;
  628. }
  629. continue;
  630. failed:
  631. if (user) {
  632. os_free(user->password);
  633. os_free(user->identity);
  634. os_free(user);
  635. }
  636. ret = -1;
  637. break;
  638. }
  639. fclose(f);
  640. return ret;
  641. }
  642. #endif /* EAP_SERVER */
  643. static int
  644. hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
  645. int *num_server, const char *val, int def_port,
  646. struct hostapd_radius_server **curr_serv)
  647. {
  648. struct hostapd_radius_server *nserv;
  649. int ret;
  650. static int server_index = 1;
  651. nserv = os_realloc(*server, (*num_server + 1) * sizeof(*nserv));
  652. if (nserv == NULL)
  653. return -1;
  654. *server = nserv;
  655. nserv = &nserv[*num_server];
  656. (*num_server)++;
  657. (*curr_serv) = nserv;
  658. os_memset(nserv, 0, sizeof(*nserv));
  659. nserv->port = def_port;
  660. ret = hostapd_parse_ip_addr(val, &nserv->addr);
  661. nserv->index = server_index++;
  662. return ret;
  663. }
  664. static int hostapd_config_parse_key_mgmt(int line, const char *value)
  665. {
  666. int val = 0, last;
  667. char *start, *end, *buf;
  668. buf = os_strdup(value);
  669. if (buf == NULL)
  670. return -1;
  671. start = buf;
  672. while (start != '\0') {
  673. while (*start == ' ' || *start == '\t')
  674. start++;
  675. if (*start == '\0')
  676. break;
  677. end = start;
  678. while (*end != ' ' && *end != '\t' && *end != '\0')
  679. end++;
  680. last = *end == '\0';
  681. *end = '\0';
  682. if (os_strcmp(start, "WPA-PSK") == 0)
  683. val |= WPA_KEY_MGMT_PSK;
  684. else if (os_strcmp(start, "WPA-EAP") == 0)
  685. val |= WPA_KEY_MGMT_IEEE8021X;
  686. #ifdef CONFIG_IEEE80211R
  687. else if (os_strcmp(start, "FT-PSK") == 0)
  688. val |= WPA_KEY_MGMT_FT_PSK;
  689. else if (os_strcmp(start, "FT-EAP") == 0)
  690. val |= WPA_KEY_MGMT_FT_IEEE8021X;
  691. #endif /* CONFIG_IEEE80211R */
  692. else {
  693. printf("Line %d: invalid key_mgmt '%s'\n",
  694. line, start);
  695. os_free(buf);
  696. return -1;
  697. }
  698. if (last)
  699. break;
  700. start = end + 1;
  701. }
  702. os_free(buf);
  703. if (val == 0) {
  704. printf("Line %d: no key_mgmt values configured.\n", line);
  705. return -1;
  706. }
  707. return val;
  708. }
  709. static int hostapd_config_parse_cipher(int line, const char *value)
  710. {
  711. int val = 0, last;
  712. char *start, *end, *buf;
  713. buf = os_strdup(value);
  714. if (buf == NULL)
  715. return -1;
  716. start = buf;
  717. while (start != '\0') {
  718. while (*start == ' ' || *start == '\t')
  719. start++;
  720. if (*start == '\0')
  721. break;
  722. end = start;
  723. while (*end != ' ' && *end != '\t' && *end != '\0')
  724. end++;
  725. last = *end == '\0';
  726. *end = '\0';
  727. if (os_strcmp(start, "CCMP") == 0)
  728. val |= WPA_CIPHER_CCMP;
  729. else if (os_strcmp(start, "TKIP") == 0)
  730. val |= WPA_CIPHER_TKIP;
  731. else if (os_strcmp(start, "WEP104") == 0)
  732. val |= WPA_CIPHER_WEP104;
  733. else if (os_strcmp(start, "WEP40") == 0)
  734. val |= WPA_CIPHER_WEP40;
  735. else if (os_strcmp(start, "NONE") == 0)
  736. val |= WPA_CIPHER_NONE;
  737. else {
  738. printf("Line %d: invalid cipher '%s'.", line, start);
  739. os_free(buf);
  740. return -1;
  741. }
  742. if (last)
  743. break;
  744. start = end + 1;
  745. }
  746. os_free(buf);
  747. if (val == 0) {
  748. printf("Line %d: no cipher values configured.", line);
  749. return -1;
  750. }
  751. return val;
  752. }
  753. static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
  754. struct hostapd_config *conf)
  755. {
  756. if (bss->ieee802_1x && !bss->eap_server &&
  757. !bss->radius->auth_servers) {
  758. printf("Invalid IEEE 802.1X configuration (no EAP "
  759. "authenticator configured).\n");
  760. return -1;
  761. }
  762. if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
  763. bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
  764. bss->ssid.wpa_psk_file == NULL) {
  765. printf("WPA-PSK enabled, but PSK or passphrase is not "
  766. "configured.\n");
  767. return -1;
  768. }
  769. if (hostapd_mac_comp_empty(bss->bssid) != 0) {
  770. size_t i;
  771. for (i = 0; i < conf->num_bss; i++) {
  772. if ((&conf->bss[i] != bss) &&
  773. (hostapd_mac_comp(conf->bss[i].bssid,
  774. bss->bssid) == 0)) {
  775. printf("Duplicate BSSID " MACSTR
  776. " on interface '%s' and '%s'.\n",
  777. MAC2STR(bss->bssid),
  778. conf->bss[i].iface, bss->iface);
  779. return -1;
  780. }
  781. }
  782. }
  783. #ifdef CONFIG_IEEE80211R
  784. if ((bss->wpa_key_mgmt &
  785. (WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X)) &&
  786. (bss->nas_identifier == NULL ||
  787. os_strlen(bss->nas_identifier) < 1 ||
  788. os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
  789. printf("FT (IEEE 802.11r) requires nas_identifier to be "
  790. "configured as a 1..48 octet string\n");
  791. return -1;
  792. }
  793. #endif /* CONFIG_IEEE80211R */
  794. return 0;
  795. }
  796. static int hostapd_config_check(struct hostapd_config *conf)
  797. {
  798. size_t i;
  799. for (i = 0; i < conf->num_bss; i++) {
  800. if (hostapd_config_check_bss(&conf->bss[i], conf))
  801. return -1;
  802. }
  803. return 0;
  804. }
  805. static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
  806. char *val)
  807. {
  808. size_t len = os_strlen(val);
  809. if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
  810. return -1;
  811. if (val[0] == '"') {
  812. if (len < 2 || val[len - 1] != '"')
  813. return -1;
  814. len -= 2;
  815. wep->key[keyidx] = os_malloc(len);
  816. if (wep->key[keyidx] == NULL)
  817. return -1;
  818. os_memcpy(wep->key[keyidx], val + 1, len);
  819. wep->len[keyidx] = len;
  820. } else {
  821. if (len & 1)
  822. return -1;
  823. len /= 2;
  824. wep->key[keyidx] = os_malloc(len);
  825. if (wep->key[keyidx] == NULL)
  826. return -1;
  827. wep->len[keyidx] = len;
  828. if (hexstr2bin(val, wep->key[keyidx], len) < 0)
  829. return -1;
  830. }
  831. wep->keys_set++;
  832. return 0;
  833. }
  834. static int hostapd_parse_rates(int **rate_list, char *val)
  835. {
  836. int *list;
  837. int count;
  838. char *pos, *end;
  839. os_free(*rate_list);
  840. *rate_list = NULL;
  841. pos = val;
  842. count = 0;
  843. while (*pos != '\0') {
  844. if (*pos == ' ')
  845. count++;
  846. pos++;
  847. }
  848. list = os_malloc(sizeof(int) * (count + 2));
  849. if (list == NULL)
  850. return -1;
  851. pos = val;
  852. count = 0;
  853. while (*pos != '\0') {
  854. end = os_strchr(pos, ' ');
  855. if (end)
  856. *end = '\0';
  857. list[count++] = atoi(pos);
  858. if (!end)
  859. break;
  860. pos = end + 1;
  861. }
  862. list[count] = -1;
  863. *rate_list = list;
  864. return 0;
  865. }
  866. static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
  867. {
  868. struct hostapd_bss_config *bss;
  869. if (*ifname == '\0')
  870. return -1;
  871. bss = os_realloc(conf->bss, (conf->num_bss + 1) *
  872. sizeof(struct hostapd_bss_config));
  873. if (bss == NULL) {
  874. printf("Failed to allocate memory for multi-BSS entry\n");
  875. return -1;
  876. }
  877. conf->bss = bss;
  878. bss = &(conf->bss[conf->num_bss]);
  879. os_memset(bss, 0, sizeof(*bss));
  880. bss->radius = os_zalloc(sizeof(*bss->radius));
  881. if (bss->radius == NULL) {
  882. printf("Failed to allocate memory for multi-BSS RADIUS "
  883. "data\n");
  884. return -1;
  885. }
  886. conf->num_bss++;
  887. conf->last_bss = bss;
  888. hostapd_config_defaults_bss(bss);
  889. os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
  890. os_memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
  891. return 0;
  892. }
  893. static int valid_cw(int cw)
  894. {
  895. return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
  896. cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
  897. }
  898. enum {
  899. IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
  900. IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
  901. IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
  902. IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */
  903. IEEE80211_TX_QUEUE_DATA4 = 4,
  904. IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
  905. IEEE80211_TX_QUEUE_BEACON = 7
  906. };
  907. static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
  908. char *val)
  909. {
  910. int num;
  911. char *pos;
  912. struct hostapd_tx_queue_params *queue;
  913. /* skip 'tx_queue_' prefix */
  914. pos = name + 9;
  915. if (os_strncmp(pos, "data", 4) == 0 &&
  916. pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
  917. num = pos[4] - '0';
  918. pos += 6;
  919. } else if (os_strncmp(pos, "after_beacon_", 13) == 0) {
  920. num = IEEE80211_TX_QUEUE_AFTER_BEACON;
  921. pos += 13;
  922. } else if (os_strncmp(pos, "beacon_", 7) == 0) {
  923. num = IEEE80211_TX_QUEUE_BEACON;
  924. pos += 7;
  925. } else {
  926. printf("Unknown tx_queue name '%s'\n", pos);
  927. return -1;
  928. }
  929. queue = &conf->tx_queue[num];
  930. if (os_strcmp(pos, "aifs") == 0) {
  931. queue->aifs = atoi(val);
  932. if (queue->aifs < 0 || queue->aifs > 255) {
  933. printf("Invalid AIFS value %d\n", queue->aifs);
  934. return -1;
  935. }
  936. } else if (os_strcmp(pos, "cwmin") == 0) {
  937. queue->cwmin = atoi(val);
  938. if (!valid_cw(queue->cwmin)) {
  939. printf("Invalid cwMin value %d\n", queue->cwmin);
  940. return -1;
  941. }
  942. } else if (os_strcmp(pos, "cwmax") == 0) {
  943. queue->cwmax = atoi(val);
  944. if (!valid_cw(queue->cwmax)) {
  945. printf("Invalid cwMax value %d\n", queue->cwmax);
  946. return -1;
  947. }
  948. } else if (os_strcmp(pos, "burst") == 0) {
  949. queue->burst = hostapd_config_read_int10(val);
  950. } else {
  951. printf("Unknown tx_queue field '%s'\n", pos);
  952. return -1;
  953. }
  954. queue->configured = 1;
  955. return 0;
  956. }
  957. static int hostapd_config_wme_ac(struct hostapd_config *conf, char *name,
  958. char *val)
  959. {
  960. int num, v;
  961. char *pos;
  962. struct hostapd_wme_ac_params *ac;
  963. /* skip 'wme_ac_' prefix */
  964. pos = name + 7;
  965. if (os_strncmp(pos, "be_", 3) == 0) {
  966. num = 0;
  967. pos += 3;
  968. } else if (os_strncmp(pos, "bk_", 3) == 0) {
  969. num = 1;
  970. pos += 3;
  971. } else if (os_strncmp(pos, "vi_", 3) == 0) {
  972. num = 2;
  973. pos += 3;
  974. } else if (os_strncmp(pos, "vo_", 3) == 0) {
  975. num = 3;
  976. pos += 3;
  977. } else {
  978. printf("Unknown wme name '%s'\n", pos);
  979. return -1;
  980. }
  981. ac = &conf->wme_ac_params[num];
  982. if (os_strcmp(pos, "aifs") == 0) {
  983. v = atoi(val);
  984. if (v < 1 || v > 255) {
  985. printf("Invalid AIFS value %d\n", v);
  986. return -1;
  987. }
  988. ac->aifs = v;
  989. } else if (os_strcmp(pos, "cwmin") == 0) {
  990. v = atoi(val);
  991. if (v < 0 || v > 12) {
  992. printf("Invalid cwMin value %d\n", v);
  993. return -1;
  994. }
  995. ac->cwmin = v;
  996. } else if (os_strcmp(pos, "cwmax") == 0) {
  997. v = atoi(val);
  998. if (v < 0 || v > 12) {
  999. printf("Invalid cwMax value %d\n", v);
  1000. return -1;
  1001. }
  1002. ac->cwmax = v;
  1003. } else if (os_strcmp(pos, "txop_limit") == 0) {
  1004. v = atoi(val);
  1005. if (v < 0 || v > 0xffff) {
  1006. printf("Invalid txop value %d\n", v);
  1007. return -1;
  1008. }
  1009. ac->txopLimit = v;
  1010. } else if (os_strcmp(pos, "acm") == 0) {
  1011. v = atoi(val);
  1012. if (v < 0 || v > 1) {
  1013. printf("Invalid acm value %d\n", v);
  1014. return -1;
  1015. }
  1016. ac->admission_control_mandatory = v;
  1017. } else {
  1018. printf("Unknown wme_ac_ field '%s'\n", pos);
  1019. return -1;
  1020. }
  1021. return 0;
  1022. }
  1023. #ifdef CONFIG_IEEE80211R
  1024. static int add_r0kh(struct hostapd_bss_config *bss, char *value)
  1025. {
  1026. struct ft_remote_r0kh *r0kh;
  1027. char *pos, *next;
  1028. r0kh = os_zalloc(sizeof(*r0kh));
  1029. if (r0kh == NULL)
  1030. return -1;
  1031. /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
  1032. pos = value;
  1033. next = os_strchr(pos, ' ');
  1034. if (next)
  1035. *next++ = '\0';
  1036. if (next == NULL || hwaddr_aton(pos, r0kh->addr)) {
  1037. printf("Invalid R0KH MAC address: '%s'\n", pos);
  1038. os_free(r0kh);
  1039. return -1;
  1040. }
  1041. pos = next;
  1042. next = os_strchr(pos, ' ');
  1043. if (next)
  1044. *next++ = '\0';
  1045. if (next == NULL || next - pos > FT_R0KH_ID_MAX_LEN) {
  1046. printf("Invalid R0KH-ID: '%s'\n", pos);
  1047. os_free(r0kh);
  1048. return -1;
  1049. }
  1050. r0kh->id_len = next - pos - 1;
  1051. os_memcpy(r0kh->id, pos, r0kh->id_len);
  1052. pos = next;
  1053. if (hexstr2bin(pos, r0kh->key, sizeof(r0kh->key))) {
  1054. printf("Invalid R0KH key: '%s'\n", pos);
  1055. os_free(r0kh);
  1056. return -1;
  1057. }
  1058. r0kh->next = bss->r0kh_list;
  1059. bss->r0kh_list = r0kh;
  1060. return 0;
  1061. }
  1062. static int add_r1kh(struct hostapd_bss_config *bss, char *value)
  1063. {
  1064. struct ft_remote_r1kh *r1kh;
  1065. char *pos, *next;
  1066. r1kh = os_zalloc(sizeof(*r1kh));
  1067. if (r1kh == NULL)
  1068. return -1;
  1069. /* 02:01:02:03:04:05 02:01:02:03:04:05
  1070. * 000102030405060708090a0b0c0d0e0f */
  1071. pos = value;
  1072. next = os_strchr(pos, ' ');
  1073. if (next)
  1074. *next++ = '\0';
  1075. if (next == NULL || hwaddr_aton(pos, r1kh->addr)) {
  1076. printf("Invalid R1KH MAC address: '%s'\n", pos);
  1077. os_free(r1kh);
  1078. return -1;
  1079. }
  1080. pos = next;
  1081. next = os_strchr(pos, ' ');
  1082. if (next)
  1083. *next++ = '\0';
  1084. if (next == NULL || hwaddr_aton(pos, r1kh->id)) {
  1085. printf("Invalid R1KH-ID: '%s'\n", pos);
  1086. os_free(r1kh);
  1087. return -1;
  1088. }
  1089. pos = next;
  1090. if (hexstr2bin(pos, r1kh->key, sizeof(r1kh->key))) {
  1091. printf("Invalid R1KH key: '%s'\n", pos);
  1092. os_free(r1kh);
  1093. return -1;
  1094. }
  1095. r1kh->next = bss->r1kh_list;
  1096. bss->r1kh_list = r1kh;
  1097. return 0;
  1098. }
  1099. #endif /* CONFIG_IEEE80211R */
  1100. struct hostapd_config * hostapd_config_read(const char *fname)
  1101. {
  1102. struct hostapd_config *conf;
  1103. struct hostapd_bss_config *bss;
  1104. FILE *f;
  1105. char buf[256], *pos;
  1106. int line = 0;
  1107. int errors = 0;
  1108. int pairwise;
  1109. size_t i;
  1110. f = fopen(fname, "r");
  1111. if (f == NULL) {
  1112. printf("Could not open configuration file '%s' for reading.\n",
  1113. fname);
  1114. return NULL;
  1115. }
  1116. conf = hostapd_config_defaults();
  1117. if (conf == NULL) {
  1118. fclose(f);
  1119. return NULL;
  1120. }
  1121. bss = conf->last_bss = conf->bss;
  1122. while (fgets(buf, sizeof(buf), f)) {
  1123. bss = conf->last_bss;
  1124. line++;
  1125. if (buf[0] == '#')
  1126. continue;
  1127. pos = buf;
  1128. while (*pos != '\0') {
  1129. if (*pos == '\n') {
  1130. *pos = '\0';
  1131. break;
  1132. }
  1133. pos++;
  1134. }
  1135. if (buf[0] == '\0')
  1136. continue;
  1137. pos = os_strchr(buf, '=');
  1138. if (pos == NULL) {
  1139. printf("Line %d: invalid line '%s'\n", line, buf);
  1140. errors++;
  1141. continue;
  1142. }
  1143. *pos = '\0';
  1144. pos++;
  1145. if (os_strcmp(buf, "interface") == 0) {
  1146. os_strlcpy(conf->bss[0].iface, pos,
  1147. sizeof(conf->bss[0].iface));
  1148. } else if (os_strcmp(buf, "bridge") == 0) {
  1149. os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
  1150. } else if (os_strcmp(buf, "driver") == 0) {
  1151. int i;
  1152. /* clear to get error below if setting is invalid */
  1153. conf->driver = NULL;
  1154. for (i = 0; hostapd_drivers[i]; i++) {
  1155. if (os_strcmp(pos, hostapd_drivers[i]->name) ==
  1156. 0) {
  1157. conf->driver = hostapd_drivers[i];
  1158. break;
  1159. }
  1160. }
  1161. if (conf->driver == NULL) {
  1162. printf("Line %d: invalid/unknown driver "
  1163. "'%s'\n", line, pos);
  1164. errors++;
  1165. }
  1166. } else if (os_strcmp(buf, "debug") == 0) {
  1167. wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' "
  1168. "configuration variable is not used "
  1169. "anymore", line);
  1170. } else if (os_strcmp(buf, "logger_syslog_level") == 0) {
  1171. bss->logger_syslog_level = atoi(pos);
  1172. } else if (os_strcmp(buf, "logger_stdout_level") == 0) {
  1173. bss->logger_stdout_level = atoi(pos);
  1174. } else if (os_strcmp(buf, "logger_syslog") == 0) {
  1175. bss->logger_syslog = atoi(pos);
  1176. } else if (os_strcmp(buf, "logger_stdout") == 0) {
  1177. bss->logger_stdout = atoi(pos);
  1178. } else if (os_strcmp(buf, "dump_file") == 0) {
  1179. bss->dump_log_name = os_strdup(pos);
  1180. } else if (os_strcmp(buf, "ssid") == 0) {
  1181. bss->ssid.ssid_len = os_strlen(pos);
  1182. if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
  1183. bss->ssid.ssid_len < 1) {
  1184. printf("Line %d: invalid SSID '%s'\n", line,
  1185. pos);
  1186. errors++;
  1187. } else {
  1188. os_memcpy(bss->ssid.ssid, pos,
  1189. bss->ssid.ssid_len);
  1190. bss->ssid.ssid[bss->ssid.ssid_len] = '\0';
  1191. bss->ssid.ssid_set = 1;
  1192. }
  1193. } else if (os_strcmp(buf, "macaddr_acl") == 0) {
  1194. bss->macaddr_acl = atoi(pos);
  1195. if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
  1196. bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
  1197. bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
  1198. printf("Line %d: unknown macaddr_acl %d\n",
  1199. line, bss->macaddr_acl);
  1200. }
  1201. } else if (os_strcmp(buf, "accept_mac_file") == 0) {
  1202. if (hostapd_config_read_maclist(pos, &bss->accept_mac,
  1203. &bss->num_accept_mac))
  1204. {
  1205. printf("Line %d: Failed to read "
  1206. "accept_mac_file '%s'\n",
  1207. line, pos);
  1208. errors++;
  1209. }
  1210. } else if (os_strcmp(buf, "deny_mac_file") == 0) {
  1211. if (hostapd_config_read_maclist(pos, &bss->deny_mac,
  1212. &bss->num_deny_mac))
  1213. {
  1214. printf("Line %d: Failed to read "
  1215. "deny_mac_file '%s'\n",
  1216. line, pos);
  1217. errors++;
  1218. }
  1219. } else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
  1220. bss->ap_max_inactivity = atoi(pos);
  1221. } else if (os_strcmp(buf, "country_code") == 0) {
  1222. os_memcpy(conf->country, pos, 2);
  1223. /* FIX: make this configurable */
  1224. conf->country[2] = ' ';
  1225. } else if (os_strcmp(buf, "ieee80211d") == 0) {
  1226. conf->ieee80211d = atoi(pos);
  1227. } else if (os_strcmp(buf, "ieee80211h") == 0) {
  1228. conf->ieee80211h = atoi(pos);
  1229. } else if (os_strcmp(buf, "assoc_ap_addr") == 0) {
  1230. if (hwaddr_aton(pos, bss->assoc_ap_addr)) {
  1231. printf("Line %d: invalid MAC address '%s'\n",
  1232. line, pos);
  1233. errors++;
  1234. }
  1235. bss->assoc_ap = 1;
  1236. } else if (os_strcmp(buf, "ieee8021x") == 0) {
  1237. bss->ieee802_1x = atoi(pos);
  1238. } else if (os_strcmp(buf, "eapol_version") == 0) {
  1239. bss->eapol_version = atoi(pos);
  1240. if (bss->eapol_version < 1 ||
  1241. bss->eapol_version > 2) {
  1242. printf("Line %d: invalid EAPOL "
  1243. "version (%d): '%s'.\n",
  1244. line, bss->eapol_version, pos);
  1245. errors++;
  1246. } else
  1247. wpa_printf(MSG_DEBUG, "eapol_version=%d",
  1248. bss->eapol_version);
  1249. #ifdef EAP_SERVER
  1250. } else if (os_strcmp(buf, "eap_authenticator") == 0) {
  1251. bss->eap_server = atoi(pos);
  1252. printf("Line %d: obsolete eap_authenticator used; "
  1253. "this has been renamed to eap_server\n", line);
  1254. } else if (os_strcmp(buf, "eap_server") == 0) {
  1255. bss->eap_server = atoi(pos);
  1256. } else if (os_strcmp(buf, "eap_user_file") == 0) {
  1257. if (hostapd_config_read_eap_user(pos, bss))
  1258. errors++;
  1259. } else if (os_strcmp(buf, "ca_cert") == 0) {
  1260. os_free(bss->ca_cert);
  1261. bss->ca_cert = os_strdup(pos);
  1262. } else if (os_strcmp(buf, "server_cert") == 0) {
  1263. os_free(bss->server_cert);
  1264. bss->server_cert = os_strdup(pos);
  1265. } else if (os_strcmp(buf, "private_key") == 0) {
  1266. os_free(bss->private_key);
  1267. bss->private_key = os_strdup(pos);
  1268. } else if (os_strcmp(buf, "private_key_passwd") == 0) {
  1269. os_free(bss->private_key_passwd);
  1270. bss->private_key_passwd = os_strdup(pos);
  1271. } else if (os_strcmp(buf, "check_crl") == 0) {
  1272. bss->check_crl = atoi(pos);
  1273. } else if (os_strcmp(buf, "dh_file") == 0) {
  1274. os_free(bss->dh_file);
  1275. bss->dh_file = os_strdup(pos);
  1276. #ifdef EAP_FAST
  1277. } else if (os_strcmp(buf, "pac_opaque_encr_key") == 0) {
  1278. os_free(bss->pac_opaque_encr_key);
  1279. bss->pac_opaque_encr_key = os_malloc(16);
  1280. if (bss->pac_opaque_encr_key == NULL) {
  1281. printf("Line %d: No memory for "
  1282. "pac_opque_encr_key\n", line);
  1283. errors++;
  1284. } else if (hexstr2bin(pos, bss->pac_opaque_encr_key,
  1285. 16)) {
  1286. printf("Line %d: Invalid pac_opque_encr_key\n",
  1287. line);
  1288. errors++;
  1289. }
  1290. } else if (os_strcmp(buf, "eap_fast_a_id") == 0) {
  1291. os_free(bss->eap_fast_a_id);
  1292. bss->eap_fast_a_id = os_strdup(pos);
  1293. #endif /* EAP_FAST */
  1294. #ifdef EAP_SIM
  1295. } else if (os_strcmp(buf, "eap_sim_db") == 0) {
  1296. os_free(bss->eap_sim_db);
  1297. bss->eap_sim_db = os_strdup(pos);
  1298. } else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
  1299. bss->eap_sim_aka_result_ind = atoi(pos);
  1300. #endif /* EAP_SIM */
  1301. #ifdef EAP_TNC
  1302. } else if (os_strcmp(buf, "tnc") == 0) {
  1303. bss->tnc = atoi(pos);
  1304. #endif /* EAP_TNC */
  1305. #endif /* EAP_SERVER */
  1306. } else if (os_strcmp(buf, "eap_message") == 0) {
  1307. char *term;
  1308. bss->eap_req_id_text = os_strdup(pos);
  1309. if (bss->eap_req_id_text == NULL) {
  1310. printf("Line %d: Failed to allocate memory "
  1311. "for eap_req_id_text\n", line);
  1312. errors++;
  1313. continue;
  1314. }
  1315. bss->eap_req_id_text_len =
  1316. os_strlen(bss->eap_req_id_text);
  1317. term = os_strstr(bss->eap_req_id_text, "\\0");
  1318. if (term) {
  1319. *term++ = '\0';
  1320. os_memmove(term, term + 1,
  1321. bss->eap_req_id_text_len -
  1322. (term - bss->eap_req_id_text) - 1);
  1323. bss->eap_req_id_text_len--;
  1324. }
  1325. } else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
  1326. bss->default_wep_key_len = atoi(pos);
  1327. if (bss->default_wep_key_len > 13) {
  1328. printf("Line %d: invalid WEP key len %lu "
  1329. "(= %lu bits)\n", line,
  1330. (unsigned long)
  1331. bss->default_wep_key_len,
  1332. (unsigned long)
  1333. bss->default_wep_key_len * 8);
  1334. errors++;
  1335. }
  1336. } else if (os_strcmp(buf, "wep_key_len_unicast") == 0) {
  1337. bss->individual_wep_key_len = atoi(pos);
  1338. if (bss->individual_wep_key_len < 0 ||
  1339. bss->individual_wep_key_len > 13) {
  1340. printf("Line %d: invalid WEP key len %d "
  1341. "(= %d bits)\n", line,
  1342. bss->individual_wep_key_len,
  1343. bss->individual_wep_key_len * 8);
  1344. errors++;
  1345. }
  1346. } else if (os_strcmp(buf, "wep_rekey_period") == 0) {
  1347. bss->wep_rekeying_period = atoi(pos);
  1348. if (bss->wep_rekeying_period < 0) {
  1349. printf("Line %d: invalid period %d\n",
  1350. line, bss->wep_rekeying_period);
  1351. errors++;
  1352. }
  1353. } else if (os_strcmp(buf, "eap_reauth_period") == 0) {
  1354. bss->eap_reauth_period = atoi(pos);
  1355. if (bss->eap_reauth_period < 0) {
  1356. printf("Line %d: invalid period %d\n",
  1357. line, bss->eap_reauth_period);
  1358. errors++;
  1359. }
  1360. } else if (os_strcmp(buf, "eapol_key_index_workaround") == 0) {
  1361. bss->eapol_key_index_workaround = atoi(pos);
  1362. #ifdef CONFIG_IAPP
  1363. } else if (os_strcmp(buf, "iapp_interface") == 0) {
  1364. bss->ieee802_11f = 1;
  1365. os_strlcpy(bss->iapp_iface, pos,
  1366. sizeof(bss->iapp_iface));
  1367. #endif /* CONFIG_IAPP */
  1368. } else if (os_strcmp(buf, "own_ip_addr") == 0) {
  1369. if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
  1370. printf("Line %d: invalid IP address '%s'\n",
  1371. line, pos);
  1372. errors++;
  1373. }
  1374. } else if (os_strcmp(buf, "nas_identifier") == 0) {
  1375. bss->nas_identifier = os_strdup(pos);
  1376. } else if (os_strcmp(buf, "auth_server_addr") == 0) {
  1377. if (hostapd_config_read_radius_addr(
  1378. &bss->radius->auth_servers,
  1379. &bss->radius->num_auth_servers, pos, 1812,
  1380. &bss->radius->auth_server)) {
  1381. printf("Line %d: invalid IP address '%s'\n",
  1382. line, pos);
  1383. errors++;
  1384. }
  1385. } else if (bss->radius->auth_server &&
  1386. os_strcmp(buf, "auth_server_port") == 0) {
  1387. bss->radius->auth_server->port = atoi(pos);
  1388. } else if (bss->radius->auth_server &&
  1389. os_strcmp(buf, "auth_server_shared_secret") == 0) {
  1390. int len = os_strlen(pos);
  1391. if (len == 0) {
  1392. /* RFC 2865, Ch. 3 */
  1393. printf("Line %d: empty shared secret is not "
  1394. "allowed.\n", line);
  1395. errors++;
  1396. }
  1397. bss->radius->auth_server->shared_secret =
  1398. (u8 *) os_strdup(pos);
  1399. bss->radius->auth_server->shared_secret_len = len;
  1400. } else if (os_strcmp(buf, "acct_server_addr") == 0) {
  1401. if (hostapd_config_read_radius_addr(
  1402. &bss->radius->acct_servers,
  1403. &bss->radius->num_acct_servers, pos, 1813,
  1404. &bss->radius->acct_server)) {
  1405. printf("Line %d: invalid IP address '%s'\n",
  1406. line, pos);
  1407. errors++;
  1408. }
  1409. } else if (bss->radius->acct_server &&
  1410. os_strcmp(buf, "acct_server_port") == 0) {
  1411. bss->radius->acct_server->port = atoi(pos);
  1412. } else if (bss->radius->acct_server &&
  1413. os_strcmp(buf, "acct_server_shared_secret") == 0) {
  1414. int len = os_strlen(pos);
  1415. if (len == 0) {
  1416. /* RFC 2865, Ch. 3 */
  1417. printf("Line %d: empty shared secret is not "
  1418. "allowed.\n", line);
  1419. errors++;
  1420. }
  1421. bss->radius->acct_server->shared_secret =
  1422. (u8 *) os_strdup(pos);
  1423. bss->radius->acct_server->shared_secret_len = len;
  1424. } else if (os_strcmp(buf, "radius_retry_primary_interval") ==
  1425. 0) {
  1426. bss->radius->retry_primary_interval = atoi(pos);
  1427. } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0)
  1428. {
  1429. bss->radius->acct_interim_interval = atoi(pos);
  1430. } else if (os_strcmp(buf, "auth_algs") == 0) {
  1431. bss->auth_algs = atoi(pos);
  1432. if (bss->auth_algs == 0) {
  1433. printf("Line %d: no authentication algorithms "
  1434. "allowed\n",
  1435. line);
  1436. errors++;
  1437. }
  1438. } else if (os_strcmp(buf, "max_num_sta") == 0) {
  1439. bss->max_num_sta = atoi(pos);
  1440. if (bss->max_num_sta < 0 ||
  1441. bss->max_num_sta > MAX_STA_COUNT) {
  1442. printf("Line %d: Invalid max_num_sta=%d; "
  1443. "allowed range 0..%d\n", line,
  1444. bss->max_num_sta, MAX_STA_COUNT);
  1445. errors++;
  1446. }
  1447. } else if (os_strcmp(buf, "wpa") == 0) {
  1448. bss->wpa = atoi(pos);
  1449. } else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
  1450. bss->wpa_group_rekey = atoi(pos);
  1451. } else if (os_strcmp(buf, "wpa_strict_rekey") == 0) {
  1452. bss->wpa_strict_rekey = atoi(pos);
  1453. } else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
  1454. bss->wpa_gmk_rekey = atoi(pos);
  1455. } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
  1456. int len = os_strlen(pos);
  1457. if (len < 8 || len > 63) {
  1458. printf("Line %d: invalid WPA passphrase length"
  1459. " %d (expected 8..63)\n", line, len);
  1460. errors++;
  1461. } else {
  1462. os_free(bss->ssid.wpa_passphrase);
  1463. bss->ssid.wpa_passphrase = os_strdup(pos);
  1464. }
  1465. } else if (os_strcmp(buf, "wpa_psk") == 0) {
  1466. os_free(bss->ssid.wpa_psk);
  1467. bss->ssid.wpa_psk =
  1468. os_zalloc(sizeof(struct hostapd_wpa_psk));
  1469. if (bss->ssid.wpa_psk == NULL)
  1470. errors++;
  1471. else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
  1472. PMK_LEN) ||
  1473. pos[PMK_LEN * 2] != '\0') {
  1474. printf("Line %d: Invalid PSK '%s'.\n", line,
  1475. pos);
  1476. errors++;
  1477. } else {
  1478. bss->ssid.wpa_psk->group = 1;
  1479. }
  1480. } else if (os_strcmp(buf, "wpa_psk_file") == 0) {
  1481. os_free(bss->ssid.wpa_psk_file);
  1482. bss->ssid.wpa_psk_file = os_strdup(pos);
  1483. if (!bss->ssid.wpa_psk_file) {
  1484. printf("Line %d: allocation failed\n", line);
  1485. errors++;
  1486. }
  1487. } else if (os_strcmp(buf, "wpa_key_mgmt") == 0) {
  1488. bss->wpa_key_mgmt =
  1489. hostapd_config_parse_key_mgmt(line, pos);
  1490. if (bss->wpa_key_mgmt == -1)
  1491. errors++;
  1492. } else if (os_strcmp(buf, "wpa_pairwise") == 0) {
  1493. bss->wpa_pairwise =
  1494. hostapd_config_parse_cipher(line, pos);
  1495. if (bss->wpa_pairwise == -1 ||
  1496. bss->wpa_pairwise == 0)
  1497. errors++;
  1498. else if (bss->wpa_pairwise &
  1499. (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
  1500. WPA_CIPHER_WEP104)) {
  1501. printf("Line %d: unsupported pairwise "
  1502. "cipher suite '%s'\n",
  1503. bss->wpa_pairwise, pos);
  1504. errors++;
  1505. }
  1506. } else if (os_strcmp(buf, "rsn_pairwise") == 0) {
  1507. bss->rsn_pairwise =
  1508. hostapd_config_parse_cipher(line, pos);
  1509. if (bss->rsn_pairwise == -1 ||
  1510. bss->rsn_pairwise == 0)
  1511. errors++;
  1512. else if (bss->rsn_pairwise &
  1513. (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
  1514. WPA_CIPHER_WEP104)) {
  1515. printf("Line %d: unsupported pairwise "
  1516. "cipher suite '%s'\n",
  1517. bss->rsn_pairwise, pos);
  1518. errors++;
  1519. }
  1520. #ifdef CONFIG_RSN_PREAUTH
  1521. } else if (os_strcmp(buf, "rsn_preauth") == 0) {
  1522. bss->rsn_preauth = atoi(pos);
  1523. } else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
  1524. bss->rsn_preauth_interfaces = os_strdup(pos);
  1525. #endif /* CONFIG_RSN_PREAUTH */
  1526. #ifdef CONFIG_PEERKEY
  1527. } else if (os_strcmp(buf, "peerkey") == 0) {
  1528. bss->peerkey = atoi(pos);
  1529. #endif /* CONFIG_PEERKEY */
  1530. #ifdef CONFIG_IEEE80211R
  1531. } else if (os_strcmp(buf, "mobility_domain") == 0) {
  1532. if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
  1533. hexstr2bin(pos, bss->mobility_domain,
  1534. MOBILITY_DOMAIN_ID_LEN) != 0) {
  1535. wpa_printf(MSG_DEBUG, "Line %d: Invalid "
  1536. "mobility_domain '%s'", line, pos);
  1537. errors++;
  1538. continue;
  1539. }
  1540. } else if (os_strcmp(buf, "r1_key_holder") == 0) {
  1541. if (os_strlen(pos) != 2 * FT_R1KH_ID_LEN ||
  1542. hexstr2bin(pos, bss->r1_key_holder,
  1543. FT_R1KH_ID_LEN) != 0) {
  1544. wpa_printf(MSG_DEBUG, "Line %d: Invalid "
  1545. "r1_key_holder '%s'", line, pos);
  1546. errors++;
  1547. continue;
  1548. }
  1549. } else if (os_strcmp(buf, "r0_key_lifetime") == 0) {
  1550. bss->r0_key_lifetime = atoi(pos);
  1551. } else if (os_strcmp(buf, "reassociation_deadline") == 0) {
  1552. bss->reassociation_deadline = atoi(pos);
  1553. } else if (os_strcmp(buf, "r0kh") == 0) {
  1554. if (add_r0kh(bss, pos) < 0) {
  1555. wpa_printf(MSG_DEBUG, "Line %d: Invalid "
  1556. "r0kh '%s'", line, pos);
  1557. errors++;
  1558. continue;
  1559. }
  1560. } else if (os_strcmp(buf, "r1kh") == 0) {
  1561. if (add_r1kh(bss, pos) < 0) {
  1562. wpa_printf(MSG_DEBUG, "Line %d: Invalid "
  1563. "r1kh '%s'", line, pos);
  1564. errors++;
  1565. continue;
  1566. }
  1567. } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
  1568. bss->pmk_r1_push = atoi(pos);
  1569. #endif /* CONFIG_IEEE80211R */
  1570. } else if (os_strcmp(buf, "ctrl_interface") == 0) {
  1571. os_free(bss->ctrl_interface);
  1572. bss->ctrl_interface = os_strdup(pos);
  1573. } else if (os_strcmp(buf, "ctrl_interface_group") == 0) {
  1574. #ifndef CONFIG_NATIVE_WINDOWS
  1575. struct group *grp;
  1576. char *endp;
  1577. const char *group = pos;
  1578. grp = getgrnam(group);
  1579. if (grp) {
  1580. bss->ctrl_interface_gid = grp->gr_gid;
  1581. bss->ctrl_interface_gid_set = 1;
  1582. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
  1583. " (from group name '%s')",
  1584. bss->ctrl_interface_gid, group);
  1585. continue;
  1586. }
  1587. /* Group name not found - try to parse this as gid */
  1588. bss->ctrl_interface_gid = strtol(group, &endp, 10);
  1589. if (*group == '\0' || *endp != '\0') {
  1590. wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
  1591. "'%s'", line, group);
  1592. errors++;
  1593. continue;
  1594. }
  1595. bss->ctrl_interface_gid_set = 1;
  1596. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
  1597. bss->ctrl_interface_gid);
  1598. #endif /* CONFIG_NATIVE_WINDOWS */
  1599. #ifdef RADIUS_SERVER
  1600. } else if (os_strcmp(buf, "radius_server_clients") == 0) {
  1601. os_free(bss->radius_server_clients);
  1602. bss->radius_server_clients = os_strdup(pos);
  1603. } else if (os_strcmp(buf, "radius_server_auth_port") == 0) {
  1604. bss->radius_server_auth_port = atoi(pos);
  1605. } else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
  1606. bss->radius_server_ipv6 = atoi(pos);
  1607. #endif /* RADIUS_SERVER */
  1608. } else if (os_strcmp(buf, "test_socket") == 0) {
  1609. os_free(bss->test_socket);
  1610. bss->test_socket = os_strdup(pos);
  1611. } else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
  1612. bss->use_pae_group_addr = atoi(pos);
  1613. } else if (os_strcmp(buf, "hw_mode") == 0) {
  1614. if (os_strcmp(pos, "a") == 0)
  1615. conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
  1616. else if (os_strcmp(pos, "b") == 0)
  1617. conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
  1618. else if (os_strcmp(pos, "g") == 0)
  1619. conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
  1620. else {
  1621. printf("Line %d: unknown hw_mode '%s'\n",
  1622. line, pos);
  1623. errors++;
  1624. }
  1625. } else if (os_strcmp(buf, "channel") == 0) {
  1626. conf->channel = atoi(pos);
  1627. } else if (os_strcmp(buf, "beacon_int") == 0) {
  1628. int val = atoi(pos);
  1629. /* MIB defines range as 1..65535, but very small values
  1630. * cause problems with the current implementation.
  1631. * Since it is unlikely that this small numbers are
  1632. * useful in real life scenarios, do not allow beacon
  1633. * period to be set below 15 TU. */
  1634. if (val < 15 || val > 65535) {
  1635. printf("Line %d: invalid beacon_int %d "
  1636. "(expected 15..65535)\n",
  1637. line, val);
  1638. errors++;
  1639. } else
  1640. conf->beacon_int = val;
  1641. } else if (os_strcmp(buf, "dtim_period") == 0) {
  1642. bss->dtim_period = atoi(pos);
  1643. if (bss->dtim_period < 1 || bss->dtim_period > 255) {
  1644. printf("Line %d: invalid dtim_period %d\n",
  1645. line, bss->dtim_period);
  1646. errors++;
  1647. }
  1648. } else if (os_strcmp(buf, "rts_threshold") == 0) {
  1649. conf->rts_threshold = atoi(pos);
  1650. if (conf->rts_threshold < 0 ||
  1651. conf->rts_threshold > 2347) {
  1652. printf("Line %d: invalid rts_threshold %d\n",
  1653. line, conf->rts_threshold);
  1654. errors++;
  1655. }
  1656. } else if (os_strcmp(buf, "fragm_threshold") == 0) {
  1657. conf->fragm_threshold = atoi(pos);
  1658. if (conf->fragm_threshold < 256 ||
  1659. conf->fragm_threshold > 2346) {
  1660. printf("Line %d: invalid fragm_threshold %d\n",
  1661. line, conf->fragm_threshold);
  1662. errors++;
  1663. }
  1664. } else if (os_strcmp(buf, "send_probe_response") == 0) {
  1665. int val = atoi(pos);
  1666. if (val != 0 && val != 1) {
  1667. printf("Line %d: invalid send_probe_response "
  1668. "%d (expected 0 or 1)\n", line, val);
  1669. } else
  1670. conf->send_probe_response = val;
  1671. } else if (os_strcmp(buf, "supported_rates") == 0) {
  1672. if (hostapd_parse_rates(&conf->supported_rates, pos)) {
  1673. printf("Line %d: invalid rate list\n", line);
  1674. errors++;
  1675. }
  1676. } else if (os_strcmp(buf, "basic_rates") == 0) {
  1677. if (hostapd_parse_rates(&conf->basic_rates, pos)) {
  1678. printf("Line %d: invalid rate list\n", line);
  1679. errors++;
  1680. }
  1681. } else if (os_strcmp(buf, "preamble") == 0) {
  1682. if (atoi(pos))
  1683. conf->preamble = SHORT_PREAMBLE;
  1684. else
  1685. conf->preamble = LONG_PREAMBLE;
  1686. } else if (os_strcmp(buf, "ignore_broadcast_ssid") == 0) {
  1687. bss->ignore_broadcast_ssid = atoi(pos);
  1688. } else if (os_strcmp(buf, "bridge_packets") == 0) {
  1689. conf->bridge_packets = atoi(pos);
  1690. } else if (os_strcmp(buf, "wep_default_key") == 0) {
  1691. bss->ssid.wep.idx = atoi(pos);
  1692. if (bss->ssid.wep.idx > 3) {
  1693. printf("Invalid wep_default_key index %d\n",
  1694. bss->ssid.wep.idx);
  1695. errors++;
  1696. }
  1697. } else if (os_strcmp(buf, "wep_key0") == 0 ||
  1698. os_strcmp(buf, "wep_key1") == 0 ||
  1699. os_strcmp(buf, "wep_key2") == 0 ||
  1700. os_strcmp(buf, "wep_key3") == 0) {
  1701. if (hostapd_config_read_wep(&bss->ssid.wep,
  1702. buf[7] - '0', pos)) {
  1703. printf("Line %d: invalid WEP key '%s'\n",
  1704. line, buf);
  1705. errors++;
  1706. }
  1707. } else if (os_strcmp(buf, "dynamic_vlan") == 0) {
  1708. bss->ssid.dynamic_vlan = atoi(pos);
  1709. } else if (os_strcmp(buf, "vlan_file") == 0) {
  1710. if (hostapd_config_read_vlan_file(bss, pos)) {
  1711. printf("Line %d: failed to read VLAN file "
  1712. "'%s'\n", line, pos);
  1713. errors++;
  1714. }
  1715. #ifdef CONFIG_FULL_DYNAMIC_VLAN
  1716. } else if (os_strcmp(buf, "vlan_tagged_interface") == 0) {
  1717. bss->ssid.vlan_tagged_interface = os_strdup(pos);
  1718. #endif /* CONFIG_FULL_DYNAMIC_VLAN */
  1719. } else if (os_strcmp(buf, "passive_scan_interval") == 0) {
  1720. conf->passive_scan_interval = atoi(pos);
  1721. } else if (os_strcmp(buf, "passive_scan_listen") == 0) {
  1722. conf->passive_scan_listen = atoi(pos);
  1723. } else if (os_strcmp(buf, "passive_scan_mode") == 0) {
  1724. conf->passive_scan_mode = atoi(pos);
  1725. } else if (os_strcmp(buf, "ap_table_max_size") == 0) {
  1726. conf->ap_table_max_size = atoi(pos);
  1727. } else if (os_strcmp(buf, "ap_table_expiration_time") == 0) {
  1728. conf->ap_table_expiration_time = atoi(pos);
  1729. } else if (os_strncmp(buf, "tx_queue_", 9) == 0) {
  1730. if (hostapd_config_tx_queue(conf, buf, pos)) {
  1731. printf("Line %d: invalid TX queue item\n",
  1732. line);
  1733. errors++;
  1734. }
  1735. } else if (os_strcmp(buf, "wme_enabled") == 0) {
  1736. bss->wme_enabled = atoi(pos);
  1737. } else if (os_strncmp(buf, "wme_ac_", 7) == 0) {
  1738. if (hostapd_config_wme_ac(conf, buf, pos)) {
  1739. printf("Line %d: invalid wme ac item\n",
  1740. line);
  1741. errors++;
  1742. }
  1743. } else if (os_strcmp(buf, "bss") == 0) {
  1744. if (hostapd_config_bss(conf, pos)) {
  1745. printf("Line %d: invalid bss item\n", line);
  1746. errors++;
  1747. }
  1748. } else if (os_strcmp(buf, "bssid") == 0) {
  1749. if (bss == conf->bss &&
  1750. (!conf->driver || !conf->driver->init_bssid)) {
  1751. printf("Line %d: bssid item not allowed "
  1752. "for the default interface and this "
  1753. "driver\n", line);
  1754. errors++;
  1755. } else if (hwaddr_aton(pos, bss->bssid)) {
  1756. printf("Line %d: invalid bssid item\n", line);
  1757. errors++;
  1758. }
  1759. #ifdef CONFIG_IEEE80211W
  1760. } else if (os_strcmp(buf, "ieee80211w") == 0) {
  1761. bss->ieee80211w = atoi(pos);
  1762. #endif /* CONFIG_IEEE80211W */
  1763. #ifdef CONFIG_IEEE80211N
  1764. } else if (os_strcmp(buf, "ieee80211n") == 0) {
  1765. conf->ieee80211n = atoi(pos);
  1766. #endif /* CONFIG_IEEE80211N */
  1767. } else if (os_strcmp(buf, "max_listen_interval") == 0) {
  1768. bss->max_listen_interval = atoi(pos);
  1769. } else if (os_strcmp(buf, "okc") == 0) {
  1770. bss->okc = atoi(pos);
  1771. } else {
  1772. printf("Line %d: unknown configuration item '%s'\n",
  1773. line, buf);
  1774. errors++;
  1775. }
  1776. }
  1777. fclose(f);
  1778. if (bss->individual_wep_key_len == 0) {
  1779. /* individual keys are not use; can use key idx0 for broadcast
  1780. * keys */
  1781. bss->broadcast_key_idx_min = 0;
  1782. }
  1783. /* Select group cipher based on the enabled pairwise cipher suites */
  1784. pairwise = 0;
  1785. if (bss->wpa & 1)
  1786. pairwise |= bss->wpa_pairwise;
  1787. if (bss->wpa & 2) {
  1788. if (bss->rsn_pairwise == 0)
  1789. bss->rsn_pairwise = bss->wpa_pairwise;
  1790. pairwise |= bss->rsn_pairwise;
  1791. }
  1792. if (pairwise & WPA_CIPHER_TKIP)
  1793. bss->wpa_group = WPA_CIPHER_TKIP;
  1794. else
  1795. bss->wpa_group = WPA_CIPHER_CCMP;
  1796. for (i = 0; i < conf->num_bss; i++) {
  1797. bss = &conf->bss[i];
  1798. bss->radius->auth_server = bss->radius->auth_servers;
  1799. bss->radius->acct_server = bss->radius->acct_servers;
  1800. if (bss->wpa && bss->ieee802_1x) {
  1801. bss->ssid.security_policy = SECURITY_WPA;
  1802. } else if (bss->wpa) {
  1803. bss->ssid.security_policy = SECURITY_WPA_PSK;
  1804. } else if (bss->ieee802_1x) {
  1805. bss->ssid.security_policy = SECURITY_IEEE_802_1X;
  1806. bss->ssid.wep.default_len = bss->default_wep_key_len;
  1807. } else if (bss->ssid.wep.keys_set)
  1808. bss->ssid.security_policy = SECURITY_STATIC_WEP;
  1809. else
  1810. bss->ssid.security_policy = SECURITY_PLAINTEXT;
  1811. }
  1812. if (hostapd_config_check(conf))
  1813. errors++;
  1814. if (errors) {
  1815. printf("%d errors found in configuration file '%s'\n",
  1816. errors, fname);
  1817. hostapd_config_free(conf);
  1818. conf = NULL;
  1819. }
  1820. return conf;
  1821. }
  1822. int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
  1823. {
  1824. int i;
  1825. if (a->idx != b->idx || a->default_len != b->default_len)
  1826. return 1;
  1827. for (i = 0; i < NUM_WEP_KEYS; i++)
  1828. if (a->len[i] != b->len[i] ||
  1829. os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
  1830. return 1;
  1831. return 0;
  1832. }
  1833. static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
  1834. int num_servers)
  1835. {
  1836. int i;
  1837. for (i = 0; i < num_servers; i++) {
  1838. os_free(servers[i].shared_secret);
  1839. }
  1840. os_free(servers);
  1841. }
  1842. static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
  1843. {
  1844. os_free(user->identity);
  1845. os_free(user->password);
  1846. os_free(user);
  1847. }
  1848. static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
  1849. {
  1850. int i;
  1851. for (i = 0; i < NUM_WEP_KEYS; i++) {
  1852. os_free(keys->key[i]);
  1853. keys->key[i] = NULL;
  1854. }
  1855. }
  1856. static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
  1857. {
  1858. struct hostapd_wpa_psk *psk, *prev;
  1859. struct hostapd_eap_user *user, *prev_user;
  1860. if (conf == NULL)
  1861. return;
  1862. psk = conf->ssid.wpa_psk;
  1863. while (psk) {
  1864. prev = psk;
  1865. psk = psk->next;
  1866. os_free(prev);
  1867. }
  1868. os_free(conf->ssid.wpa_passphrase);
  1869. os_free(conf->ssid.wpa_psk_file);
  1870. #ifdef CONFIG_FULL_DYNAMIC_VLAN
  1871. os_free(conf->ssid.vlan_tagged_interface);
  1872. #endif /* CONFIG_FULL_DYNAMIC_VLAN */
  1873. user = conf->eap_user;
  1874. while (user) {
  1875. prev_user = user;
  1876. user = user->next;
  1877. hostapd_config_free_eap_user(prev_user);
  1878. }
  1879. os_free(conf->dump_log_name);
  1880. os_free(conf->eap_req_id_text);
  1881. os_free(conf->accept_mac);
  1882. os_free(conf->deny_mac);
  1883. os_free(conf->nas_identifier);
  1884. hostapd_config_free_radius(conf->radius->auth_servers,
  1885. conf->radius->num_auth_servers);
  1886. hostapd_config_free_radius(conf->radius->acct_servers,
  1887. conf->radius->num_acct_servers);
  1888. os_free(conf->rsn_preauth_interfaces);
  1889. os_free(conf->ctrl_interface);
  1890. os_free(conf->ca_cert);
  1891. os_free(conf->server_cert);
  1892. os_free(conf->private_key);
  1893. os_free(conf->private_key_passwd);
  1894. os_free(conf->dh_file);
  1895. os_free(conf->pac_opaque_encr_key);
  1896. os_free(conf->eap_fast_a_id);
  1897. os_free(conf->eap_sim_db);
  1898. os_free(conf->radius_server_clients);
  1899. os_free(conf->test_socket);
  1900. os_free(conf->radius);
  1901. hostapd_config_free_vlan(conf);
  1902. if (conf->ssid.dyn_vlan_keys) {
  1903. struct hostapd_ssid *ssid = &conf->ssid;
  1904. size_t i;
  1905. for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
  1906. if (ssid->dyn_vlan_keys[i] == NULL)
  1907. continue;
  1908. hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
  1909. os_free(ssid->dyn_vlan_keys[i]);
  1910. }
  1911. os_free(ssid->dyn_vlan_keys);
  1912. ssid->dyn_vlan_keys = NULL;
  1913. }
  1914. #ifdef CONFIG_IEEE80211R
  1915. {
  1916. struct ft_remote_r0kh *r0kh, *r0kh_prev;
  1917. struct ft_remote_r1kh *r1kh, *r1kh_prev;
  1918. r0kh = conf->r0kh_list;
  1919. conf->r0kh_list = NULL;
  1920. while (r0kh) {
  1921. r0kh_prev = r0kh;
  1922. r0kh = r0kh->next;
  1923. os_free(r0kh_prev);
  1924. }
  1925. r1kh = conf->r1kh_list;
  1926. conf->r1kh_list = NULL;
  1927. while (r1kh) {
  1928. r1kh_prev = r1kh;
  1929. r1kh = r1kh->next;
  1930. os_free(r1kh_prev);
  1931. }
  1932. }
  1933. #endif /* CONFIG_IEEE80211R */
  1934. }
  1935. void hostapd_config_free(struct hostapd_config *conf)
  1936. {
  1937. size_t i;
  1938. if (conf == NULL)
  1939. return;
  1940. for (i = 0; i < conf->num_bss; i++)
  1941. hostapd_config_free_bss(&conf->bss[i]);
  1942. os_free(conf->bss);
  1943. os_free(conf);
  1944. }
  1945. /* Perform a binary search for given MAC address from a pre-sorted list.
  1946. * Returns 1 if address is in the list or 0 if not. */
  1947. int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
  1948. const u8 *addr, int *vlan_id)
  1949. {
  1950. int start, end, middle, res;
  1951. start = 0;
  1952. end = num_entries - 1;
  1953. while (start <= end) {
  1954. middle = (start + end) / 2;
  1955. res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
  1956. if (res == 0) {
  1957. if (vlan_id)
  1958. *vlan_id = list[middle].vlan_id;
  1959. return 1;
  1960. }
  1961. if (res < 0)
  1962. start = middle + 1;
  1963. else
  1964. end = middle - 1;
  1965. }
  1966. return 0;
  1967. }
  1968. int hostapd_rate_found(int *list, int rate)
  1969. {
  1970. int i;
  1971. if (list == NULL)
  1972. return 0;
  1973. for (i = 0; list[i] >= 0; i++)
  1974. if (list[i] == rate)
  1975. return 1;
  1976. return 0;
  1977. }
  1978. const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
  1979. {
  1980. struct hostapd_vlan *v = vlan;
  1981. while (v) {
  1982. if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
  1983. return v->ifname;
  1984. v = v->next;
  1985. }
  1986. return NULL;
  1987. }
  1988. const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
  1989. const u8 *addr, const u8 *prev_psk)
  1990. {
  1991. struct hostapd_wpa_psk *psk;
  1992. int next_ok = prev_psk == NULL;
  1993. for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
  1994. if (next_ok &&
  1995. (psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0))
  1996. return psk->psk;
  1997. if (psk->psk == prev_psk)
  1998. next_ok = 1;
  1999. }
  2000. return NULL;
  2001. }
  2002. const struct hostapd_eap_user *
  2003. hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
  2004. size_t identity_len, int phase2)
  2005. {
  2006. struct hostapd_eap_user *user = conf->eap_user;
  2007. while (user) {
  2008. if (!phase2 && user->identity == NULL) {
  2009. /* Wildcard match */
  2010. break;
  2011. }
  2012. if (user->phase2 == !!phase2 && user->wildcard_prefix &&
  2013. identity_len >= user->identity_len &&
  2014. os_memcmp(user->identity, identity, user->identity_len) ==
  2015. 0) {
  2016. /* Wildcard prefix match */
  2017. break;
  2018. }
  2019. if (user->phase2 == !!phase2 &&
  2020. user->identity_len == identity_len &&
  2021. os_memcmp(user->identity, identity, identity_len) == 0)
  2022. break;
  2023. user = user->next;
  2024. }
  2025. return user;
  2026. }