Branch data Line data Source code
1 : : /*
2 : : * hostapd / Configuration file parser
3 : : * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "utils/includes.h"
10 : : #ifndef CONFIG_NATIVE_WINDOWS
11 : : #include <grp.h>
12 : : #endif /* CONFIG_NATIVE_WINDOWS */
13 : :
14 : : #include "utils/common.h"
15 : : #include "utils/uuid.h"
16 : : #include "common/ieee802_11_defs.h"
17 : : #include "drivers/driver.h"
18 : : #include "eap_server/eap.h"
19 : : #include "radius/radius_client.h"
20 : : #include "ap/wpa_auth.h"
21 : : #include "ap/ap_config.h"
22 : : #include "config_file.h"
23 : :
24 : :
25 : : #ifndef CONFIG_NO_VLAN
26 : 0 : static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
27 : : const char *fname)
28 : : {
29 : : FILE *f;
30 : : char buf[128], *pos, *pos2;
31 : 0 : int line = 0, vlan_id;
32 : : struct hostapd_vlan *vlan;
33 : :
34 : 0 : f = fopen(fname, "r");
35 [ # # ]: 0 : if (!f) {
36 : 0 : wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname);
37 : 0 : return -1;
38 : : }
39 : :
40 [ # # ]: 0 : while (fgets(buf, sizeof(buf), f)) {
41 : 0 : line++;
42 : :
43 [ # # ]: 0 : if (buf[0] == '#')
44 : 0 : continue;
45 : 0 : pos = buf;
46 [ # # ]: 0 : while (*pos != '\0') {
47 [ # # ]: 0 : if (*pos == '\n') {
48 : 0 : *pos = '\0';
49 : 0 : break;
50 : : }
51 : 0 : pos++;
52 : : }
53 [ # # ]: 0 : if (buf[0] == '\0')
54 : 0 : continue;
55 : :
56 [ # # ]: 0 : if (buf[0] == '*') {
57 : 0 : vlan_id = VLAN_ID_WILDCARD;
58 : 0 : pos = buf + 1;
59 : : } else {
60 : 0 : vlan_id = strtol(buf, &pos, 10);
61 [ # # ][ # # ]: 0 : if (buf == pos || vlan_id < 1 ||
[ # # ]
62 : : vlan_id > MAX_VLAN_ID) {
63 : 0 : wpa_printf(MSG_ERROR, "Invalid VLAN ID at "
64 : : "line %d in '%s'", line, fname);
65 : 0 : fclose(f);
66 : 0 : return -1;
67 : : }
68 : : }
69 : :
70 [ # # ][ # # ]: 0 : while (*pos == ' ' || *pos == '\t')
71 : 0 : pos++;
72 : 0 : pos2 = pos;
73 [ # # ][ # # ]: 0 : while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
[ # # ]
74 : 0 : pos2++;
75 : 0 : *pos2 = '\0';
76 [ # # ][ # # ]: 0 : if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
77 : 0 : wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d "
78 : : "in '%s'", line, fname);
79 : 0 : fclose(f);
80 : 0 : return -1;
81 : : }
82 : :
83 : 0 : vlan = os_zalloc(sizeof(*vlan));
84 [ # # ]: 0 : if (vlan == NULL) {
85 : 0 : wpa_printf(MSG_ERROR, "Out of memory while reading "
86 : : "VLAN interfaces from '%s'", fname);
87 : 0 : fclose(f);
88 : 0 : return -1;
89 : : }
90 : :
91 : 0 : vlan->vlan_id = vlan_id;
92 : 0 : os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
93 : 0 : vlan->next = bss->vlan;
94 : 0 : bss->vlan = vlan;
95 : : }
96 : :
97 : 0 : fclose(f);
98 : :
99 : 0 : return 0;
100 : : }
101 : : #endif /* CONFIG_NO_VLAN */
102 : :
103 : :
104 : 0 : static int hostapd_acl_comp(const void *a, const void *b)
105 : : {
106 : 0 : const struct mac_acl_entry *aa = a;
107 : 0 : const struct mac_acl_entry *bb = b;
108 : 0 : return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
109 : : }
110 : :
111 : :
112 : 0 : static int hostapd_config_read_maclist(const char *fname,
113 : : struct mac_acl_entry **acl, int *num)
114 : : {
115 : : FILE *f;
116 : : char buf[128], *pos;
117 : 0 : int line = 0;
118 : : u8 addr[ETH_ALEN];
119 : : struct mac_acl_entry *newacl;
120 : : int vlan_id;
121 : :
122 [ # # ]: 0 : if (!fname)
123 : 0 : return 0;
124 : :
125 : 0 : f = fopen(fname, "r");
126 [ # # ]: 0 : if (!f) {
127 : 0 : wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
128 : 0 : return -1;
129 : : }
130 : :
131 [ # # ]: 0 : while (fgets(buf, sizeof(buf), f)) {
132 : 0 : int i, rem = 0;
133 : :
134 : 0 : line++;
135 : :
136 [ # # ]: 0 : if (buf[0] == '#')
137 : 0 : continue;
138 : 0 : pos = buf;
139 [ # # ]: 0 : while (*pos != '\0') {
140 [ # # ]: 0 : if (*pos == '\n') {
141 : 0 : *pos = '\0';
142 : 0 : break;
143 : : }
144 : 0 : pos++;
145 : : }
146 [ # # ]: 0 : if (buf[0] == '\0')
147 : 0 : continue;
148 : 0 : pos = buf;
149 [ # # ]: 0 : if (buf[0] == '-') {
150 : 0 : rem = 1;
151 : 0 : pos++;
152 : : }
153 : :
154 [ # # ]: 0 : if (hwaddr_aton(pos, addr)) {
155 : 0 : wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at "
156 : : "line %d in '%s'", pos, line, fname);
157 : 0 : fclose(f);
158 : 0 : return -1;
159 : : }
160 : :
161 [ # # ]: 0 : if (rem) {
162 : 0 : i = 0;
163 [ # # ]: 0 : while (i < *num) {
164 [ # # ]: 0 : if (os_memcmp((*acl)[i].addr, addr, ETH_ALEN) ==
165 : : 0) {
166 : 0 : os_remove_in_array(*acl, *num,
167 : : sizeof(**acl), i);
168 : 0 : (*num)--;
169 : : } else
170 : 0 : i++;
171 : : }
172 : 0 : continue;
173 : : }
174 : 0 : vlan_id = 0;
175 : 0 : pos = buf;
176 [ # # ][ # # ]: 0 : while (*pos != '\0' && *pos != ' ' && *pos != '\t')
[ # # ]
177 : 0 : pos++;
178 [ # # ][ # # ]: 0 : while (*pos == ' ' || *pos == '\t')
179 : 0 : pos++;
180 [ # # ]: 0 : if (*pos != '\0')
181 : 0 : vlan_id = atoi(pos);
182 : :
183 : 0 : newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
184 [ # # ]: 0 : if (newacl == NULL) {
185 : 0 : wpa_printf(MSG_ERROR, "MAC list reallocation failed");
186 : 0 : fclose(f);
187 : 0 : return -1;
188 : : }
189 : :
190 : 0 : *acl = newacl;
191 : 0 : os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
192 : 0 : (*acl)[*num].vlan_id = vlan_id;
193 : 0 : (*num)++;
194 : : }
195 : :
196 : 0 : fclose(f);
197 : :
198 : 0 : qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
199 : :
200 : 0 : return 0;
201 : : }
202 : :
203 : :
204 : : #ifdef EAP_SERVER
205 : 14 : static int hostapd_config_read_eap_user(const char *fname,
206 : : struct hostapd_bss_config *conf)
207 : : {
208 : : FILE *f;
209 : : char buf[512], *pos, *start, *pos2;
210 : 14 : int line = 0, ret = 0, num_methods;
211 : 14 : struct hostapd_eap_user *user, *tail = NULL;
212 : :
213 [ - + ]: 14 : if (!fname)
214 : 0 : return 0;
215 : :
216 [ - + ]: 14 : if (os_strncmp(fname, "sqlite:", 7) == 0) {
217 : 0 : os_free(conf->eap_user_sqlite);
218 : 0 : conf->eap_user_sqlite = os_strdup(fname + 7);
219 : 0 : return 0;
220 : : }
221 : :
222 : 14 : f = fopen(fname, "r");
223 [ - + ]: 14 : if (!f) {
224 : 0 : wpa_printf(MSG_ERROR, "EAP user file '%s' not found.", fname);
225 : 0 : return -1;
226 : : }
227 : :
228 : : /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
229 [ + + ]: 588 : while (fgets(buf, sizeof(buf), f)) {
230 : 574 : line++;
231 : :
232 [ - + ]: 574 : if (buf[0] == '#')
233 : 0 : continue;
234 : 574 : pos = buf;
235 [ + - ]: 15330 : while (*pos != '\0') {
236 [ + + ]: 15330 : if (*pos == '\n') {
237 : 574 : *pos = '\0';
238 : 574 : break;
239 : : }
240 : 14756 : pos++;
241 : : }
242 [ + + ]: 574 : if (buf[0] == '\0')
243 : 56 : continue;
244 : :
245 : 518 : user = NULL;
246 : :
247 [ + + ][ - + ]: 518 : if (buf[0] != '"' && buf[0] != '*') {
248 : 0 : wpa_printf(MSG_ERROR, "Invalid EAP identity (no \" in "
249 : : "start) on line %d in '%s'", line, fname);
250 : 0 : goto failed;
251 : : }
252 : :
253 : 518 : user = os_zalloc(sizeof(*user));
254 [ - + ]: 518 : if (user == NULL) {
255 : 0 : wpa_printf(MSG_ERROR, "EAP user allocation failed");
256 : 0 : goto failed;
257 : : }
258 : 518 : user->force_version = -1;
259 : :
260 [ + + ]: 518 : if (buf[0] == '*') {
261 : 14 : pos = buf;
262 : : } else {
263 : 504 : pos = buf + 1;
264 : 504 : start = pos;
265 [ + + ][ + - ]: 3612 : while (*pos != '"' && *pos != '\0')
266 : 3108 : pos++;
267 [ - + ]: 504 : if (*pos == '\0') {
268 : 0 : wpa_printf(MSG_ERROR, "Invalid EAP identity "
269 : : "(no \" in end) on line %d in '%s'",
270 : : line, fname);
271 : 0 : goto failed;
272 : : }
273 : :
274 : 504 : user->identity = os_malloc(pos - start);
275 [ - + ]: 504 : if (user->identity == NULL) {
276 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate "
277 : : "memory for EAP identity");
278 : 0 : goto failed;
279 : : }
280 : 504 : os_memcpy(user->identity, start, pos - start);
281 : 504 : user->identity_len = pos - start;
282 : :
283 [ + - ][ + + ]: 504 : if (pos[0] == '"' && pos[1] == '*') {
284 : 252 : user->wildcard_prefix = 1;
285 : 252 : pos++;
286 : : }
287 : : }
288 : 518 : pos++;
289 [ - + ][ + + ]: 1302 : while (*pos == ' ' || *pos == '\t')
290 : 784 : pos++;
291 : :
292 [ - + ]: 518 : if (*pos == '\0') {
293 : 0 : wpa_printf(MSG_ERROR, "No EAP method on line %d in "
294 : : "'%s'", line, fname);
295 : 0 : goto failed;
296 : : }
297 : :
298 : 518 : start = pos;
299 [ + - ][ + + ]: 3878 : while (*pos != ' ' && *pos != '\t' && *pos != '\0')
[ + + ]
300 : 3360 : pos++;
301 [ + + ]: 518 : if (*pos == '\0') {
302 : 154 : pos = NULL;
303 : : } else {
304 : 364 : *pos = '\0';
305 : 364 : pos++;
306 : : }
307 : 518 : num_methods = 0;
308 [ + - ]: 630 : while (*start) {
309 : 630 : char *pos3 = os_strchr(start, ',');
310 [ + + ]: 630 : if (pos3) {
311 : 112 : *pos3++ = '\0';
312 : : }
313 : 630 : user->methods[num_methods].method =
314 : 630 : eap_server_get_type(
315 : : start,
316 : : &user->methods[num_methods].vendor);
317 [ + + ]: 630 : if (user->methods[num_methods].vendor ==
318 [ + + ]: 602 : EAP_VENDOR_IETF &&
319 : 602 : user->methods[num_methods].method == EAP_TYPE_NONE)
320 : : {
321 [ + + ]: 98 : if (os_strcmp(start, "TTLS-PAP") == 0) {
322 : 14 : user->ttls_auth |= EAP_TTLS_AUTH_PAP;
323 : 14 : goto skip_eap;
324 : : }
325 [ + + ]: 84 : if (os_strcmp(start, "TTLS-CHAP") == 0) {
326 : 14 : user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
327 : 14 : goto skip_eap;
328 : : }
329 [ + + ]: 70 : if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
330 : 14 : user->ttls_auth |=
331 : : EAP_TTLS_AUTH_MSCHAP;
332 : 14 : goto skip_eap;
333 : : }
334 [ + - ]: 56 : if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
335 : 56 : user->ttls_auth |=
336 : : EAP_TTLS_AUTH_MSCHAPV2;
337 : 56 : goto skip_eap;
338 : : }
339 : 0 : wpa_printf(MSG_ERROR, "Unsupported EAP type "
340 : : "'%s' on line %d in '%s'",
341 : : start, line, fname);
342 : 0 : goto failed;
343 : : }
344 : :
345 : 532 : num_methods++;
346 [ - + ]: 532 : if (num_methods >= EAP_MAX_METHODS)
347 : 0 : break;
348 : : skip_eap:
349 [ + + ]: 630 : if (pos3 == NULL)
350 : 518 : break;
351 : 112 : start = pos3;
352 : : }
353 [ + + ][ - + ]: 518 : if (num_methods == 0 && user->ttls_auth == 0) {
354 : 0 : wpa_printf(MSG_ERROR, "No EAP types configured on "
355 : : "line %d in '%s'", line, fname);
356 : 0 : goto failed;
357 : : }
358 : :
359 [ + + ]: 518 : if (pos == NULL)
360 : 154 : goto done;
361 : :
362 [ - + ][ - + ]: 364 : while (*pos == ' ' || *pos == '\t')
363 : 0 : pos++;
364 [ - + ]: 364 : if (*pos == '\0')
365 : 0 : goto done;
366 : :
367 [ - + ]: 364 : if (os_strncmp(pos, "[ver=0]", 7) == 0) {
368 : 0 : user->force_version = 0;
369 : 0 : goto done;
370 : : }
371 : :
372 [ - + ]: 364 : if (os_strncmp(pos, "[ver=1]", 7) == 0) {
373 : 0 : user->force_version = 1;
374 : 0 : goto done;
375 : : }
376 : :
377 [ + + ]: 364 : if (os_strncmp(pos, "[2]", 3) == 0) {
378 : 140 : user->phase2 = 1;
379 : 140 : goto done;
380 : : }
381 : :
382 [ + + ]: 224 : if (*pos == '"') {
383 : 154 : pos++;
384 : 154 : start = pos;
385 [ + + ][ + - ]: 2016 : while (*pos != '"' && *pos != '\0')
386 : 1862 : pos++;
387 [ - + ]: 154 : if (*pos == '\0') {
388 : 0 : wpa_printf(MSG_ERROR, "Invalid EAP password "
389 : : "(no \" in end) on line %d in '%s'",
390 : : line, fname);
391 : 0 : goto failed;
392 : : }
393 : :
394 : 154 : user->password = os_malloc(pos - start);
395 [ - + ]: 154 : if (user->password == NULL) {
396 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate "
397 : : "memory for EAP password");
398 : 0 : goto failed;
399 : : }
400 : 154 : os_memcpy(user->password, start, pos - start);
401 : 154 : user->password_len = pos - start;
402 : :
403 : 154 : pos++;
404 [ + + ]: 70 : } else if (os_strncmp(pos, "hash:", 5) == 0) {
405 : 28 : pos += 5;
406 : 28 : pos2 = pos;
407 [ + - ][ + - ]: 924 : while (*pos2 != '\0' && *pos2 != ' ' &&
[ + + ]
408 [ + - ]: 896 : *pos2 != '\t' && *pos2 != '#')
409 : 896 : pos2++;
410 [ - + ]: 28 : if (pos2 - pos != 32) {
411 : 0 : wpa_printf(MSG_ERROR, "Invalid password hash "
412 : : "on line %d in '%s'", line, fname);
413 : 0 : goto failed;
414 : : }
415 : 28 : user->password = os_malloc(16);
416 [ - + ]: 28 : if (user->password == NULL) {
417 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate "
418 : : "memory for EAP password hash");
419 : 0 : goto failed;
420 : : }
421 [ - + ]: 28 : if (hexstr2bin(pos, user->password, 16) < 0) {
422 : 0 : wpa_printf(MSG_ERROR, "Invalid hash password "
423 : : "on line %d in '%s'", line, fname);
424 : 0 : goto failed;
425 : : }
426 : 28 : user->password_len = 16;
427 : 28 : user->password_hash = 1;
428 : 28 : pos = pos2;
429 : : } else {
430 : 42 : pos2 = pos;
431 [ + + ][ + - ]: 1834 : while (*pos2 != '\0' && *pos2 != ' ' &&
[ + - ]
432 [ + - ]: 1792 : *pos2 != '\t' && *pos2 != '#')
433 : 1792 : pos2++;
434 [ - + ]: 42 : if ((pos2 - pos) & 1) {
435 : 0 : wpa_printf(MSG_ERROR, "Invalid hex password "
436 : : "on line %d in '%s'", line, fname);
437 : 0 : goto failed;
438 : : }
439 : 42 : user->password = os_malloc((pos2 - pos) / 2);
440 [ - + ]: 42 : if (user->password == NULL) {
441 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate "
442 : : "memory for EAP password");
443 : 0 : goto failed;
444 : : }
445 [ - + ]: 42 : if (hexstr2bin(pos, user->password,
446 : 42 : (pos2 - pos) / 2) < 0) {
447 : 0 : wpa_printf(MSG_ERROR, "Invalid hex password "
448 : : "on line %d in '%s'", line, fname);
449 : 0 : goto failed;
450 : : }
451 : 42 : user->password_len = (pos2 - pos) / 2;
452 : 42 : pos = pos2;
453 : : }
454 : :
455 [ - + ][ + + ]: 336 : while (*pos == ' ' || *pos == '\t')
456 : 112 : pos++;
457 [ + + ]: 224 : if (os_strncmp(pos, "[2]", 3) == 0) {
458 : 112 : user->phase2 = 1;
459 : : }
460 : :
461 : : done:
462 [ + + ]: 518 : if (tail == NULL) {
463 : 14 : tail = conf->eap_user = user;
464 : : } else {
465 : 504 : tail->next = user;
466 : 504 : tail = user;
467 : : }
468 : 518 : continue;
469 : :
470 : : failed:
471 [ # # ]: 0 : if (user) {
472 : 0 : os_free(user->password);
473 : 0 : os_free(user->identity);
474 : 0 : os_free(user);
475 : : }
476 : 0 : ret = -1;
477 : 0 : break;
478 : : }
479 : :
480 : 14 : fclose(f);
481 : :
482 : 14 : return ret;
483 : : }
484 : : #endif /* EAP_SERVER */
485 : :
486 : :
487 : : #ifndef CONFIG_NO_RADIUS
488 : : static int
489 : 151 : hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
490 : : int *num_server, const char *val, int def_port,
491 : : struct hostapd_radius_server **curr_serv)
492 : : {
493 : : struct hostapd_radius_server *nserv;
494 : : int ret;
495 : : static int server_index = 1;
496 : :
497 : 151 : nserv = os_realloc_array(*server, *num_server + 1, sizeof(*nserv));
498 [ - + ]: 151 : if (nserv == NULL)
499 : 0 : return -1;
500 : :
501 : 151 : *server = nserv;
502 : 151 : nserv = &nserv[*num_server];
503 : 151 : (*num_server)++;
504 : 151 : (*curr_serv) = nserv;
505 : :
506 : 151 : os_memset(nserv, 0, sizeof(*nserv));
507 : 151 : nserv->port = def_port;
508 : 151 : ret = hostapd_parse_ip_addr(val, &nserv->addr);
509 : 151 : nserv->index = server_index++;
510 : :
511 : 151 : return ret;
512 : : }
513 : :
514 : :
515 : : static struct hostapd_radius_attr *
516 : 0 : hostapd_parse_radius_attr(const char *value)
517 : : {
518 : : const char *pos;
519 : : char syntax;
520 : : struct hostapd_radius_attr *attr;
521 : : size_t len;
522 : :
523 : 0 : attr = os_zalloc(sizeof(*attr));
524 [ # # ]: 0 : if (attr == NULL)
525 : 0 : return NULL;
526 : :
527 : 0 : attr->type = atoi(value);
528 : :
529 : 0 : pos = os_strchr(value, ':');
530 [ # # ]: 0 : if (pos == NULL) {
531 : 0 : attr->val = wpabuf_alloc(1);
532 [ # # ]: 0 : if (attr->val == NULL) {
533 : 0 : os_free(attr);
534 : 0 : return NULL;
535 : : }
536 : 0 : wpabuf_put_u8(attr->val, 0);
537 : 0 : return attr;
538 : : }
539 : :
540 : 0 : pos++;
541 [ # # ][ # # ]: 0 : if (pos[0] == '\0' || pos[1] != ':') {
542 : 0 : os_free(attr);
543 : 0 : return NULL;
544 : : }
545 : 0 : syntax = *pos++;
546 : 0 : pos++;
547 : :
548 [ # # # # ]: 0 : switch (syntax) {
549 : : case 's':
550 : 0 : attr->val = wpabuf_alloc_copy(pos, os_strlen(pos));
551 : 0 : break;
552 : : case 'x':
553 : 0 : len = os_strlen(pos);
554 [ # # ]: 0 : if (len & 1)
555 : 0 : break;
556 : 0 : len /= 2;
557 : 0 : attr->val = wpabuf_alloc(len);
558 [ # # ]: 0 : if (attr->val == NULL)
559 : 0 : break;
560 [ # # ]: 0 : if (hexstr2bin(pos, wpabuf_put(attr->val, len), len) < 0) {
561 : 0 : wpabuf_free(attr->val);
562 : 0 : os_free(attr);
563 : 0 : return NULL;
564 : : }
565 : 0 : break;
566 : : case 'd':
567 : 0 : attr->val = wpabuf_alloc(4);
568 [ # # ]: 0 : if (attr->val)
569 : 0 : wpabuf_put_be32(attr->val, atoi(pos));
570 : 0 : break;
571 : : default:
572 : 0 : os_free(attr);
573 : 0 : return NULL;
574 : : }
575 : :
576 [ # # ]: 0 : if (attr->val == NULL) {
577 : 0 : os_free(attr);
578 : 0 : return NULL;
579 : : }
580 : :
581 : 0 : return attr;
582 : : }
583 : :
584 : :
585 : 2 : static int hostapd_parse_das_client(struct hostapd_bss_config *bss,
586 : : const char *val)
587 : : {
588 : : char *secret;
589 : :
590 : 2 : secret = os_strchr(val, ' ');
591 [ - + ]: 2 : if (secret == NULL)
592 : 0 : return -1;
593 : :
594 : 2 : secret++;
595 : :
596 [ - + ]: 2 : if (hostapd_parse_ip_addr(val, &bss->radius_das_client_addr))
597 : 0 : return -1;
598 : :
599 : 2 : os_free(bss->radius_das_shared_secret);
600 : 2 : bss->radius_das_shared_secret = (u8 *) os_strdup(secret);
601 [ - + ]: 2 : if (bss->radius_das_shared_secret == NULL)
602 : 0 : return -1;
603 : 2 : bss->radius_das_shared_secret_len = os_strlen(secret);
604 : :
605 : 2 : return 0;
606 : : }
607 : : #endif /* CONFIG_NO_RADIUS */
608 : :
609 : :
610 : 252 : static int hostapd_config_parse_key_mgmt(int line, const char *value)
611 : : {
612 : 252 : int val = 0, last;
613 : : char *start, *end, *buf;
614 : :
615 : 252 : buf = os_strdup(value);
616 [ - + ]: 252 : if (buf == NULL)
617 : 0 : return -1;
618 : 252 : start = buf;
619 : :
620 [ + - ]: 255 : while (*start != '\0') {
621 [ - + ][ - + ]: 255 : while (*start == ' ' || *start == '\t')
622 : 0 : start++;
623 [ - + ]: 255 : if (*start == '\0')
624 : 0 : break;
625 : 255 : end = start;
626 [ + + ][ + - ]: 2043 : while (*end != ' ' && *end != '\t' && *end != '\0')
[ + + ]
627 : 1788 : end++;
628 : 255 : last = *end == '\0';
629 : 255 : *end = '\0';
630 [ + + ]: 255 : if (os_strcmp(start, "WPA-PSK") == 0)
631 : 77 : val |= WPA_KEY_MGMT_PSK;
632 [ + + ]: 178 : else if (os_strcmp(start, "WPA-EAP") == 0)
633 : 153 : val |= WPA_KEY_MGMT_IEEE8021X;
634 : : #ifdef CONFIG_IEEE80211R
635 [ + + ]: 25 : else if (os_strcmp(start, "FT-PSK") == 0)
636 : 10 : val |= WPA_KEY_MGMT_FT_PSK;
637 [ + + ]: 15 : else if (os_strcmp(start, "FT-EAP") == 0)
638 : 2 : val |= WPA_KEY_MGMT_FT_IEEE8021X;
639 : : #endif /* CONFIG_IEEE80211R */
640 : : #ifdef CONFIG_IEEE80211W
641 [ + + ]: 13 : else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
642 : 4 : val |= WPA_KEY_MGMT_PSK_SHA256;
643 [ + + ]: 9 : else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
644 : 1 : val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
645 : : #endif /* CONFIG_IEEE80211W */
646 : : #ifdef CONFIG_SAE
647 [ + + ]: 8 : else if (os_strcmp(start, "SAE") == 0)
648 : 4 : val |= WPA_KEY_MGMT_SAE;
649 [ + - ]: 4 : else if (os_strcmp(start, "FT-SAE") == 0)
650 : 4 : val |= WPA_KEY_MGMT_FT_SAE;
651 : : #endif /* CONFIG_SAE */
652 : : else {
653 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
654 : : line, start);
655 : 0 : os_free(buf);
656 : 0 : return -1;
657 : : }
658 : :
659 [ + + ]: 255 : if (last)
660 : 252 : break;
661 : 3 : start = end + 1;
662 : : }
663 : :
664 : 252 : os_free(buf);
665 [ - + ]: 252 : if (val == 0) {
666 : 0 : wpa_printf(MSG_ERROR, "Line %d: no key_mgmt values "
667 : : "configured.", line);
668 : 0 : return -1;
669 : : }
670 : :
671 : 252 : return val;
672 : : }
673 : :
674 : :
675 : 257 : static int hostapd_config_parse_cipher(int line, const char *value)
676 : : {
677 : 257 : int val = wpa_parse_cipher(value);
678 [ - + ]: 257 : if (val < 0) {
679 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
680 : : line, value);
681 : 0 : return -1;
682 : : }
683 [ - + ]: 257 : if (val == 0) {
684 : 0 : wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
685 : : line);
686 : 0 : return -1;
687 : : }
688 : 257 : return val;
689 : : }
690 : :
691 : :
692 : 4 : static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
693 : : char *val)
694 : : {
695 : 4 : size_t len = os_strlen(val);
696 : :
697 [ + - ][ + - ]: 4 : if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
[ - + ]
698 : 0 : return -1;
699 : :
700 [ + - ]: 4 : if (val[0] == '"') {
701 [ + - ][ - + ]: 4 : if (len < 2 || val[len - 1] != '"')
702 : 0 : return -1;
703 : 4 : len -= 2;
704 : 4 : wep->key[keyidx] = os_malloc(len);
705 [ - + ]: 4 : if (wep->key[keyidx] == NULL)
706 : 0 : return -1;
707 : 4 : os_memcpy(wep->key[keyidx], val + 1, len);
708 : 4 : wep->len[keyidx] = len;
709 : : } else {
710 [ # # ]: 0 : if (len & 1)
711 : 0 : return -1;
712 : 0 : len /= 2;
713 : 0 : wep->key[keyidx] = os_malloc(len);
714 [ # # ]: 0 : if (wep->key[keyidx] == NULL)
715 : 0 : return -1;
716 : 0 : wep->len[keyidx] = len;
717 [ # # ]: 0 : if (hexstr2bin(val, wep->key[keyidx], len) < 0)
718 : 0 : return -1;
719 : : }
720 : :
721 : 4 : wep->keys_set++;
722 : :
723 : 4 : return 0;
724 : : }
725 : :
726 : :
727 : 4 : static int hostapd_parse_intlist(int **int_list, char *val)
728 : : {
729 : : int *list;
730 : : int count;
731 : : char *pos, *end;
732 : :
733 : 4 : os_free(*int_list);
734 : 4 : *int_list = NULL;
735 : :
736 : 4 : pos = val;
737 : 4 : count = 0;
738 [ + + ]: 35 : while (*pos != '\0') {
739 [ + + ]: 31 : if (*pos == ' ')
740 : 9 : count++;
741 : 31 : pos++;
742 : : }
743 : :
744 : 4 : list = os_malloc(sizeof(int) * (count + 2));
745 [ - + ]: 4 : if (list == NULL)
746 : 0 : return -1;
747 : 4 : pos = val;
748 : 4 : count = 0;
749 [ + - ]: 13 : while (*pos != '\0') {
750 : 13 : end = os_strchr(pos, ' ');
751 [ + + ]: 13 : if (end)
752 : 9 : *end = '\0';
753 : :
754 : 13 : list[count++] = atoi(pos);
755 [ + + ]: 13 : if (!end)
756 : 4 : break;
757 : 9 : pos = end + 1;
758 : : }
759 : 4 : list[count] = -1;
760 : :
761 : 4 : *int_list = list;
762 : 4 : return 0;
763 : : }
764 : :
765 : :
766 : 10 : static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
767 : : {
768 : : struct hostapd_bss_config **all, *bss;
769 : :
770 [ - + ]: 10 : if (*ifname == '\0')
771 : 0 : return -1;
772 : :
773 : 10 : all = os_realloc_array(conf->bss, conf->num_bss + 1,
774 : : sizeof(struct hostapd_bss_config *));
775 [ - + ]: 10 : if (all == NULL) {
776 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate memory for "
777 : : "multi-BSS entry");
778 : 0 : return -1;
779 : : }
780 : 10 : conf->bss = all;
781 : :
782 : 10 : bss = os_zalloc(sizeof(*bss));
783 [ - + ]: 10 : if (bss == NULL)
784 : 0 : return -1;
785 : 10 : bss->radius = os_zalloc(sizeof(*bss->radius));
786 [ - + ]: 10 : if (bss->radius == NULL) {
787 : 0 : wpa_printf(MSG_ERROR, "Failed to allocate memory for "
788 : : "multi-BSS RADIUS data");
789 : 0 : os_free(bss);
790 : 0 : return -1;
791 : : }
792 : :
793 : 10 : conf->bss[conf->num_bss++] = bss;
794 : 10 : conf->last_bss = bss;
795 : :
796 : 10 : hostapd_config_defaults_bss(bss);
797 : 10 : os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
798 : 10 : os_memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
799 : :
800 : 10 : return 0;
801 : : }
802 : :
803 : :
804 : : /* convert floats with one decimal place to value*10 int, i.e.,
805 : : * "1.5" will return 15 */
806 : 0 : static int hostapd_config_read_int10(const char *value)
807 : : {
808 : : int i, d;
809 : : char *pos;
810 : :
811 : 0 : i = atoi(value);
812 : 0 : pos = os_strchr(value, '.');
813 : 0 : d = 0;
814 [ # # ]: 0 : if (pos) {
815 : 0 : pos++;
816 [ # # ][ # # ]: 0 : if (*pos >= '0' && *pos <= '9')
817 : 0 : d = *pos - '0';
818 : : }
819 : :
820 : 0 : return i * 10 + d;
821 : : }
822 : :
823 : :
824 : 0 : static int valid_cw(int cw)
825 : : {
826 [ # # ][ # # ]: 0 : return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
[ # # ][ # # ]
[ # # ][ # # ]
827 [ # # ][ # # ]: 0 : cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
[ # # ][ # # ]
828 : : }
829 : :
830 : :
831 : : enum {
832 : : IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
833 : : IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
834 : : IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
835 : : IEEE80211_TX_QUEUE_DATA3 = 3 /* used for EDCA AC_BK data */
836 : : };
837 : :
838 : 0 : static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
839 : : char *val)
840 : : {
841 : : int num;
842 : : char *pos;
843 : : struct hostapd_tx_queue_params *queue;
844 : :
845 : : /* skip 'tx_queue_' prefix */
846 : 0 : pos = name + 9;
847 [ # # ][ # # ]: 0 : if (os_strncmp(pos, "data", 4) == 0 &&
848 [ # # ][ # # ]: 0 : pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
849 : 0 : num = pos[4] - '0';
850 : 0 : pos += 6;
851 [ # # ][ # # ]: 0 : } else if (os_strncmp(pos, "after_beacon_", 13) == 0 ||
852 : 0 : os_strncmp(pos, "beacon_", 7) == 0) {
853 : 0 : wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
854 : 0 : return 0;
855 : : } else {
856 : 0 : wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
857 : 0 : return -1;
858 : : }
859 : :
860 [ # # ]: 0 : if (num >= NUM_TX_QUEUES) {
861 : : /* for backwards compatibility, do not trigger failure */
862 : 0 : wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
863 : 0 : return 0;
864 : : }
865 : :
866 : 0 : queue = &conf->tx_queue[num];
867 : :
868 [ # # ]: 0 : if (os_strcmp(pos, "aifs") == 0) {
869 : 0 : queue->aifs = atoi(val);
870 [ # # ][ # # ]: 0 : if (queue->aifs < 0 || queue->aifs > 255) {
871 : 0 : wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
872 : : queue->aifs);
873 : 0 : return -1;
874 : : }
875 [ # # ]: 0 : } else if (os_strcmp(pos, "cwmin") == 0) {
876 : 0 : queue->cwmin = atoi(val);
877 [ # # ]: 0 : if (!valid_cw(queue->cwmin)) {
878 : 0 : wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
879 : : queue->cwmin);
880 : 0 : return -1;
881 : : }
882 [ # # ]: 0 : } else if (os_strcmp(pos, "cwmax") == 0) {
883 : 0 : queue->cwmax = atoi(val);
884 [ # # ]: 0 : if (!valid_cw(queue->cwmax)) {
885 : 0 : wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
886 : : queue->cwmax);
887 : 0 : return -1;
888 : : }
889 [ # # ]: 0 : } else if (os_strcmp(pos, "burst") == 0) {
890 : 0 : queue->burst = hostapd_config_read_int10(val);
891 : : } else {
892 : 0 : wpa_printf(MSG_ERROR, "Unknown tx_queue field '%s'", pos);
893 : 0 : return -1;
894 : : }
895 : :
896 : 0 : return 0;
897 : : }
898 : :
899 : :
900 : : #ifdef CONFIG_IEEE80211R
901 : 32 : static int add_r0kh(struct hostapd_bss_config *bss, char *value)
902 : : {
903 : : struct ft_remote_r0kh *r0kh;
904 : : char *pos, *next;
905 : :
906 : 32 : r0kh = os_zalloc(sizeof(*r0kh));
907 [ - + ]: 32 : if (r0kh == NULL)
908 : 0 : return -1;
909 : :
910 : : /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
911 : 32 : pos = value;
912 : 32 : next = os_strchr(pos, ' ');
913 [ + - ]: 32 : if (next)
914 : 32 : *next++ = '\0';
915 [ + - ][ - + ]: 32 : if (next == NULL || hwaddr_aton(pos, r0kh->addr)) {
916 : 0 : wpa_printf(MSG_ERROR, "Invalid R0KH MAC address: '%s'", pos);
917 : 0 : os_free(r0kh);
918 : 0 : return -1;
919 : : }
920 : :
921 : 32 : pos = next;
922 : 32 : next = os_strchr(pos, ' ');
923 [ + - ]: 32 : if (next)
924 : 32 : *next++ = '\0';
925 [ + - ][ - + ]: 32 : if (next == NULL || next - pos > FT_R0KH_ID_MAX_LEN) {
926 : 0 : wpa_printf(MSG_ERROR, "Invalid R0KH-ID: '%s'", pos);
927 : 0 : os_free(r0kh);
928 : 0 : return -1;
929 : : }
930 : 32 : r0kh->id_len = next - pos - 1;
931 : 32 : os_memcpy(r0kh->id, pos, r0kh->id_len);
932 : :
933 : 32 : pos = next;
934 [ - + ]: 32 : if (hexstr2bin(pos, r0kh->key, sizeof(r0kh->key))) {
935 : 0 : wpa_printf(MSG_ERROR, "Invalid R0KH key: '%s'", pos);
936 : 0 : os_free(r0kh);
937 : 0 : return -1;
938 : : }
939 : :
940 : 32 : r0kh->next = bss->r0kh_list;
941 : 32 : bss->r0kh_list = r0kh;
942 : :
943 : 32 : return 0;
944 : : }
945 : :
946 : :
947 : 16 : static int add_r1kh(struct hostapd_bss_config *bss, char *value)
948 : : {
949 : : struct ft_remote_r1kh *r1kh;
950 : : char *pos, *next;
951 : :
952 : 16 : r1kh = os_zalloc(sizeof(*r1kh));
953 [ - + ]: 16 : if (r1kh == NULL)
954 : 0 : return -1;
955 : :
956 : : /* 02:01:02:03:04:05 02:01:02:03:04:05
957 : : * 000102030405060708090a0b0c0d0e0f */
958 : 16 : pos = value;
959 : 16 : next = os_strchr(pos, ' ');
960 [ + - ]: 16 : if (next)
961 : 16 : *next++ = '\0';
962 [ + - ][ - + ]: 16 : if (next == NULL || hwaddr_aton(pos, r1kh->addr)) {
963 : 0 : wpa_printf(MSG_ERROR, "Invalid R1KH MAC address: '%s'", pos);
964 : 0 : os_free(r1kh);
965 : 0 : return -1;
966 : : }
967 : :
968 : 16 : pos = next;
969 : 16 : next = os_strchr(pos, ' ');
970 [ + - ]: 16 : if (next)
971 : 16 : *next++ = '\0';
972 [ + - ][ - + ]: 16 : if (next == NULL || hwaddr_aton(pos, r1kh->id)) {
973 : 0 : wpa_printf(MSG_ERROR, "Invalid R1KH-ID: '%s'", pos);
974 : 0 : os_free(r1kh);
975 : 0 : return -1;
976 : : }
977 : :
978 : 16 : pos = next;
979 [ - + ]: 16 : if (hexstr2bin(pos, r1kh->key, sizeof(r1kh->key))) {
980 : 0 : wpa_printf(MSG_ERROR, "Invalid R1KH key: '%s'", pos);
981 : 0 : os_free(r1kh);
982 : 0 : return -1;
983 : : }
984 : :
985 : 16 : r1kh->next = bss->r1kh_list;
986 : 16 : bss->r1kh_list = r1kh;
987 : :
988 : 16 : return 0;
989 : : }
990 : : #endif /* CONFIG_IEEE80211R */
991 : :
992 : :
993 : : #ifdef CONFIG_IEEE80211N
994 : 12 : static int hostapd_config_ht_capab(struct hostapd_config *conf,
995 : : const char *capab)
996 : : {
997 [ - + ]: 12 : if (os_strstr(capab, "[LDPC]"))
998 : 0 : conf->ht_capab |= HT_CAP_INFO_LDPC_CODING_CAP;
999 [ + + ]: 12 : if (os_strstr(capab, "[HT40-]")) {
1000 : 3 : conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1001 : 3 : conf->secondary_channel = -1;
1002 : : }
1003 [ + + ]: 12 : if (os_strstr(capab, "[HT40+]")) {
1004 : 9 : conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1005 : 9 : conf->secondary_channel = 1;
1006 : : }
1007 [ - + ]: 12 : if (os_strstr(capab, "[SMPS-STATIC]")) {
1008 : 0 : conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
1009 : 0 : conf->ht_capab |= HT_CAP_INFO_SMPS_STATIC;
1010 : : }
1011 [ - + ]: 12 : if (os_strstr(capab, "[SMPS-DYNAMIC]")) {
1012 : 0 : conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
1013 : 0 : conf->ht_capab |= HT_CAP_INFO_SMPS_DYNAMIC;
1014 : : }
1015 [ - + ]: 12 : if (os_strstr(capab, "[GF]"))
1016 : 0 : conf->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
1017 [ - + ]: 12 : if (os_strstr(capab, "[SHORT-GI-20]"))
1018 : 0 : conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
1019 [ - + ]: 12 : if (os_strstr(capab, "[SHORT-GI-40]"))
1020 : 0 : conf->ht_capab |= HT_CAP_INFO_SHORT_GI40MHZ;
1021 [ - + ]: 12 : if (os_strstr(capab, "[TX-STBC]"))
1022 : 0 : conf->ht_capab |= HT_CAP_INFO_TX_STBC;
1023 [ - + ]: 12 : if (os_strstr(capab, "[RX-STBC1]")) {
1024 : 0 : conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1025 : 0 : conf->ht_capab |= HT_CAP_INFO_RX_STBC_1;
1026 : : }
1027 [ - + ]: 12 : if (os_strstr(capab, "[RX-STBC12]")) {
1028 : 0 : conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1029 : 0 : conf->ht_capab |= HT_CAP_INFO_RX_STBC_12;
1030 : : }
1031 [ - + ]: 12 : if (os_strstr(capab, "[RX-STBC123]")) {
1032 : 0 : conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1033 : 0 : conf->ht_capab |= HT_CAP_INFO_RX_STBC_123;
1034 : : }
1035 [ - + ]: 12 : if (os_strstr(capab, "[DELAYED-BA]"))
1036 : 0 : conf->ht_capab |= HT_CAP_INFO_DELAYED_BA;
1037 [ - + ]: 12 : if (os_strstr(capab, "[MAX-AMSDU-7935]"))
1038 : 0 : conf->ht_capab |= HT_CAP_INFO_MAX_AMSDU_SIZE;
1039 [ - + ]: 12 : if (os_strstr(capab, "[DSSS_CCK-40]"))
1040 : 0 : conf->ht_capab |= HT_CAP_INFO_DSSS_CCK40MHZ;
1041 [ - + ]: 12 : if (os_strstr(capab, "[PSMP]"))
1042 : 0 : conf->ht_capab |= HT_CAP_INFO_PSMP_SUPP;
1043 [ - + ]: 12 : if (os_strstr(capab, "[LSIG-TXOP-PROT]"))
1044 : 0 : conf->ht_capab |= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT;
1045 : :
1046 : 12 : return 0;
1047 : : }
1048 : : #endif /* CONFIG_IEEE80211N */
1049 : :
1050 : :
1051 : : #ifdef CONFIG_IEEE80211AC
1052 : 0 : static int hostapd_config_vht_capab(struct hostapd_config *conf,
1053 : : const char *capab)
1054 : : {
1055 [ # # ]: 0 : if (os_strstr(capab, "[MAX-MPDU-7991]"))
1056 : 0 : conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_7991;
1057 [ # # ]: 0 : if (os_strstr(capab, "[MAX-MPDU-11454]"))
1058 : 0 : conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_11454;
1059 [ # # ]: 0 : if (os_strstr(capab, "[VHT160]"))
1060 : 0 : conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1061 [ # # ]: 0 : if (os_strstr(capab, "[VHT160-80PLUS80]"))
1062 : 0 : conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1063 [ # # ]: 0 : if (os_strstr(capab, "[VHT160-80PLUS80]"))
1064 : 0 : conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1065 [ # # ]: 0 : if (os_strstr(capab, "[RXLDPC]"))
1066 : 0 : conf->vht_capab |= VHT_CAP_RXLDPC;
1067 [ # # ]: 0 : if (os_strstr(capab, "[SHORT-GI-80]"))
1068 : 0 : conf->vht_capab |= VHT_CAP_SHORT_GI_80;
1069 [ # # ]: 0 : if (os_strstr(capab, "[SHORT-GI-160]"))
1070 : 0 : conf->vht_capab |= VHT_CAP_SHORT_GI_160;
1071 [ # # ]: 0 : if (os_strstr(capab, "[TX-STBC-2BY1]"))
1072 : 0 : conf->vht_capab |= VHT_CAP_TXSTBC;
1073 [ # # ]: 0 : if (os_strstr(capab, "[RX-STBC-1]"))
1074 : 0 : conf->vht_capab |= VHT_CAP_RXSTBC_1;
1075 [ # # ]: 0 : if (os_strstr(capab, "[RX-STBC-12]"))
1076 : 0 : conf->vht_capab |= VHT_CAP_RXSTBC_2;
1077 [ # # ]: 0 : if (os_strstr(capab, "[RX-STBC-123]"))
1078 : 0 : conf->vht_capab |= VHT_CAP_RXSTBC_3;
1079 [ # # ]: 0 : if (os_strstr(capab, "[RX-STBC-1234]"))
1080 : 0 : conf->vht_capab |= VHT_CAP_RXSTBC_4;
1081 [ # # ]: 0 : if (os_strstr(capab, "[SU-BEAMFORMER]"))
1082 : 0 : conf->vht_capab |= VHT_CAP_SU_BEAMFORMER_CAPABLE;
1083 [ # # ]: 0 : if (os_strstr(capab, "[SU-BEAMFORMEE]"))
1084 : 0 : conf->vht_capab |= VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1085 [ # # ][ # # ]: 0 : if (os_strstr(capab, "[BF-ANTENNA-2]") &&
1086 : 0 : (conf->vht_capab & VHT_CAP_SU_BEAMFORMEE_CAPABLE))
1087 : 0 : conf->vht_capab |= (1 << VHT_CAP_BEAMFORMEE_STS_OFFSET);
1088 [ # # ][ # # ]: 0 : if (os_strstr(capab, "[SOUNDING-DIMENSION-2]") &&
1089 : 0 : (conf->vht_capab & VHT_CAP_SU_BEAMFORMER_CAPABLE))
1090 : 0 : conf->vht_capab |= (1 << VHT_CAP_SOUNDING_DIMENSION_OFFSET);
1091 [ # # ]: 0 : if (os_strstr(capab, "[MU-BEAMFORMER]"))
1092 : 0 : conf->vht_capab |= VHT_CAP_MU_BEAMFORMER_CAPABLE;
1093 [ # # ]: 0 : if (os_strstr(capab, "[MU-BEAMFORMEE]"))
1094 : 0 : conf->vht_capab |= VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1095 [ # # ]: 0 : if (os_strstr(capab, "[VHT-TXOP-PS]"))
1096 : 0 : conf->vht_capab |= VHT_CAP_VHT_TXOP_PS;
1097 [ # # ]: 0 : if (os_strstr(capab, "[HTC-VHT]"))
1098 : 0 : conf->vht_capab |= VHT_CAP_HTC_VHT;
1099 [ # # ]: 0 : if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP0]"))
1100 : 0 : conf->vht_capab |= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
1101 [ # # ][ # # ]: 0 : if (os_strstr(capab, "[VHT-LINK-ADAPT2]") &&
1102 : 0 : (conf->vht_capab & VHT_CAP_HTC_VHT))
1103 : 0 : conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB;
1104 [ # # ][ # # ]: 0 : if (os_strstr(capab, "[VHT-LINK-ADAPT3]") &&
1105 : 0 : (conf->vht_capab & VHT_CAP_HTC_VHT))
1106 : 0 : conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
1107 [ # # ]: 0 : if (os_strstr(capab, "[RX-ANTENNA-PATTERN]"))
1108 : 0 : conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN;
1109 [ # # ]: 0 : if (os_strstr(capab, "[TX-ANTENNA-PATTERN]"))
1110 : 0 : conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN;
1111 : 0 : return 0;
1112 : : }
1113 : : #endif /* CONFIG_IEEE80211AC */
1114 : :
1115 : :
1116 : : #ifdef CONFIG_INTERWORKING
1117 : 363 : static int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos,
1118 : : int line)
1119 : : {
1120 : 363 : size_t len = os_strlen(pos);
1121 : : u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
1122 : :
1123 : : struct hostapd_roaming_consortium *rc;
1124 : :
1125 [ + - ][ + - ]: 726 : if ((len & 1) || len < 2 * 3 || len / 2 > MAX_ROAMING_CONSORTIUM_LEN ||
[ + - - + ]
1126 : 363 : hexstr2bin(pos, oi, len / 2)) {
1127 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid roaming_consortium "
1128 : : "'%s'", line, pos);
1129 : 0 : return -1;
1130 : : }
1131 : 363 : len /= 2;
1132 : :
1133 : 363 : rc = os_realloc_array(bss->roaming_consortium,
1134 : 363 : bss->roaming_consortium_count + 1,
1135 : : sizeof(struct hostapd_roaming_consortium));
1136 [ - + ]: 363 : if (rc == NULL)
1137 : 0 : return -1;
1138 : :
1139 : 363 : os_memcpy(rc[bss->roaming_consortium_count].oi, oi, len);
1140 : 363 : rc[bss->roaming_consortium_count].len = len;
1141 : :
1142 : 363 : bss->roaming_consortium = rc;
1143 : 363 : bss->roaming_consortium_count++;
1144 : :
1145 : 363 : return 0;
1146 : : }
1147 : :
1148 : :
1149 : 218 : static int parse_lang_string(struct hostapd_lang_string **array,
1150 : : unsigned int *count, char *pos)
1151 : : {
1152 : 218 : char *sep, *str = NULL;
1153 : : size_t clen, nlen, slen;
1154 : : struct hostapd_lang_string *ls;
1155 : 218 : int ret = -1;
1156 : :
1157 [ + - ][ - + ]: 218 : if (*pos == '"' || (*pos == 'P' && pos[1] == '"')) {
[ # # ]
1158 : 0 : str = wpa_config_parse_string(pos, &slen);
1159 [ # # ]: 0 : if (!str)
1160 : 0 : return -1;
1161 : 0 : pos = str;
1162 : : }
1163 : :
1164 : 218 : sep = os_strchr(pos, ':');
1165 [ - + ]: 218 : if (sep == NULL)
1166 : 0 : goto fail;
1167 : 218 : *sep++ = '\0';
1168 : :
1169 : 218 : clen = os_strlen(pos);
1170 [ + - ][ + - ]: 218 : if (clen < 2 || clen > sizeof(ls->lang))
1171 : : goto fail;
1172 : 218 : nlen = os_strlen(sep);
1173 [ - + ]: 218 : if (nlen > 252)
1174 : 0 : goto fail;
1175 : :
1176 : 218 : ls = os_realloc_array(*array, *count + 1,
1177 : : sizeof(struct hostapd_lang_string));
1178 [ - + ]: 218 : if (ls == NULL)
1179 : 0 : goto fail;
1180 : :
1181 : 218 : *array = ls;
1182 : 218 : ls = &(*array)[*count];
1183 : 218 : (*count)++;
1184 : :
1185 : 218 : os_memset(ls->lang, 0, sizeof(ls->lang));
1186 : 218 : os_memcpy(ls->lang, pos, clen);
1187 : 218 : ls->name_len = nlen;
1188 : 218 : os_memcpy(ls->name, sep, nlen);
1189 : :
1190 : 218 : ret = 0;
1191 : : fail:
1192 : 218 : os_free(str);
1193 : 218 : return ret;
1194 : : }
1195 : :
1196 : :
1197 : 186 : static int parse_venue_name(struct hostapd_bss_config *bss, char *pos,
1198 : : int line)
1199 : : {
1200 [ - + ]: 186 : if (parse_lang_string(&bss->venue_name, &bss->venue_name_count, pos)) {
1201 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid venue_name '%s'",
1202 : : line, pos);
1203 : 0 : return -1;
1204 : : }
1205 : 186 : return 0;
1206 : : }
1207 : :
1208 : :
1209 : 92 : static int parse_3gpp_cell_net(struct hostapd_bss_config *bss, char *buf,
1210 : : int line)
1211 : : {
1212 : : size_t count;
1213 : : char *pos;
1214 : 92 : u8 *info = NULL, *ipos;
1215 : :
1216 : : /* format: <MCC1,MNC1>[;<MCC2,MNC2>][;...] */
1217 : :
1218 : 92 : count = 1;
1219 [ + + ]: 672 : for (pos = buf; *pos; pos++) {
1220 [ + + ][ - + ]: 580 : if ((*pos < '0' && *pos > '9') && *pos != ';' && *pos != ',')
[ # # ][ # # ]
1221 : 0 : goto fail;
1222 [ + + ]: 580 : if (*pos == ';')
1223 : 3 : count++;
1224 : : }
1225 [ - + ]: 92 : if (1 + count * 3 > 0x7f)
1226 : 0 : goto fail;
1227 : :
1228 : 92 : info = os_zalloc(2 + 3 + count * 3);
1229 [ - + ]: 92 : if (info == NULL)
1230 : 0 : return -1;
1231 : :
1232 : 92 : ipos = info;
1233 : 92 : *ipos++ = 0; /* GUD - Version 1 */
1234 : 92 : *ipos++ = 3 + count * 3; /* User Data Header Length (UDHL) */
1235 : 92 : *ipos++ = 0; /* PLMN List IEI */
1236 : : /* ext(b8) | Length of PLMN List value contents(b7..1) */
1237 : 92 : *ipos++ = 1 + count * 3;
1238 : 92 : *ipos++ = count; /* Number of PLMNs */
1239 : :
1240 : 92 : pos = buf;
1241 [ + + ][ + - ]: 187 : while (pos && *pos) {
1242 : : char *mcc, *mnc;
1243 : : size_t mnc_len;
1244 : :
1245 : 95 : mcc = pos;
1246 : 95 : mnc = os_strchr(pos, ',');
1247 [ - + ]: 95 : if (mnc == NULL)
1248 : 0 : goto fail;
1249 : 95 : *mnc++ = '\0';
1250 : 95 : pos = os_strchr(mnc, ';');
1251 [ + + ]: 95 : if (pos)
1252 : 3 : *pos++ = '\0';
1253 : :
1254 : 95 : mnc_len = os_strlen(mnc);
1255 [ + - ][ + + ]: 95 : if (os_strlen(mcc) != 3 || (mnc_len != 2 && mnc_len != 3))
[ + - ]
1256 : : goto fail;
1257 : :
1258 : : /* BC coded MCC,MNC */
1259 : : /* MCC digit 2 | MCC digit 1 */
1260 : 95 : *ipos++ = ((mcc[1] - '0') << 4) | (mcc[0] - '0');
1261 : : /* MNC digit 3 | MCC digit 3 */
1262 [ + + ]: 95 : *ipos++ = (((mnc_len == 2) ? 0xf0 : ((mnc[2] - '0') << 4))) |
1263 : 95 : (mcc[2] - '0');
1264 : : /* MNC digit 2 | MNC digit 1 */
1265 : 95 : *ipos++ = ((mnc[1] - '0') << 4) | (mnc[0] - '0');
1266 : : }
1267 : :
1268 : 92 : os_free(bss->anqp_3gpp_cell_net);
1269 : 92 : bss->anqp_3gpp_cell_net = info;
1270 : 92 : bss->anqp_3gpp_cell_net_len = 2 + 3 + 3 * count;
1271 : 92 : wpa_hexdump(MSG_MSGDUMP, "3GPP Cellular Network information",
1272 : 92 : bss->anqp_3gpp_cell_net, bss->anqp_3gpp_cell_net_len);
1273 : :
1274 : 92 : return 0;
1275 : :
1276 : : fail:
1277 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid anqp_3gpp_cell_net: %s",
1278 : : line, buf);
1279 : 0 : os_free(info);
1280 : 92 : return -1;
1281 : : }
1282 : :
1283 : :
1284 : 162 : static int parse_nai_realm(struct hostapd_bss_config *bss, char *buf, int line)
1285 : : {
1286 : : struct hostapd_nai_realm_data *realm;
1287 : : size_t i, j, len;
1288 : : int *offsets;
1289 : : char *pos, *end, *rpos;
1290 : :
1291 : 162 : offsets = os_calloc(bss->nai_realm_count * MAX_NAI_REALMS,
1292 : : sizeof(int));
1293 [ - + ]: 162 : if (offsets == NULL)
1294 : 0 : return -1;
1295 : :
1296 [ + + ]: 233 : for (i = 0; i < bss->nai_realm_count; i++) {
1297 : 71 : realm = &bss->nai_realm_data[i];
1298 [ + + ]: 781 : for (j = 0; j < MAX_NAI_REALMS; j++) {
1299 [ + + ]: 710 : offsets[i * MAX_NAI_REALMS + j] =
1300 : 710 : realm->realm[j] ?
1301 : 71 : realm->realm[j] - realm->realm_buf : -1;
1302 : : }
1303 : : }
1304 : :
1305 : 162 : realm = os_realloc_array(bss->nai_realm_data, bss->nai_realm_count + 1,
1306 : : sizeof(struct hostapd_nai_realm_data));
1307 [ - + ]: 162 : if (realm == NULL) {
1308 : 0 : os_free(offsets);
1309 : 0 : return -1;
1310 : : }
1311 : 162 : bss->nai_realm_data = realm;
1312 : :
1313 : : /* patch the pointers after realloc */
1314 [ + + ]: 233 : for (i = 0; i < bss->nai_realm_count; i++) {
1315 : 71 : realm = &bss->nai_realm_data[i];
1316 [ + + ]: 781 : for (j = 0; j < MAX_NAI_REALMS; j++) {
1317 : 710 : int offs = offsets[i * MAX_NAI_REALMS + j];
1318 [ + + ]: 710 : if (offs >= 0)
1319 : 71 : realm->realm[j] = realm->realm_buf + offs;
1320 : : else
1321 : 639 : realm->realm[j] = NULL;
1322 : : }
1323 : : }
1324 : 162 : os_free(offsets);
1325 : :
1326 : 162 : realm = &bss->nai_realm_data[bss->nai_realm_count];
1327 : 162 : os_memset(realm, 0, sizeof(*realm));
1328 : :
1329 : 162 : pos = buf;
1330 : 162 : realm->encoding = atoi(pos);
1331 : 162 : pos = os_strchr(pos, ',');
1332 [ - + ]: 162 : if (pos == NULL)
1333 : 0 : goto fail;
1334 : 162 : pos++;
1335 : :
1336 : 162 : end = os_strchr(pos, ',');
1337 [ + + ]: 162 : if (end) {
1338 : 93 : len = end - pos;
1339 : 93 : *end = '\0';
1340 : : } else {
1341 : 69 : len = os_strlen(pos);
1342 : : }
1343 : :
1344 [ - + ]: 162 : if (len > MAX_NAI_REALMLEN) {
1345 : 0 : wpa_printf(MSG_ERROR, "Too long a realm string (%d > max %d "
1346 : : "characters)", (int) len, MAX_NAI_REALMLEN);
1347 : 0 : goto fail;
1348 : : }
1349 : 162 : os_memcpy(realm->realm_buf, pos, len);
1350 : :
1351 [ + + ]: 162 : if (end)
1352 : 93 : pos = end + 1;
1353 : : else
1354 : 69 : pos = NULL;
1355 : :
1356 [ + + ][ + - ]: 234 : while (pos && *pos) {
1357 : : struct hostapd_nai_realm_eap *eap;
1358 : :
1359 [ - + ]: 165 : if (realm->eap_method_count >= MAX_NAI_EAP_METHODS) {
1360 : 0 : wpa_printf(MSG_ERROR, "Too many EAP methods");
1361 : 0 : goto fail;
1362 : : }
1363 : :
1364 : 165 : eap = &realm->eap_method[realm->eap_method_count];
1365 : 165 : realm->eap_method_count++;
1366 : :
1367 : 165 : end = os_strchr(pos, ',');
1368 [ + + ]: 165 : if (end == NULL)
1369 : 93 : end = pos + os_strlen(pos);
1370 : :
1371 : 165 : eap->eap_method = atoi(pos);
1372 : : for (;;) {
1373 : 403 : pos = os_strchr(pos, '[');
1374 [ + + ][ + + ]: 403 : if (pos == NULL || pos > end)
1375 : : break;
1376 : 238 : pos++;
1377 [ - + ]: 238 : if (eap->num_auths >= MAX_NAI_AUTH_TYPES) {
1378 : 0 : wpa_printf(MSG_ERROR, "Too many auth params");
1379 : 0 : goto fail;
1380 : : }
1381 : 238 : eap->auth_id[eap->num_auths] = atoi(pos);
1382 : 238 : pos = os_strchr(pos, ':');
1383 [ + - ][ + - ]: 238 : if (pos == NULL || pos > end)
1384 : : goto fail;
1385 : 238 : pos++;
1386 : 238 : eap->auth_val[eap->num_auths] = atoi(pos);
1387 : 238 : pos = os_strchr(pos, ']');
1388 [ + - ][ + - ]: 238 : if (pos == NULL || pos > end)
1389 : : goto fail;
1390 : 238 : pos++;
1391 : 238 : eap->num_auths++;
1392 : 238 : }
1393 : :
1394 [ + + ]: 165 : if (*end != ',')
1395 : 93 : break;
1396 : :
1397 : 72 : pos = end + 1;
1398 : : }
1399 : :
1400 : : /* Split realm list into null terminated realms */
1401 : 162 : rpos = realm->realm_buf;
1402 : 162 : i = 0;
1403 [ + - ]: 164 : while (*rpos) {
1404 [ - + ]: 164 : if (i >= MAX_NAI_REALMS) {
1405 : 0 : wpa_printf(MSG_ERROR, "Too many realms");
1406 : 0 : goto fail;
1407 : : }
1408 : 164 : realm->realm[i++] = rpos;
1409 : 164 : rpos = os_strchr(rpos, ';');
1410 [ + + ]: 164 : if (rpos == NULL)
1411 : 162 : break;
1412 : 2 : *rpos++ = '\0';
1413 : : }
1414 : :
1415 : 162 : bss->nai_realm_count++;
1416 : :
1417 : 162 : return 0;
1418 : :
1419 : : fail:
1420 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid nai_realm '%s'", line, buf);
1421 : 162 : return -1;
1422 : : }
1423 : :
1424 : :
1425 : 1 : static int parse_qos_map_set(struct hostapd_bss_config *bss,
1426 : : char *buf, int line)
1427 : : {
1428 : 1 : u8 qos_map_set[16 + 2 * 21], count = 0;
1429 : 1 : char *pos = buf;
1430 : : int val;
1431 : :
1432 : : for (;;) {
1433 [ - + ]: 20 : if (count == sizeof(qos_map_set)) {
1434 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too many qos_map_set "
1435 : : "parameters '%s'", line, buf);
1436 : 0 : return -1;
1437 : : }
1438 : :
1439 : 20 : val = atoi(pos);
1440 [ - + ][ + - ]: 20 : if (val > 255 || val < 0) {
1441 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid qos_map_set "
1442 : : "'%s'", line, buf);
1443 : 0 : return -1;
1444 : : }
1445 : :
1446 : 20 : qos_map_set[count++] = val;
1447 : 20 : pos = os_strchr(pos, ',');
1448 [ + + ]: 20 : if (!pos)
1449 : 1 : break;
1450 : 19 : pos++;
1451 : 19 : }
1452 : :
1453 [ + - ][ - + ]: 1 : if (count < 16 || count & 1) {
1454 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid qos_map_set '%s'",
1455 : : line, buf);
1456 : 0 : return -1;
1457 : : }
1458 : :
1459 : 1 : os_memcpy(bss->qos_map_set, qos_map_set, count);
1460 : 1 : bss->qos_map_set_len = count;
1461 : :
1462 : 1 : return 0;
1463 : : }
1464 : :
1465 : : #endif /* CONFIG_INTERWORKING */
1466 : :
1467 : :
1468 : : #ifdef CONFIG_HS20
1469 : 281 : static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
1470 : : int line)
1471 : : {
1472 : : u8 *conn_cap;
1473 : : char *pos;
1474 : :
1475 [ - + ]: 281 : if (bss->hs20_connection_capability_len >= 0xfff0)
1476 : 0 : return -1;
1477 : :
1478 : 281 : conn_cap = os_realloc(bss->hs20_connection_capability,
1479 : 281 : bss->hs20_connection_capability_len + 4);
1480 [ - + ]: 281 : if (conn_cap == NULL)
1481 : 0 : return -1;
1482 : :
1483 : 281 : bss->hs20_connection_capability = conn_cap;
1484 : 281 : conn_cap += bss->hs20_connection_capability_len;
1485 : 281 : pos = buf;
1486 : 281 : conn_cap[0] = atoi(pos);
1487 : 281 : pos = os_strchr(pos, ':');
1488 [ - + ]: 281 : if (pos == NULL)
1489 : 0 : return -1;
1490 : 281 : pos++;
1491 : 281 : WPA_PUT_LE16(conn_cap + 1, atoi(pos));
1492 : 281 : pos = os_strchr(pos, ':');
1493 [ - + ]: 281 : if (pos == NULL)
1494 : 0 : return -1;
1495 : 281 : pos++;
1496 : 281 : conn_cap[3] = atoi(pos);
1497 : 281 : bss->hs20_connection_capability_len += 4;
1498 : :
1499 : 281 : return 0;
1500 : : }
1501 : :
1502 : :
1503 : 92 : static int hs20_parse_wan_metrics(struct hostapd_bss_config *bss, char *buf,
1504 : : int line)
1505 : : {
1506 : : u8 *wan_metrics;
1507 : : char *pos;
1508 : :
1509 : : /* <WAN Info>:<DL Speed>:<UL Speed>:<DL Load>:<UL Load>:<LMD> */
1510 : :
1511 : 92 : wan_metrics = os_zalloc(13);
1512 [ - + ]: 92 : if (wan_metrics == NULL)
1513 : 0 : return -1;
1514 : :
1515 : 92 : pos = buf;
1516 : : /* WAN Info */
1517 [ - + ]: 92 : if (hexstr2bin(pos, wan_metrics, 1) < 0)
1518 : 0 : goto fail;
1519 : 92 : pos += 2;
1520 [ - + ]: 92 : if (*pos != ':')
1521 : 0 : goto fail;
1522 : 92 : pos++;
1523 : :
1524 : : /* Downlink Speed */
1525 : 92 : WPA_PUT_LE32(wan_metrics + 1, atoi(pos));
1526 : 92 : pos = os_strchr(pos, ':');
1527 [ - + ]: 92 : if (pos == NULL)
1528 : 0 : goto fail;
1529 : 92 : pos++;
1530 : :
1531 : : /* Uplink Speed */
1532 : 92 : WPA_PUT_LE32(wan_metrics + 5, atoi(pos));
1533 : 92 : pos = os_strchr(pos, ':');
1534 [ - + ]: 92 : if (pos == NULL)
1535 : 0 : goto fail;
1536 : 92 : pos++;
1537 : :
1538 : : /* Downlink Load */
1539 : 92 : wan_metrics[9] = atoi(pos);
1540 : 92 : pos = os_strchr(pos, ':');
1541 [ - + ]: 92 : if (pos == NULL)
1542 : 0 : goto fail;
1543 : 92 : pos++;
1544 : :
1545 : : /* Uplink Load */
1546 : 92 : wan_metrics[10] = atoi(pos);
1547 : 92 : pos = os_strchr(pos, ':');
1548 [ - + ]: 92 : if (pos == NULL)
1549 : 0 : goto fail;
1550 : 92 : pos++;
1551 : :
1552 : : /* LMD */
1553 : 92 : WPA_PUT_LE16(wan_metrics + 11, atoi(pos));
1554 : :
1555 : 92 : os_free(bss->hs20_wan_metrics);
1556 : 92 : bss->hs20_wan_metrics = wan_metrics;
1557 : :
1558 : 92 : return 0;
1559 : :
1560 : : fail:
1561 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid hs20_wan_metrics '%s'",
1562 : : line, pos);
1563 : 0 : os_free(wan_metrics);
1564 : 92 : return -1;
1565 : : }
1566 : :
1567 : :
1568 : 24 : static int hs20_parse_oper_friendly_name(struct hostapd_bss_config *bss,
1569 : : char *pos, int line)
1570 : : {
1571 [ - + ]: 24 : if (parse_lang_string(&bss->hs20_oper_friendly_name,
1572 : : &bss->hs20_oper_friendly_name_count, pos)) {
1573 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
1574 : : "hs20_oper_friendly_name '%s'", line, pos);
1575 : 0 : return -1;
1576 : : }
1577 : 24 : return 0;
1578 : : }
1579 : :
1580 : :
1581 : 2 : static int hs20_parse_icon(struct hostapd_bss_config *bss, char *pos)
1582 : : {
1583 : : struct hs20_icon *icon;
1584 : : char *end;
1585 : :
1586 : 2 : icon = os_realloc_array(bss->hs20_icons, bss->hs20_icons_count + 1,
1587 : : sizeof(struct hs20_icon));
1588 [ - + ]: 2 : if (icon == NULL)
1589 : 0 : return -1;
1590 : 2 : bss->hs20_icons = icon;
1591 : 2 : icon = &bss->hs20_icons[bss->hs20_icons_count];
1592 : 2 : os_memset(icon, 0, sizeof(*icon));
1593 : :
1594 : 2 : icon->width = atoi(pos);
1595 : 2 : pos = os_strchr(pos, ':');
1596 [ - + ]: 2 : if (pos == NULL)
1597 : 0 : return -1;
1598 : 2 : pos++;
1599 : :
1600 : 2 : icon->height = atoi(pos);
1601 : 2 : pos = os_strchr(pos, ':');
1602 [ - + ]: 2 : if (pos == NULL)
1603 : 0 : return -1;
1604 : 2 : pos++;
1605 : :
1606 : 2 : end = os_strchr(pos, ':');
1607 [ + - ][ - + ]: 2 : if (end == NULL || end - pos > 3)
1608 : 0 : return -1;
1609 : 2 : os_memcpy(icon->language, pos, end - pos);
1610 : 2 : pos = end + 1;
1611 : :
1612 : 2 : end = os_strchr(pos, ':');
1613 [ + - ][ - + ]: 2 : if (end == NULL || end - pos > 255)
1614 : 0 : return -1;
1615 : 2 : os_memcpy(icon->type, pos, end - pos);
1616 : 2 : pos = end + 1;
1617 : :
1618 : 2 : end = os_strchr(pos, ':');
1619 [ + - ][ - + ]: 2 : if (end == NULL || end - pos > 255)
1620 : 0 : return -1;
1621 : 2 : os_memcpy(icon->name, pos, end - pos);
1622 : 2 : pos = end + 1;
1623 : :
1624 [ - + ]: 2 : if (os_strlen(pos) > 255)
1625 : 0 : return -1;
1626 : 2 : os_memcpy(icon->file, pos, os_strlen(pos));
1627 : :
1628 : 2 : bss->hs20_icons_count++;
1629 : :
1630 : 2 : return 0;
1631 : : }
1632 : :
1633 : :
1634 : 2 : static int hs20_parse_osu_ssid(struct hostapd_bss_config *bss,
1635 : : char *pos, int line)
1636 : : {
1637 : : size_t slen;
1638 : : char *str;
1639 : :
1640 : 2 : str = wpa_config_parse_string(pos, &slen);
1641 [ + - ][ - + ]: 2 : if (str == NULL || slen < 1 || slen > HOSTAPD_MAX_SSID_LEN) {
[ + - ]
1642 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid SSID '%s'", line, pos);
1643 : 0 : return -1;
1644 : : }
1645 : :
1646 : 2 : os_memcpy(bss->osu_ssid, str, slen);
1647 : 2 : bss->osu_ssid_len = slen;
1648 : 2 : os_free(str);
1649 : :
1650 : 2 : return 0;
1651 : : }
1652 : :
1653 : :
1654 : 2 : static int hs20_parse_osu_server_uri(struct hostapd_bss_config *bss,
1655 : : char *pos, int line)
1656 : : {
1657 : : struct hs20_osu_provider *p;
1658 : :
1659 : 2 : p = os_realloc_array(bss->hs20_osu_providers,
1660 : 2 : bss->hs20_osu_providers_count + 1, sizeof(*p));
1661 [ - + ]: 2 : if (p == NULL)
1662 : 0 : return -1;
1663 : :
1664 : 2 : bss->hs20_osu_providers = p;
1665 : 2 : bss->last_osu = &bss->hs20_osu_providers[bss->hs20_osu_providers_count];
1666 : 2 : bss->hs20_osu_providers_count++;
1667 : 2 : os_memset(bss->last_osu, 0, sizeof(*p));
1668 : 2 : bss->last_osu->server_uri = os_strdup(pos);
1669 : :
1670 : 2 : return 0;
1671 : : }
1672 : :
1673 : :
1674 : 4 : static int hs20_parse_osu_friendly_name(struct hostapd_bss_config *bss,
1675 : : char *pos, int line)
1676 : : {
1677 [ - + ]: 4 : if (bss->last_osu == NULL) {
1678 : 0 : wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line);
1679 : 0 : return -1;
1680 : : }
1681 : :
1682 [ - + ]: 4 : if (parse_lang_string(&bss->last_osu->friendly_name,
1683 : 4 : &bss->last_osu->friendly_name_count, pos)) {
1684 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid osu_friendly_name '%s'",
1685 : : line, pos);
1686 : 0 : return -1;
1687 : : }
1688 : :
1689 : 4 : return 0;
1690 : : }
1691 : :
1692 : :
1693 : 0 : static int hs20_parse_osu_nai(struct hostapd_bss_config *bss,
1694 : : char *pos, int line)
1695 : : {
1696 [ # # ]: 0 : if (bss->last_osu == NULL) {
1697 : 0 : wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line);
1698 : 0 : return -1;
1699 : : }
1700 : :
1701 : 0 : os_free(bss->last_osu->osu_nai);
1702 : 0 : bss->last_osu->osu_nai = os_strdup(pos);
1703 [ # # ]: 0 : if (bss->last_osu->osu_nai == NULL)
1704 : 0 : return -1;
1705 : :
1706 : 0 : return 0;
1707 : : }
1708 : :
1709 : :
1710 : 2 : static int hs20_parse_osu_method_list(struct hostapd_bss_config *bss, char *pos,
1711 : : int line)
1712 : : {
1713 [ - + ]: 2 : if (bss->last_osu == NULL) {
1714 : 0 : wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line);
1715 : 0 : return -1;
1716 : : }
1717 : :
1718 [ - + ]: 2 : if (hostapd_parse_intlist(&bss->last_osu->method_list, pos)) {
1719 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid osu_method_list", line);
1720 : 0 : return -1;
1721 : : }
1722 : :
1723 : 2 : return 0;
1724 : : }
1725 : :
1726 : :
1727 : 2 : static int hs20_parse_osu_icon(struct hostapd_bss_config *bss, char *pos,
1728 : : int line)
1729 : : {
1730 : : char **n;
1731 : 2 : struct hs20_osu_provider *p = bss->last_osu;
1732 : :
1733 [ - + ]: 2 : if (p == NULL) {
1734 : 0 : wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line);
1735 : 0 : return -1;
1736 : : }
1737 : :
1738 : 2 : n = os_realloc_array(p->icons, p->icons_count + 1, sizeof(char *));
1739 [ - + ]: 2 : if (n == NULL)
1740 : 0 : return -1;
1741 : 2 : p->icons = n;
1742 : 2 : p->icons[p->icons_count] = os_strdup(pos);
1743 [ - + ]: 2 : if (p->icons[p->icons_count] == NULL)
1744 : 0 : return -1;
1745 : 2 : p->icons_count++;
1746 : :
1747 : 2 : return 0;
1748 : : }
1749 : :
1750 : :
1751 : 4 : static int hs20_parse_osu_service_desc(struct hostapd_bss_config *bss,
1752 : : char *pos, int line)
1753 : : {
1754 [ - + ]: 4 : if (bss->last_osu == NULL) {
1755 : 0 : wpa_printf(MSG_ERROR, "Line %d: Unexpected OSU field", line);
1756 : 0 : return -1;
1757 : : }
1758 : :
1759 [ - + ]: 4 : if (parse_lang_string(&bss->last_osu->service_desc,
1760 : 4 : &bss->last_osu->service_desc_count, pos)) {
1761 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid osu_service_desc '%s'",
1762 : : line, pos);
1763 : 0 : return -1;
1764 : : }
1765 : :
1766 : 4 : return 0;
1767 : : }
1768 : :
1769 : : #endif /* CONFIG_HS20 */
1770 : :
1771 : :
1772 : : #ifdef CONFIG_WPS_NFC
1773 : 0 : static struct wpabuf * hostapd_parse_bin(const char *buf)
1774 : : {
1775 : : size_t len;
1776 : : struct wpabuf *ret;
1777 : :
1778 : 0 : len = os_strlen(buf);
1779 [ # # ]: 0 : if (len & 0x01)
1780 : 0 : return NULL;
1781 : 0 : len /= 2;
1782 : :
1783 : 0 : ret = wpabuf_alloc(len);
1784 [ # # ]: 0 : if (ret == NULL)
1785 : 0 : return NULL;
1786 : :
1787 [ # # ]: 0 : if (hexstr2bin(buf, wpabuf_put(ret, len), len)) {
1788 : 0 : wpabuf_free(ret);
1789 : 0 : return NULL;
1790 : : }
1791 : :
1792 : 0 : return ret;
1793 : : }
1794 : : #endif /* CONFIG_WPS_NFC */
1795 : :
1796 : :
1797 : 7053 : static int hostapd_config_fill(struct hostapd_config *conf,
1798 : : struct hostapd_bss_config *bss,
1799 : : char *buf, char *pos, int line)
1800 : : {
1801 : 7053 : int errors = 0;
1802 : :
1803 : : {
1804 [ + + ]: 7053 : if (os_strcmp(buf, "interface") == 0) {
1805 : 24 : os_strlcpy(conf->bss[0]->iface, pos,
1806 : : sizeof(conf->bss[0]->iface));
1807 [ - + ]: 7029 : } else if (os_strcmp(buf, "bridge") == 0) {
1808 : 0 : os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
1809 [ - + ]: 7029 : } else if (os_strcmp(buf, "vlan_bridge") == 0) {
1810 : 0 : os_strlcpy(bss->vlan_bridge, pos,
1811 : : sizeof(bss->vlan_bridge));
1812 [ - + ]: 7029 : } else if (os_strcmp(buf, "wds_bridge") == 0) {
1813 : 0 : os_strlcpy(bss->wds_bridge, pos,
1814 : : sizeof(bss->wds_bridge));
1815 [ + + ]: 7029 : } else if (os_strcmp(buf, "driver") == 0) {
1816 : : int j;
1817 : : /* clear to get error below if setting is invalid */
1818 : 346 : conf->driver = NULL;
1819 [ + - ]: 348 : for (j = 0; wpa_drivers[j]; j++) {
1820 [ + + ]: 348 : if (os_strcmp(pos, wpa_drivers[j]->name) == 0)
1821 : : {
1822 : 346 : conf->driver = wpa_drivers[j];
1823 : 346 : break;
1824 : : }
1825 : : }
1826 [ - + ]: 346 : if (conf->driver == NULL) {
1827 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid/"
1828 : : "unknown driver '%s'", line, pos);
1829 : 0 : errors++;
1830 : : }
1831 [ - + ]: 6683 : } else if (os_strcmp(buf, "debug") == 0) {
1832 : 0 : wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' "
1833 : : "configuration variable is not used "
1834 : : "anymore", line);
1835 [ - + ]: 6683 : } else if (os_strcmp(buf, "logger_syslog_level") == 0) {
1836 : 0 : bss->logger_syslog_level = atoi(pos);
1837 [ + + ]: 6683 : } else if (os_strcmp(buf, "logger_stdout_level") == 0) {
1838 : 322 : bss->logger_stdout_level = atoi(pos);
1839 [ - + ]: 6361 : } else if (os_strcmp(buf, "logger_syslog") == 0) {
1840 : 0 : bss->logger_syslog = atoi(pos);
1841 [ + + ]: 6361 : } else if (os_strcmp(buf, "logger_stdout") == 0) {
1842 : 322 : bss->logger_stdout = atoi(pos);
1843 [ - + ]: 6039 : } else if (os_strcmp(buf, "dump_file") == 0) {
1844 : 0 : wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
1845 : : line);
1846 [ + + ]: 6039 : } else if (os_strcmp(buf, "ssid") == 0) {
1847 : 354 : bss->ssid.ssid_len = os_strlen(pos);
1848 [ + - ][ - + ]: 354 : if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
1849 : 354 : bss->ssid.ssid_len < 1) {
1850 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
1851 : : "'%s'", line, pos);
1852 : 0 : errors++;
1853 : : } else {
1854 : 354 : os_memcpy(bss->ssid.ssid, pos,
1855 : : bss->ssid.ssid_len);
1856 : 354 : bss->ssid.ssid_set = 1;
1857 : : }
1858 [ + + ]: 5685 : } else if (os_strcmp(buf, "ssid2") == 0) {
1859 : : size_t slen;
1860 : 2 : char *str = wpa_config_parse_string(pos, &slen);
1861 [ + - ][ - + ]: 2 : if (str == NULL || slen < 1 ||
[ + - ]
1862 : 2 : slen > HOSTAPD_MAX_SSID_LEN) {
1863 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
1864 : : "'%s'", line, pos);
1865 : 0 : errors++;
1866 : : } else {
1867 : 2 : os_memcpy(bss->ssid.ssid, str, slen);
1868 : 2 : bss->ssid.ssid_len = slen;
1869 : 2 : bss->ssid.ssid_set = 1;
1870 : : }
1871 : 2 : os_free(str);
1872 [ + + ]: 5683 : } else if (os_strcmp(buf, "utf8_ssid") == 0) {
1873 : 1 : bss->ssid.utf8_ssid = atoi(pos) > 0;
1874 [ - + ]: 5682 : } else if (os_strcmp(buf, "macaddr_acl") == 0) {
1875 : 0 : bss->macaddr_acl = atoi(pos);
1876 [ # # ][ # # ]: 0 : if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
1877 [ # # ]: 0 : bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
1878 : 0 : bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
1879 : 0 : wpa_printf(MSG_ERROR, "Line %d: unknown "
1880 : : "macaddr_acl %d",
1881 : 0 : line, bss->macaddr_acl);
1882 : : }
1883 [ - + ]: 5682 : } else if (os_strcmp(buf, "accept_mac_file") == 0) {
1884 [ # # ]: 0 : if (hostapd_config_read_maclist(pos, &bss->accept_mac,
1885 : : &bss->num_accept_mac))
1886 : : {
1887 : 0 : wpa_printf(MSG_ERROR, "Line %d: Failed to "
1888 : : "read accept_mac_file '%s'",
1889 : : line, pos);
1890 : 0 : errors++;
1891 : : }
1892 [ - + ]: 5682 : } else if (os_strcmp(buf, "deny_mac_file") == 0) {
1893 [ # # ]: 0 : if (hostapd_config_read_maclist(pos, &bss->deny_mac,
1894 : : &bss->num_deny_mac)) {
1895 : 0 : wpa_printf(MSG_ERROR, "Line %d: Failed to "
1896 : : "read deny_mac_file '%s'",
1897 : : line, pos);
1898 : 0 : errors++;
1899 : : }
1900 [ - + ]: 5682 : } else if (os_strcmp(buf, "wds_sta") == 0) {
1901 : 0 : bss->wds_sta = atoi(pos);
1902 [ - + ]: 5682 : } else if (os_strcmp(buf, "start_disabled") == 0) {
1903 : 0 : bss->start_disabled = atoi(pos);
1904 [ - + ]: 5682 : } else if (os_strcmp(buf, "ap_isolate") == 0) {
1905 : 0 : bss->isolate = atoi(pos);
1906 [ - + ]: 5682 : } else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
1907 : 0 : bss->ap_max_inactivity = atoi(pos);
1908 [ - + ]: 5682 : } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
1909 : 0 : bss->skip_inactivity_poll = atoi(pos);
1910 [ - + ]: 5682 : } else if (os_strcmp(buf, "country_code") == 0) {
1911 : 0 : os_memcpy(conf->country, pos, 2);
1912 : : /* FIX: make this configurable */
1913 : 0 : conf->country[2] = ' ';
1914 [ - + ]: 5682 : } else if (os_strcmp(buf, "ieee80211d") == 0) {
1915 : 0 : conf->ieee80211d = atoi(pos);
1916 [ - + ]: 5682 : } else if (os_strcmp(buf, "ieee80211h") == 0) {
1917 : 0 : conf->ieee80211h = atoi(pos);
1918 [ + + ]: 5682 : } else if (os_strcmp(buf, "ieee8021x") == 0) {
1919 : 159 : bss->ieee802_1x = atoi(pos);
1920 [ - + ]: 5523 : } else if (os_strcmp(buf, "eapol_version") == 0) {
1921 : 0 : bss->eapol_version = atoi(pos);
1922 [ # # ][ # # ]: 0 : if (bss->eapol_version < 1 ||
1923 : 0 : bss->eapol_version > 2) {
1924 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid EAPOL "
1925 : : "version (%d): '%s'.",
1926 : : line, bss->eapol_version, pos);
1927 : 0 : errors++;
1928 : : } else
1929 : 0 : wpa_printf(MSG_DEBUG, "eapol_version=%d",
1930 : : bss->eapol_version);
1931 : : #ifdef EAP_SERVER
1932 [ - + ]: 5523 : } else if (os_strcmp(buf, "eap_authenticator") == 0) {
1933 : 0 : bss->eap_server = atoi(pos);
1934 : 0 : wpa_printf(MSG_ERROR, "Line %d: obsolete "
1935 : : "eap_authenticator used; this has been "
1936 : : "renamed to eap_server", line);
1937 [ + + ]: 5523 : } else if (os_strcmp(buf, "eap_server") == 0) {
1938 : 65 : bss->eap_server = atoi(pos);
1939 [ + + ]: 5458 : } else if (os_strcmp(buf, "eap_user_file") == 0) {
1940 [ - + ]: 14 : if (hostapd_config_read_eap_user(pos, bss))
1941 : 0 : errors++;
1942 [ + + ]: 5444 : } else if (os_strcmp(buf, "ca_cert") == 0) {
1943 : 9 : os_free(bss->ca_cert);
1944 : 9 : bss->ca_cert = os_strdup(pos);
1945 [ + + ]: 5435 : } else if (os_strcmp(buf, "server_cert") == 0) {
1946 : 9 : os_free(bss->server_cert);
1947 : 9 : bss->server_cert = os_strdup(pos);
1948 [ + + ]: 5426 : } else if (os_strcmp(buf, "private_key") == 0) {
1949 : 9 : os_free(bss->private_key);
1950 : 9 : bss->private_key = os_strdup(pos);
1951 [ - + ]: 5417 : } else if (os_strcmp(buf, "private_key_passwd") == 0) {
1952 : 0 : os_free(bss->private_key_passwd);
1953 : 0 : bss->private_key_passwd = os_strdup(pos);
1954 [ - + ]: 5417 : } else if (os_strcmp(buf, "check_crl") == 0) {
1955 : 0 : bss->check_crl = atoi(pos);
1956 [ + + ]: 5417 : } else if (os_strcmp(buf, "ocsp_stapling_response") == 0) {
1957 : 2 : os_free(bss->ocsp_stapling_response);
1958 : 2 : bss->ocsp_stapling_response = os_strdup(pos);
1959 [ + + ]: 5415 : } else if (os_strcmp(buf, "dh_file") == 0) {
1960 : 1 : os_free(bss->dh_file);
1961 : 1 : bss->dh_file = os_strdup(pos);
1962 [ + + ]: 5414 : } else if (os_strcmp(buf, "fragment_size") == 0) {
1963 : 1 : bss->fragment_size = atoi(pos);
1964 : : #ifdef EAP_SERVER_FAST
1965 [ + + ]: 5413 : } else if (os_strcmp(buf, "pac_opaque_encr_key") == 0) {
1966 : 1 : os_free(bss->pac_opaque_encr_key);
1967 : 1 : bss->pac_opaque_encr_key = os_malloc(16);
1968 [ - + ]: 1 : if (bss->pac_opaque_encr_key == NULL) {
1969 : 0 : wpa_printf(MSG_ERROR, "Line %d: No memory for "
1970 : : "pac_opaque_encr_key", line);
1971 : 0 : errors++;
1972 [ - + ]: 1 : } else if (hexstr2bin(pos, bss->pac_opaque_encr_key,
1973 : : 16)) {
1974 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
1975 : : "pac_opaque_encr_key", line);
1976 : 0 : errors++;
1977 : : }
1978 [ + + ]: 5412 : } else if (os_strcmp(buf, "eap_fast_a_id") == 0) {
1979 : 1 : size_t idlen = os_strlen(pos);
1980 [ - + ]: 1 : if (idlen & 1) {
1981 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
1982 : : "eap_fast_a_id", line);
1983 : 0 : errors++;
1984 : : } else {
1985 : 1 : os_free(bss->eap_fast_a_id);
1986 : 1 : bss->eap_fast_a_id = os_malloc(idlen / 2);
1987 [ + - - + ]: 2 : if (bss->eap_fast_a_id == NULL ||
1988 : 1 : hexstr2bin(pos, bss->eap_fast_a_id,
1989 : : idlen / 2)) {
1990 : 0 : wpa_printf(MSG_ERROR, "Line %d: "
1991 : : "Failed to parse "
1992 : : "eap_fast_a_id", line);
1993 : 0 : errors++;
1994 : : } else
1995 : 1 : bss->eap_fast_a_id_len = idlen / 2;
1996 : : }
1997 [ + + ]: 5411 : } else if (os_strcmp(buf, "eap_fast_a_id_info") == 0) {
1998 : 1 : os_free(bss->eap_fast_a_id_info);
1999 : 1 : bss->eap_fast_a_id_info = os_strdup(pos);
2000 [ - + ]: 5410 : } else if (os_strcmp(buf, "eap_fast_prov") == 0) {
2001 : 0 : bss->eap_fast_prov = atoi(pos);
2002 [ - + ]: 5410 : } else if (os_strcmp(buf, "pac_key_lifetime") == 0) {
2003 : 0 : bss->pac_key_lifetime = atoi(pos);
2004 [ - + ]: 5410 : } else if (os_strcmp(buf, "pac_key_refresh_time") == 0) {
2005 : 0 : bss->pac_key_refresh_time = atoi(pos);
2006 : : #endif /* EAP_SERVER_FAST */
2007 : : #ifdef EAP_SERVER_SIM
2008 [ + + ]: 5410 : } else if (os_strcmp(buf, "eap_sim_db") == 0) {
2009 : 1 : os_free(bss->eap_sim_db);
2010 : 1 : bss->eap_sim_db = os_strdup(pos);
2011 [ + + ]: 5409 : } else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
2012 : 1 : bss->eap_sim_aka_result_ind = atoi(pos);
2013 : : #endif /* EAP_SERVER_SIM */
2014 : : #ifdef EAP_SERVER_TNC
2015 [ - + ]: 5408 : } else if (os_strcmp(buf, "tnc") == 0) {
2016 : 0 : bss->tnc = atoi(pos);
2017 : : #endif /* EAP_SERVER_TNC */
2018 : : #ifdef EAP_SERVER_PWD
2019 [ + + ]: 5408 : } else if (os_strcmp(buf, "pwd_group") == 0) {
2020 : 5 : bss->pwd_group = atoi(pos);
2021 : : #endif /* EAP_SERVER_PWD */
2022 : : #endif /* EAP_SERVER */
2023 [ - + ]: 5403 : } else if (os_strcmp(buf, "eap_message") == 0) {
2024 : : char *term;
2025 : 0 : bss->eap_req_id_text = os_strdup(pos);
2026 [ # # ]: 0 : if (bss->eap_req_id_text == NULL) {
2027 : 0 : wpa_printf(MSG_ERROR, "Line %d: Failed to "
2028 : : "allocate memory for "
2029 : : "eap_req_id_text", line);
2030 : 0 : errors++;
2031 : 0 : return errors;
2032 : : }
2033 : 0 : bss->eap_req_id_text_len =
2034 : 0 : os_strlen(bss->eap_req_id_text);
2035 : 0 : term = os_strstr(bss->eap_req_id_text, "\\0");
2036 [ # # ]: 0 : if (term) {
2037 : 0 : *term++ = '\0';
2038 : 0 : os_memmove(term, term + 1,
2039 : : bss->eap_req_id_text_len -
2040 : : (term - bss->eap_req_id_text) - 1);
2041 : 0 : bss->eap_req_id_text_len--;
2042 : : }
2043 [ + + ]: 5403 : } else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
2044 : 2 : bss->default_wep_key_len = atoi(pos);
2045 [ - + ]: 2 : if (bss->default_wep_key_len > 13) {
2046 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
2047 : : "key len %lu (= %lu bits)", line,
2048 : : (unsigned long)
2049 : : bss->default_wep_key_len,
2050 : : (unsigned long)
2051 : 0 : bss->default_wep_key_len * 8);
2052 : 0 : errors++;
2053 : : }
2054 [ + + ]: 5401 : } else if (os_strcmp(buf, "wep_key_len_unicast") == 0) {
2055 : 2 : bss->individual_wep_key_len = atoi(pos);
2056 [ - + ][ + - ]: 2 : if (bss->individual_wep_key_len < 0 ||
2057 : 2 : bss->individual_wep_key_len > 13) {
2058 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
2059 : : "key len %d (= %d bits)", line,
2060 : : bss->individual_wep_key_len,
2061 : 0 : bss->individual_wep_key_len * 8);
2062 : 0 : errors++;
2063 : : }
2064 [ - + ]: 5399 : } else if (os_strcmp(buf, "wep_rekey_period") == 0) {
2065 : 0 : bss->wep_rekeying_period = atoi(pos);
2066 [ # # ]: 0 : if (bss->wep_rekeying_period < 0) {
2067 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2068 : : "period %d",
2069 : : line, bss->wep_rekeying_period);
2070 : 0 : errors++;
2071 : : }
2072 [ - + ]: 5399 : } else if (os_strcmp(buf, "eap_reauth_period") == 0) {
2073 : 0 : bss->eap_reauth_period = atoi(pos);
2074 [ # # ]: 0 : if (bss->eap_reauth_period < 0) {
2075 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2076 : : "period %d",
2077 : : line, bss->eap_reauth_period);
2078 : 0 : errors++;
2079 : : }
2080 [ - + ]: 5399 : } else if (os_strcmp(buf, "eapol_key_index_workaround") == 0) {
2081 : 0 : bss->eapol_key_index_workaround = atoi(pos);
2082 : : #ifdef CONFIG_IAPP
2083 : : } else if (os_strcmp(buf, "iapp_interface") == 0) {
2084 : : bss->ieee802_11f = 1;
2085 : : os_strlcpy(bss->iapp_iface, pos,
2086 : : sizeof(bss->iapp_iface));
2087 : : #endif /* CONFIG_IAPP */
2088 [ + + ]: 5399 : } else if (os_strcmp(buf, "own_ip_addr") == 0) {
2089 [ - + ]: 2 : if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
2090 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid IP "
2091 : : "address '%s'", line, pos);
2092 : 0 : errors++;
2093 : : }
2094 [ + + ]: 5397 : } else if (os_strcmp(buf, "nas_identifier") == 0) {
2095 : 68 : bss->nas_identifier = os_strdup(pos);
2096 : : #ifndef CONFIG_NO_RADIUS
2097 [ + + ]: 5329 : } else if (os_strcmp(buf, "auth_server_addr") == 0) {
2098 [ - + ]: 148 : if (hostapd_config_read_radius_addr(
2099 : 148 : &bss->radius->auth_servers,
2100 : 148 : &bss->radius->num_auth_servers, pos, 1812,
2101 : 148 : &bss->radius->auth_server)) {
2102 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid IP "
2103 : : "address '%s'", line, pos);
2104 : 0 : errors++;
2105 : : }
2106 [ + + ][ + + ]: 5181 : } else if (bss->radius->auth_server &&
2107 : 2727 : os_strcmp(buf, "auth_server_port") == 0) {
2108 : 148 : bss->radius->auth_server->port = atoi(pos);
2109 [ + + ][ + + ]: 5033 : } else if (bss->radius->auth_server &&
2110 : 148 : os_strcmp(buf, "auth_server_shared_secret") == 0) {
2111 : 148 : int len = os_strlen(pos);
2112 [ - + ]: 148 : if (len == 0) {
2113 : : /* RFC 2865, Ch. 3 */
2114 : 0 : wpa_printf(MSG_ERROR, "Line %d: empty shared "
2115 : : "secret is not allowed.", line);
2116 : 0 : errors++;
2117 : : }
2118 : 296 : bss->radius->auth_server->shared_secret =
2119 : 148 : (u8 *) os_strdup(pos);
2120 : 148 : bss->radius->auth_server->shared_secret_len = len;
2121 [ + + ]: 4885 : } else if (os_strcmp(buf, "acct_server_addr") == 0) {
2122 [ - + ]: 3 : if (hostapd_config_read_radius_addr(
2123 : 3 : &bss->radius->acct_servers,
2124 : 3 : &bss->radius->num_acct_servers, pos, 1813,
2125 : 3 : &bss->radius->acct_server)) {
2126 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid IP "
2127 : : "address '%s'", line, pos);
2128 : 0 : errors++;
2129 : : }
2130 [ + + ][ + + ]: 4882 : } else if (bss->radius->acct_server &&
2131 : 6 : os_strcmp(buf, "acct_server_port") == 0) {
2132 : 3 : bss->radius->acct_server->port = atoi(pos);
2133 [ + + ][ + - ]: 4879 : } else if (bss->radius->acct_server &&
2134 : 3 : os_strcmp(buf, "acct_server_shared_secret") == 0) {
2135 : 3 : int len = os_strlen(pos);
2136 [ - + ]: 3 : if (len == 0) {
2137 : : /* RFC 2865, Ch. 3 */
2138 : 0 : wpa_printf(MSG_ERROR, "Line %d: empty shared "
2139 : : "secret is not allowed.", line);
2140 : 0 : errors++;
2141 : : }
2142 : 6 : bss->radius->acct_server->shared_secret =
2143 : 3 : (u8 *) os_strdup(pos);
2144 : 3 : bss->radius->acct_server->shared_secret_len = len;
2145 [ - + ]: 4876 : } else if (os_strcmp(buf, "radius_retry_primary_interval") ==
2146 : : 0) {
2147 : 0 : bss->radius->retry_primary_interval = atoi(pos);
2148 [ - + ]: 4876 : } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0)
2149 : : {
2150 : 0 : bss->acct_interim_interval = atoi(pos);
2151 [ - + ]: 4876 : } else if (os_strcmp(buf, "radius_request_cui") == 0) {
2152 : 0 : bss->radius_request_cui = atoi(pos);
2153 [ - + ]: 4876 : } else if (os_strcmp(buf, "radius_auth_req_attr") == 0) {
2154 : : struct hostapd_radius_attr *attr, *a;
2155 : 0 : attr = hostapd_parse_radius_attr(pos);
2156 [ # # ]: 0 : if (attr == NULL) {
2157 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2158 : : "radius_auth_req_attr", line);
2159 : 0 : errors++;
2160 [ # # ]: 0 : } else if (bss->radius_auth_req_attr == NULL) {
2161 : 0 : bss->radius_auth_req_attr = attr;
2162 : : } else {
2163 : 0 : a = bss->radius_auth_req_attr;
2164 [ # # ]: 0 : while (a->next)
2165 : 0 : a = a->next;
2166 : 0 : a->next = attr;
2167 : : }
2168 [ - + ]: 4876 : } else if (os_strcmp(buf, "radius_acct_req_attr") == 0) {
2169 : : struct hostapd_radius_attr *attr, *a;
2170 : 0 : attr = hostapd_parse_radius_attr(pos);
2171 [ # # ]: 0 : if (attr == NULL) {
2172 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2173 : : "radius_acct_req_attr", line);
2174 : 0 : errors++;
2175 [ # # ]: 0 : } else if (bss->radius_acct_req_attr == NULL) {
2176 : 0 : bss->radius_acct_req_attr = attr;
2177 : : } else {
2178 : 0 : a = bss->radius_acct_req_attr;
2179 [ # # ]: 0 : while (a->next)
2180 : 0 : a = a->next;
2181 : 0 : a->next = attr;
2182 : : }
2183 [ + + ]: 4876 : } else if (os_strcmp(buf, "radius_das_port") == 0) {
2184 : 2 : bss->radius_das_port = atoi(pos);
2185 [ + + ]: 4874 : } else if (os_strcmp(buf, "radius_das_client") == 0) {
2186 [ - + ]: 2 : if (hostapd_parse_das_client(bss, pos) < 0) {
2187 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2188 : : "DAS client", line);
2189 : 0 : errors++;
2190 : : }
2191 [ - + ]: 4872 : } else if (os_strcmp(buf, "radius_das_time_window") == 0) {
2192 : 0 : bss->radius_das_time_window = atoi(pos);
2193 [ + + ]: 4872 : } else if (os_strcmp(buf, "radius_das_require_event_timestamp")
2194 : : == 0) {
2195 : 2 : bss->radius_das_require_event_timestamp = atoi(pos);
2196 : : #endif /* CONFIG_NO_RADIUS */
2197 [ + + ]: 4870 : } else if (os_strcmp(buf, "auth_algs") == 0) {
2198 : 2 : bss->auth_algs = atoi(pos);
2199 [ - + ]: 2 : if (bss->auth_algs == 0) {
2200 : 0 : wpa_printf(MSG_ERROR, "Line %d: no "
2201 : : "authentication algorithms allowed",
2202 : : line);
2203 : 0 : errors++;
2204 : : }
2205 [ - + ]: 4868 : } else if (os_strcmp(buf, "max_num_sta") == 0) {
2206 : 0 : bss->max_num_sta = atoi(pos);
2207 [ # # ][ # # ]: 0 : if (bss->max_num_sta < 0 ||
2208 : 0 : bss->max_num_sta > MAX_STA_COUNT) {
2209 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
2210 : : "max_num_sta=%d; allowed range "
2211 : : "0..%d", line, bss->max_num_sta,
2212 : : MAX_STA_COUNT);
2213 : 0 : errors++;
2214 : : }
2215 [ + + ]: 4868 : } else if (os_strcmp(buf, "wpa") == 0) {
2216 : 252 : bss->wpa = atoi(pos);
2217 [ - + ]: 4616 : } else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
2218 : 0 : bss->wpa_group_rekey = atoi(pos);
2219 [ - + ]: 4616 : } else if (os_strcmp(buf, "wpa_strict_rekey") == 0) {
2220 : 0 : bss->wpa_strict_rekey = atoi(pos);
2221 [ - + ]: 4616 : } else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
2222 : 0 : bss->wpa_gmk_rekey = atoi(pos);
2223 [ - + ]: 4616 : } else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
2224 : 0 : bss->wpa_ptk_rekey = atoi(pos);
2225 [ + + ]: 4616 : } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
2226 : 97 : int len = os_strlen(pos);
2227 [ + - ][ - + ]: 97 : if (len < 8 || len > 63) {
2228 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid WPA "
2229 : : "passphrase length %d (expected "
2230 : : "8..63)", line, len);
2231 : 0 : errors++;
2232 : : } else {
2233 : 97 : os_free(bss->ssid.wpa_passphrase);
2234 : 97 : bss->ssid.wpa_passphrase = os_strdup(pos);
2235 [ + - ]: 97 : if (bss->ssid.wpa_passphrase) {
2236 : 97 : os_free(bss->ssid.wpa_psk);
2237 : 97 : bss->ssid.wpa_psk = NULL;
2238 : 97 : bss->ssid.wpa_passphrase_set = 1;
2239 : : }
2240 : : }
2241 [ + + ]: 4519 : } else if (os_strcmp(buf, "wpa_psk") == 0) {
2242 : 1 : os_free(bss->ssid.wpa_psk);
2243 : 1 : bss->ssid.wpa_psk =
2244 : 1 : os_zalloc(sizeof(struct hostapd_wpa_psk));
2245 [ - + ]: 1 : if (bss->ssid.wpa_psk == NULL)
2246 : 0 : errors++;
2247 [ + - ]: 1 : else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
2248 [ - + ]: 1 : PMK_LEN) ||
2249 : 1 : pos[PMK_LEN * 2] != '\0') {
2250 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid PSK "
2251 : : "'%s'.", line, pos);
2252 : 0 : errors++;
2253 : : } else {
2254 : 1 : bss->ssid.wpa_psk->group = 1;
2255 : 1 : os_free(bss->ssid.wpa_passphrase);
2256 : 1 : bss->ssid.wpa_passphrase = NULL;
2257 : 1 : bss->ssid.wpa_psk_set = 1;
2258 : : }
2259 [ + + ]: 4518 : } else if (os_strcmp(buf, "wpa_psk_file") == 0) {
2260 : 1 : os_free(bss->ssid.wpa_psk_file);
2261 : 1 : bss->ssid.wpa_psk_file = os_strdup(pos);
2262 [ - + ]: 1 : if (!bss->ssid.wpa_psk_file) {
2263 : 0 : wpa_printf(MSG_ERROR, "Line %d: allocation "
2264 : : "failed", line);
2265 : 0 : errors++;
2266 : : }
2267 [ + + ]: 4517 : } else if (os_strcmp(buf, "wpa_key_mgmt") == 0) {
2268 : 252 : bss->wpa_key_mgmt =
2269 : 252 : hostapd_config_parse_key_mgmt(line, pos);
2270 [ - + ]: 252 : if (bss->wpa_key_mgmt == -1)
2271 : 0 : errors++;
2272 [ - + ]: 4265 : } else if (os_strcmp(buf, "wpa_psk_radius") == 0) {
2273 : 0 : bss->wpa_psk_radius = atoi(pos);
2274 [ # # ][ # # ]: 0 : if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
2275 [ # # ]: 0 : bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
2276 : 0 : bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
2277 : 0 : wpa_printf(MSG_ERROR, "Line %d: unknown "
2278 : : "wpa_psk_radius %d",
2279 : 0 : line, bss->wpa_psk_radius);
2280 : 0 : errors++;
2281 : : }
2282 [ + + ]: 4265 : } else if (os_strcmp(buf, "wpa_pairwise") == 0) {
2283 : 7 : bss->wpa_pairwise =
2284 : 7 : hostapd_config_parse_cipher(line, pos);
2285 [ - + ][ + - ]: 7 : if (bss->wpa_pairwise == -1 ||
2286 : 7 : bss->wpa_pairwise == 0)
2287 : 0 : errors++;
2288 [ - + ]: 7 : else if (bss->wpa_pairwise &
2289 : : (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
2290 : : WPA_CIPHER_WEP104)) {
2291 : 0 : wpa_printf(MSG_ERROR, "Line %d: unsupported "
2292 : : "pairwise cipher suite '%s'",
2293 : : bss->wpa_pairwise, pos);
2294 : 7 : errors++;
2295 : : }
2296 [ + + ]: 4258 : } else if (os_strcmp(buf, "rsn_pairwise") == 0) {
2297 : 250 : bss->rsn_pairwise =
2298 : 250 : hostapd_config_parse_cipher(line, pos);
2299 [ - + ][ + - ]: 250 : if (bss->rsn_pairwise == -1 ||
2300 : 250 : bss->rsn_pairwise == 0)
2301 : 0 : errors++;
2302 [ - + ]: 250 : else if (bss->rsn_pairwise &
2303 : : (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
2304 : : WPA_CIPHER_WEP104)) {
2305 : 0 : wpa_printf(MSG_ERROR, "Line %d: unsupported "
2306 : : "pairwise cipher suite '%s'",
2307 : : bss->rsn_pairwise, pos);
2308 : 250 : errors++;
2309 : : }
2310 : : #ifdef CONFIG_RSN_PREAUTH
2311 [ - + ]: 4008 : } else if (os_strcmp(buf, "rsn_preauth") == 0) {
2312 : 0 : bss->rsn_preauth = atoi(pos);
2313 [ - + ]: 4008 : } else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
2314 : 0 : bss->rsn_preauth_interfaces = os_strdup(pos);
2315 : : #endif /* CONFIG_RSN_PREAUTH */
2316 : : #ifdef CONFIG_PEERKEY
2317 [ + + ]: 4008 : } else if (os_strcmp(buf, "peerkey") == 0) {
2318 : 1 : bss->peerkey = atoi(pos);
2319 : : #endif /* CONFIG_PEERKEY */
2320 : : #ifdef CONFIG_IEEE80211R
2321 [ + + ]: 4007 : } else if (os_strcmp(buf, "mobility_domain") == 0) {
2322 [ + - - + ]: 32 : if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
2323 : 16 : hexstr2bin(pos, bss->mobility_domain,
2324 : : MOBILITY_DOMAIN_ID_LEN) != 0) {
2325 : 0 : wpa_printf(MSG_DEBUG, "Line %d: Invalid "
2326 : : "mobility_domain '%s'", line, pos);
2327 : 0 : errors++;
2328 : 0 : return errors;
2329 : : }
2330 [ + + ]: 3991 : } else if (os_strcmp(buf, "r1_key_holder") == 0) {
2331 [ + - - + ]: 32 : if (os_strlen(pos) != 2 * FT_R1KH_ID_LEN ||
2332 : 16 : hexstr2bin(pos, bss->r1_key_holder,
2333 : : FT_R1KH_ID_LEN) != 0) {
2334 : 0 : wpa_printf(MSG_DEBUG, "Line %d: Invalid "
2335 : : "r1_key_holder '%s'", line, pos);
2336 : 0 : errors++;
2337 : 0 : return errors;
2338 : : }
2339 [ + + ]: 3975 : } else if (os_strcmp(buf, "r0_key_lifetime") == 0) {
2340 : 16 : bss->r0_key_lifetime = atoi(pos);
2341 [ + + ]: 3959 : } else if (os_strcmp(buf, "reassociation_deadline") == 0) {
2342 : 16 : bss->reassociation_deadline = atoi(pos);
2343 [ + + ]: 3943 : } else if (os_strcmp(buf, "r0kh") == 0) {
2344 [ - + ]: 32 : if (add_r0kh(bss, pos) < 0) {
2345 : 0 : wpa_printf(MSG_DEBUG, "Line %d: Invalid "
2346 : : "r0kh '%s'", line, pos);
2347 : 0 : errors++;
2348 : 0 : return errors;
2349 : : }
2350 [ + + ]: 3911 : } else if (os_strcmp(buf, "r1kh") == 0) {
2351 [ - + ]: 16 : if (add_r1kh(bss, pos) < 0) {
2352 : 0 : wpa_printf(MSG_DEBUG, "Line %d: Invalid "
2353 : : "r1kh '%s'", line, pos);
2354 : 0 : errors++;
2355 : 0 : return errors;
2356 : : }
2357 [ + + ]: 3895 : } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
2358 : 16 : bss->pmk_r1_push = atoi(pos);
2359 [ - + ]: 3879 : } else if (os_strcmp(buf, "ft_over_ds") == 0) {
2360 : 0 : bss->ft_over_ds = atoi(pos);
2361 : : #endif /* CONFIG_IEEE80211R */
2362 : : #ifndef CONFIG_NO_CTRL_IFACE
2363 [ + + ]: 3879 : } else if (os_strcmp(buf, "ctrl_interface") == 0) {
2364 : 30 : os_free(bss->ctrl_interface);
2365 : 30 : bss->ctrl_interface = os_strdup(pos);
2366 [ + + ]: 3849 : } else if (os_strcmp(buf, "ctrl_interface_group") == 0) {
2367 : : #ifndef CONFIG_NATIVE_WINDOWS
2368 : : struct group *grp;
2369 : : char *endp;
2370 : 1 : const char *group = pos;
2371 : :
2372 : 1 : grp = getgrnam(group);
2373 [ + - ]: 1 : if (grp) {
2374 : 1 : bss->ctrl_interface_gid = grp->gr_gid;
2375 : 1 : bss->ctrl_interface_gid_set = 1;
2376 : 1 : wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
2377 : : " (from group name '%s')",
2378 : : bss->ctrl_interface_gid, group);
2379 : 1 : return errors;
2380 : : }
2381 : :
2382 : : /* Group name not found - try to parse this as gid */
2383 : 0 : bss->ctrl_interface_gid = strtol(group, &endp, 10);
2384 [ # # ][ # # ]: 0 : if (*group == '\0' || *endp != '\0') {
2385 : 0 : wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
2386 : : "'%s'", line, group);
2387 : 0 : errors++;
2388 : 0 : return errors;
2389 : : }
2390 : 0 : bss->ctrl_interface_gid_set = 1;
2391 : 0 : wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
2392 : : bss->ctrl_interface_gid);
2393 : : #endif /* CONFIG_NATIVE_WINDOWS */
2394 : : #endif /* CONFIG_NO_CTRL_IFACE */
2395 : : #ifdef RADIUS_SERVER
2396 [ + + ]: 3848 : } else if (os_strcmp(buf, "radius_server_clients") == 0) {
2397 : 2 : os_free(bss->radius_server_clients);
2398 : 2 : bss->radius_server_clients = os_strdup(pos);
2399 [ + + ]: 3846 : } else if (os_strcmp(buf, "radius_server_auth_port") == 0) {
2400 : 1 : bss->radius_server_auth_port = atoi(pos);
2401 [ + + ]: 3845 : } else if (os_strcmp(buf, "radius_server_acct_port") == 0) {
2402 : 2 : bss->radius_server_acct_port = atoi(pos);
2403 [ + + ]: 3843 : } else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
2404 : 1 : bss->radius_server_ipv6 = atoi(pos);
2405 : : #endif /* RADIUS_SERVER */
2406 [ - + ]: 3842 : } else if (os_strcmp(buf, "test_socket") == 0) {
2407 : 0 : os_free(bss->test_socket);
2408 : 0 : bss->test_socket = os_strdup(pos);
2409 [ - + ]: 3842 : } else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
2410 : 0 : bss->use_pae_group_addr = atoi(pos);
2411 [ + + ]: 3842 : } else if (os_strcmp(buf, "hw_mode") == 0) {
2412 [ - + ]: 346 : if (os_strcmp(pos, "a") == 0)
2413 : 0 : conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
2414 [ + + ]: 346 : else if (os_strcmp(pos, "b") == 0)
2415 : 1 : conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
2416 [ + - ]: 345 : else if (os_strcmp(pos, "g") == 0)
2417 : 345 : conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
2418 [ # # ]: 0 : else if (os_strcmp(pos, "ad") == 0)
2419 : 0 : conf->hw_mode = HOSTAPD_MODE_IEEE80211AD;
2420 : : else {
2421 : 0 : wpa_printf(MSG_ERROR, "Line %d: unknown "
2422 : : "hw_mode '%s'", line, pos);
2423 : 0 : errors++;
2424 : : }
2425 [ - + ]: 3496 : } else if (os_strcmp(buf, "wps_rf_bands") == 0) {
2426 [ # # ]: 0 : if (os_strcmp(pos, "a") == 0)
2427 : 0 : bss->wps_rf_bands = WPS_RF_50GHZ;
2428 [ # # ][ # # ]: 0 : else if (os_strcmp(pos, "g") == 0 ||
2429 : 0 : os_strcmp(pos, "b") == 0)
2430 : 0 : bss->wps_rf_bands = WPS_RF_24GHZ;
2431 [ # # ][ # # ]: 0 : else if (os_strcmp(pos, "ag") == 0 ||
2432 : 0 : os_strcmp(pos, "ga") == 0)
2433 : 0 : bss->wps_rf_bands =
2434 : : WPS_RF_24GHZ | WPS_RF_50GHZ;
2435 : : else {
2436 : 0 : wpa_printf(MSG_ERROR, "Line %d: unknown "
2437 : : "wps_rf_band '%s'", line, pos);
2438 : 0 : errors++;
2439 : : }
2440 [ + + ]: 3496 : } else if (os_strcmp(buf, "channel") == 0) {
2441 [ - + ]: 366 : if (os_strcmp(pos, "acs_survey") == 0) {
2442 : : #ifndef CONFIG_ACS
2443 : : wpa_printf(MSG_ERROR, "Line %d: tries to enable ACS but CONFIG_ACS disabled",
2444 : : line);
2445 : : errors++;
2446 : : #endif /* CONFIG_ACS */
2447 : 0 : conf->channel = 0;
2448 : : } else
2449 : 366 : conf->channel = atoi(pos);
2450 [ + + ]: 3130 : } else if (os_strcmp(buf, "beacon_int") == 0) {
2451 : 8 : int val = atoi(pos);
2452 : : /* MIB defines range as 1..65535, but very small values
2453 : : * cause problems with the current implementation.
2454 : : * Since it is unlikely that this small numbers are
2455 : : * useful in real life scenarios, do not allow beacon
2456 : : * period to be set below 15 TU. */
2457 [ - + ][ + - ]: 8 : if (val < 15 || val > 65535) {
2458 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2459 : : "beacon_int %d (expected "
2460 : : "15..65535)", line, val);
2461 : 0 : errors++;
2462 : : } else
2463 : 8 : conf->beacon_int = val;
2464 : : #ifdef CONFIG_ACS
2465 [ - + ]: 3122 : } else if (os_strcmp(buf, "acs_num_scans") == 0) {
2466 : 0 : int val = atoi(pos);
2467 [ # # ][ # # ]: 0 : if (val <= 0 || val > 100) {
2468 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid acs_num_scans %d (expected 1..100)",
2469 : : line, val);
2470 : 0 : errors++;
2471 : : } else
2472 : 0 : conf->acs_num_scans = val;
2473 : : #endif /* CONFIG_ACS */
2474 [ - + ]: 3122 : } else if (os_strcmp(buf, "dtim_period") == 0) {
2475 : 0 : bss->dtim_period = atoi(pos);
2476 [ # # ][ # # ]: 0 : if (bss->dtim_period < 1 || bss->dtim_period > 255) {
2477 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2478 : : "dtim_period %d",
2479 : : line, bss->dtim_period);
2480 : 0 : errors++;
2481 : : }
2482 [ + + ]: 3122 : } else if (os_strcmp(buf, "rts_threshold") == 0) {
2483 : 1 : conf->rts_threshold = atoi(pos);
2484 [ - + ][ + - ]: 1 : if (conf->rts_threshold < 0 ||
2485 : 1 : conf->rts_threshold > 2347) {
2486 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2487 : : "rts_threshold %d",
2488 : : line, conf->rts_threshold);
2489 : 0 : errors++;
2490 : : }
2491 [ + + ]: 3121 : } else if (os_strcmp(buf, "fragm_threshold") == 0) {
2492 : 3 : conf->fragm_threshold = atoi(pos);
2493 [ - + ][ + - ]: 3 : if (conf->fragm_threshold < 256 ||
2494 : 3 : conf->fragm_threshold > 2346) {
2495 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2496 : : "fragm_threshold %d",
2497 : : line, conf->fragm_threshold);
2498 : 0 : errors++;
2499 : : }
2500 [ - + ]: 3118 : } else if (os_strcmp(buf, "send_probe_response") == 0) {
2501 : 0 : int val = atoi(pos);
2502 [ # # ][ # # ]: 0 : if (val != 0 && val != 1) {
2503 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2504 : : "send_probe_response %d (expected "
2505 : : "0 or 1)", line, val);
2506 : : } else
2507 : 0 : conf->send_probe_response = val;
2508 [ - + ]: 3118 : } else if (os_strcmp(buf, "supported_rates") == 0) {
2509 [ # # ]: 0 : if (hostapd_parse_intlist(&conf->supported_rates, pos))
2510 : : {
2511 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid rate "
2512 : : "list", line);
2513 : 0 : errors++;
2514 : : }
2515 [ - + ]: 3118 : } else if (os_strcmp(buf, "basic_rates") == 0) {
2516 [ # # ]: 0 : if (hostapd_parse_intlist(&conf->basic_rates, pos)) {
2517 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid rate "
2518 : : "list", line);
2519 : 0 : errors++;
2520 : : }
2521 [ - + ]: 3118 : } else if (os_strcmp(buf, "preamble") == 0) {
2522 [ # # ]: 0 : if (atoi(pos))
2523 : 0 : conf->preamble = SHORT_PREAMBLE;
2524 : : else
2525 : 0 : conf->preamble = LONG_PREAMBLE;
2526 [ + + ]: 3118 : } else if (os_strcmp(buf, "ignore_broadcast_ssid") == 0) {
2527 : 3 : bss->ignore_broadcast_ssid = atoi(pos);
2528 [ - + ]: 3115 : } else if (os_strcmp(buf, "wep_default_key") == 0) {
2529 : 0 : bss->ssid.wep.idx = atoi(pos);
2530 [ # # ]: 0 : if (bss->ssid.wep.idx > 3) {
2531 : 0 : wpa_printf(MSG_ERROR, "Invalid "
2532 : : "wep_default_key index %d",
2533 : 0 : bss->ssid.wep.idx);
2534 : 0 : errors++;
2535 : : }
2536 [ + + ][ + - ]: 3115 : } else if (os_strcmp(buf, "wep_key0") == 0 ||
2537 [ + - ]: 3111 : os_strcmp(buf, "wep_key1") == 0 ||
2538 [ - + ]: 3111 : os_strcmp(buf, "wep_key2") == 0 ||
2539 : 3111 : os_strcmp(buf, "wep_key3") == 0) {
2540 [ - + ]: 4 : if (hostapd_config_read_wep(&bss->ssid.wep,
2541 : 4 : buf[7] - '0', pos)) {
2542 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
2543 : : "key '%s'", line, buf);
2544 : 0 : errors++;
2545 : : }
2546 : : #ifndef CONFIG_NO_VLAN
2547 [ - + ]: 3111 : } else if (os_strcmp(buf, "dynamic_vlan") == 0) {
2548 : 0 : bss->ssid.dynamic_vlan = atoi(pos);
2549 [ - + ]: 3111 : } else if (os_strcmp(buf, "vlan_file") == 0) {
2550 [ # # ]: 0 : if (hostapd_config_read_vlan_file(bss, pos)) {
2551 : 0 : wpa_printf(MSG_ERROR, "Line %d: failed to "
2552 : : "read VLAN file '%s'", line, pos);
2553 : 0 : errors++;
2554 : : }
2555 [ - + ]: 3111 : } else if (os_strcmp(buf, "vlan_naming") == 0) {
2556 : 0 : bss->ssid.vlan_naming = atoi(pos);
2557 [ # # ][ # # ]: 0 : if (bss->ssid.vlan_naming >= DYNAMIC_VLAN_NAMING_END ||
2558 : 0 : bss->ssid.vlan_naming < 0) {
2559 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2560 : : "naming scheme %d", line,
2561 : : bss->ssid.vlan_naming);
2562 : 0 : errors++;
2563 : : }
2564 : : #ifdef CONFIG_FULL_DYNAMIC_VLAN
2565 [ - + ]: 3111 : } else if (os_strcmp(buf, "vlan_tagged_interface") == 0) {
2566 : 0 : bss->ssid.vlan_tagged_interface = os_strdup(pos);
2567 : : #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2568 : : #endif /* CONFIG_NO_VLAN */
2569 [ - + ]: 3111 : } else if (os_strcmp(buf, "ap_table_max_size") == 0) {
2570 : 0 : conf->ap_table_max_size = atoi(pos);
2571 [ - + ]: 3111 : } else if (os_strcmp(buf, "ap_table_expiration_time") == 0) {
2572 : 0 : conf->ap_table_expiration_time = atoi(pos);
2573 [ - + ]: 3111 : } else if (os_strncmp(buf, "tx_queue_", 9) == 0) {
2574 [ # # ]: 0 : if (hostapd_config_tx_queue(conf, buf, pos)) {
2575 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid TX "
2576 : : "queue item", line);
2577 : 0 : errors++;
2578 : : }
2579 [ + - ][ + + ]: 3111 : } else if (os_strcmp(buf, "wme_enabled") == 0 ||
2580 : 3111 : os_strcmp(buf, "wmm_enabled") == 0) {
2581 : 1 : bss->wmm_enabled = atoi(pos);
2582 [ - + ]: 3110 : } else if (os_strcmp(buf, "uapsd_advertisement_enabled") == 0) {
2583 : 0 : bss->wmm_uapsd = atoi(pos);
2584 [ + - ][ + + ]: 3110 : } else if (os_strncmp(buf, "wme_ac_", 7) == 0 ||
2585 : 3110 : os_strncmp(buf, "wmm_ac_", 7) == 0) {
2586 [ - + ]: 20 : if (hostapd_config_wmm_ac(conf->wmm_ac_params, buf,
2587 : : pos)) {
2588 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
2589 : : "ac item", line);
2590 : 0 : errors++;
2591 : : }
2592 [ + + ]: 3090 : } else if (os_strcmp(buf, "bss") == 0) {
2593 [ - + ]: 10 : if (hostapd_config_bss(conf, pos)) {
2594 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid bss "
2595 : : "item", line);
2596 : 0 : errors++;
2597 : : }
2598 [ + + ]: 3080 : } else if (os_strcmp(buf, "bssid") == 0) {
2599 [ - + ]: 26 : if (hwaddr_aton(pos, bss->bssid)) {
2600 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid bssid "
2601 : : "item", line);
2602 : 0 : errors++;
2603 : : }
2604 : : #ifdef CONFIG_IEEE80211W
2605 [ + + ]: 3054 : } else if (os_strcmp(buf, "ieee80211w") == 0) {
2606 : 103 : bss->ieee80211w = atoi(pos);
2607 [ - + ]: 2951 : } else if (os_strcmp(buf, "assoc_sa_query_max_timeout") == 0) {
2608 : 0 : bss->assoc_sa_query_max_timeout = atoi(pos);
2609 [ # # ]: 0 : if (bss->assoc_sa_query_max_timeout == 0) {
2610 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2611 : : "assoc_sa_query_max_timeout", line);
2612 : 0 : errors++;
2613 : : }
2614 [ - + ]: 2951 : } else if (os_strcmp(buf, "assoc_sa_query_retry_timeout") == 0)
2615 : : {
2616 : 0 : bss->assoc_sa_query_retry_timeout = atoi(pos);
2617 [ # # ]: 0 : if (bss->assoc_sa_query_retry_timeout == 0) {
2618 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2619 : : "assoc_sa_query_retry_timeout",
2620 : : line);
2621 : 0 : errors++;
2622 : : }
2623 : : #endif /* CONFIG_IEEE80211W */
2624 : : #ifdef CONFIG_IEEE80211N
2625 [ + + ]: 2951 : } else if (os_strcmp(buf, "ieee80211n") == 0) {
2626 : 345 : conf->ieee80211n = atoi(pos);
2627 [ + + ]: 2606 : } else if (os_strcmp(buf, "ht_capab") == 0) {
2628 [ - + ]: 12 : if (hostapd_config_ht_capab(conf, pos) < 0) {
2629 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2630 : : "ht_capab", line);
2631 : 0 : errors++;
2632 : : }
2633 [ + + ]: 2594 : } else if (os_strcmp(buf, "require_ht") == 0) {
2634 : 1 : conf->require_ht = atoi(pos);
2635 [ + + ]: 2593 : } else if (os_strcmp(buf, "obss_interval") == 0) {
2636 : 1 : conf->obss_interval = atoi(pos);
2637 : : #endif /* CONFIG_IEEE80211N */
2638 : : #ifdef CONFIG_IEEE80211AC
2639 [ - + ]: 2592 : } else if (os_strcmp(buf, "ieee80211ac") == 0) {
2640 : 0 : conf->ieee80211ac = atoi(pos);
2641 [ - + ]: 2592 : } else if (os_strcmp(buf, "vht_capab") == 0) {
2642 [ # # ]: 0 : if (hostapd_config_vht_capab(conf, pos) < 0) {
2643 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2644 : : "vht_capab", line);
2645 : 0 : errors++;
2646 : : }
2647 [ - + ]: 2592 : } else if (os_strcmp(buf, "require_vht") == 0) {
2648 : 0 : conf->require_vht = atoi(pos);
2649 [ - + ]: 2592 : } else if (os_strcmp(buf, "vht_oper_chwidth") == 0) {
2650 : 0 : conf->vht_oper_chwidth = atoi(pos);
2651 [ - + ]: 2592 : } else if (os_strcmp(buf, "vht_oper_centr_freq_seg0_idx") == 0)
2652 : : {
2653 : 0 : conf->vht_oper_centr_freq_seg0_idx = atoi(pos);
2654 [ - + ]: 2592 : } else if (os_strcmp(buf, "vht_oper_centr_freq_seg1_idx") == 0)
2655 : : {
2656 : 0 : conf->vht_oper_centr_freq_seg1_idx = atoi(pos);
2657 : : #endif /* CONFIG_IEEE80211AC */
2658 [ - + ]: 2592 : } else if (os_strcmp(buf, "max_listen_interval") == 0) {
2659 : 0 : bss->max_listen_interval = atoi(pos);
2660 [ - + ]: 2592 : } else if (os_strcmp(buf, "disable_pmksa_caching") == 0) {
2661 : 0 : bss->disable_pmksa_caching = atoi(pos);
2662 [ + + ]: 2592 : } else if (os_strcmp(buf, "okc") == 0) {
2663 : 2 : bss->okc = atoi(pos);
2664 : : #ifdef CONFIG_WPS
2665 [ + + ]: 2590 : } else if (os_strcmp(buf, "wps_state") == 0) {
2666 : 51 : bss->wps_state = atoi(pos);
2667 [ - + ][ + - ]: 51 : if (bss->wps_state < 0 || bss->wps_state > 2) {
2668 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2669 : : "wps_state", line);
2670 : 0 : errors++;
2671 : : }
2672 [ + + ]: 2539 : } else if (os_strcmp(buf, "wps_independent") == 0) {
2673 : 2 : bss->wps_independent = atoi(pos);
2674 [ - + ]: 2537 : } else if (os_strcmp(buf, "ap_setup_locked") == 0) {
2675 : 0 : bss->ap_setup_locked = atoi(pos);
2676 [ + + ]: 2537 : } else if (os_strcmp(buf, "uuid") == 0) {
2677 [ - + ]: 15 : if (uuid_str2bin(pos, bss->uuid)) {
2678 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid UUID",
2679 : : line);
2680 : 0 : errors++;
2681 : : }
2682 [ - + ]: 2522 : } else if (os_strcmp(buf, "wps_pin_requests") == 0) {
2683 : 0 : os_free(bss->wps_pin_requests);
2684 : 0 : bss->wps_pin_requests = os_strdup(pos);
2685 [ + + ]: 2522 : } else if (os_strcmp(buf, "device_name") == 0) {
2686 [ - + ]: 16 : if (os_strlen(pos) > 32) {
2687 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too long "
2688 : : "device_name", line);
2689 : 0 : errors++;
2690 : : }
2691 : 16 : os_free(bss->device_name);
2692 : 16 : bss->device_name = os_strdup(pos);
2693 [ + + ]: 2506 : } else if (os_strcmp(buf, "manufacturer") == 0) {
2694 [ - + ]: 16 : if (os_strlen(pos) > 64) {
2695 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too long "
2696 : : "manufacturer", line);
2697 : 0 : errors++;
2698 : : }
2699 : 16 : os_free(bss->manufacturer);
2700 : 16 : bss->manufacturer = os_strdup(pos);
2701 [ + + ]: 2490 : } else if (os_strcmp(buf, "model_name") == 0) {
2702 [ - + ]: 16 : if (os_strlen(pos) > 32) {
2703 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too long "
2704 : : "model_name", line);
2705 : 0 : errors++;
2706 : : }
2707 : 16 : os_free(bss->model_name);
2708 : 16 : bss->model_name = os_strdup(pos);
2709 [ + + ]: 2474 : } else if (os_strcmp(buf, "model_number") == 0) {
2710 [ - + ]: 16 : if (os_strlen(pos) > 32) {
2711 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too long "
2712 : : "model_number", line);
2713 : 0 : errors++;
2714 : : }
2715 : 16 : os_free(bss->model_number);
2716 : 16 : bss->model_number = os_strdup(pos);
2717 [ + + ]: 2458 : } else if (os_strcmp(buf, "serial_number") == 0) {
2718 [ - + ]: 16 : if (os_strlen(pos) > 32) {
2719 : 0 : wpa_printf(MSG_ERROR, "Line %d: Too long "
2720 : : "serial_number", line);
2721 : 0 : errors++;
2722 : : }
2723 : 16 : os_free(bss->serial_number);
2724 : 16 : bss->serial_number = os_strdup(pos);
2725 [ + + ]: 2442 : } else if (os_strcmp(buf, "device_type") == 0) {
2726 [ - + ]: 15 : if (wps_dev_type_str2bin(pos, bss->device_type))
2727 : 0 : errors++;
2728 [ + + ]: 2427 : } else if (os_strcmp(buf, "config_methods") == 0) {
2729 : 15 : os_free(bss->config_methods);
2730 : 15 : bss->config_methods = os_strdup(pos);
2731 [ + + ]: 2412 : } else if (os_strcmp(buf, "os_version") == 0) {
2732 [ - + ]: 15 : if (hexstr2bin(pos, bss->os_version, 4)) {
2733 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2734 : : "os_version", line);
2735 : 0 : errors++;
2736 : : }
2737 [ + + ]: 2397 : } else if (os_strcmp(buf, "ap_pin") == 0) {
2738 : 19 : os_free(bss->ap_pin);
2739 : 19 : bss->ap_pin = os_strdup(pos);
2740 [ - + ]: 2378 : } else if (os_strcmp(buf, "skip_cred_build") == 0) {
2741 : 0 : bss->skip_cred_build = atoi(pos);
2742 [ - + ]: 2378 : } else if (os_strcmp(buf, "extra_cred") == 0) {
2743 : 0 : os_free(bss->extra_cred);
2744 : 0 : bss->extra_cred =
2745 : 0 : (u8 *) os_readfile(pos, &bss->extra_cred_len);
2746 [ # # ]: 0 : if (bss->extra_cred == NULL) {
2747 : 0 : wpa_printf(MSG_ERROR, "Line %d: could not "
2748 : : "read Credentials from '%s'",
2749 : : line, pos);
2750 : 0 : errors++;
2751 : : }
2752 [ - + ]: 2378 : } else if (os_strcmp(buf, "wps_cred_processing") == 0) {
2753 : 0 : bss->wps_cred_processing = atoi(pos);
2754 [ - + ]: 2378 : } else if (os_strcmp(buf, "ap_settings") == 0) {
2755 : 0 : os_free(bss->ap_settings);
2756 : 0 : bss->ap_settings =
2757 : 0 : (u8 *) os_readfile(pos, &bss->ap_settings_len);
2758 [ # # ]: 0 : if (bss->ap_settings == NULL) {
2759 : 0 : wpa_printf(MSG_ERROR, "Line %d: could not "
2760 : : "read AP Settings from '%s'",
2761 : : line, pos);
2762 : 0 : errors++;
2763 : : }
2764 [ + + ]: 2378 : } else if (os_strcmp(buf, "upnp_iface") == 0) {
2765 : 15 : bss->upnp_iface = os_strdup(pos);
2766 [ + + ]: 2363 : } else if (os_strcmp(buf, "friendly_name") == 0) {
2767 : 5 : os_free(bss->friendly_name);
2768 : 5 : bss->friendly_name = os_strdup(pos);
2769 [ + + ]: 2358 : } else if (os_strcmp(buf, "manufacturer_url") == 0) {
2770 : 5 : os_free(bss->manufacturer_url);
2771 : 5 : bss->manufacturer_url = os_strdup(pos);
2772 [ + + ]: 2353 : } else if (os_strcmp(buf, "model_description") == 0) {
2773 : 5 : os_free(bss->model_description);
2774 : 5 : bss->model_description = os_strdup(pos);
2775 [ + + ]: 2348 : } else if (os_strcmp(buf, "model_url") == 0) {
2776 : 5 : os_free(bss->model_url);
2777 : 5 : bss->model_url = os_strdup(pos);
2778 [ + + ]: 2343 : } else if (os_strcmp(buf, "upc") == 0) {
2779 : 5 : os_free(bss->upc);
2780 : 5 : bss->upc = os_strdup(pos);
2781 [ - + ]: 2338 : } else if (os_strcmp(buf, "pbc_in_m1") == 0) {
2782 : 0 : bss->pbc_in_m1 = atoi(pos);
2783 [ + + ]: 2338 : } else if (os_strcmp(buf, "server_id") == 0) {
2784 : 1 : os_free(bss->server_id);
2785 : 1 : bss->server_id = os_strdup(pos);
2786 : : #ifdef CONFIG_WPS_NFC
2787 [ - + ]: 2337 : } else if (os_strcmp(buf, "wps_nfc_dev_pw_id") == 0) {
2788 : 0 : bss->wps_nfc_dev_pw_id = atoi(pos);
2789 [ # # ][ # # ]: 0 : if (bss->wps_nfc_dev_pw_id < 0x10 ||
2790 : 0 : bss->wps_nfc_dev_pw_id > 0xffff) {
2791 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
2792 : : "wps_nfc_dev_pw_id value", line);
2793 : 0 : errors++;
2794 : : }
2795 : 0 : bss->wps_nfc_pw_from_config = 1;
2796 [ - + ]: 2337 : } else if (os_strcmp(buf, "wps_nfc_dh_pubkey") == 0) {
2797 : 0 : wpabuf_free(bss->wps_nfc_dh_pubkey);
2798 : 0 : bss->wps_nfc_dh_pubkey = hostapd_parse_bin(pos);
2799 : 0 : bss->wps_nfc_pw_from_config = 1;
2800 [ - + ]: 2337 : } else if (os_strcmp(buf, "wps_nfc_dh_privkey") == 0) {
2801 : 0 : wpabuf_free(bss->wps_nfc_dh_privkey);
2802 : 0 : bss->wps_nfc_dh_privkey = hostapd_parse_bin(pos);
2803 : 0 : bss->wps_nfc_pw_from_config = 1;
2804 [ - + ]: 2337 : } else if (os_strcmp(buf, "wps_nfc_dev_pw") == 0) {
2805 : 0 : wpabuf_free(bss->wps_nfc_dev_pw);
2806 : 0 : bss->wps_nfc_dev_pw = hostapd_parse_bin(pos);
2807 : 0 : bss->wps_nfc_pw_from_config = 1;
2808 : : #endif /* CONFIG_WPS_NFC */
2809 : : #endif /* CONFIG_WPS */
2810 : : #ifdef CONFIG_P2P_MANAGER
2811 [ + + ]: 2337 : } else if (os_strcmp(buf, "manage_p2p") == 0) {
2812 : 2 : int manage = atoi(pos);
2813 [ + - ]: 2 : if (manage)
2814 : 2 : bss->p2p |= P2P_MANAGE;
2815 : : else
2816 : 0 : bss->p2p &= ~P2P_MANAGE;
2817 [ + + ]: 2335 : } else if (os_strcmp(buf, "allow_cross_connection") == 0) {
2818 [ + + ]: 2 : if (atoi(pos))
2819 : 1 : bss->p2p |= P2P_ALLOW_CROSS_CONNECTION;
2820 : : else
2821 : 1 : bss->p2p &= ~P2P_ALLOW_CROSS_CONNECTION;
2822 : : #endif /* CONFIG_P2P_MANAGER */
2823 [ - + ]: 2333 : } else if (os_strcmp(buf, "disassoc_low_ack") == 0) {
2824 : 0 : bss->disassoc_low_ack = atoi(pos);
2825 [ - + ]: 2333 : } else if (os_strcmp(buf, "tdls_prohibit") == 0) {
2826 : 0 : int val = atoi(pos);
2827 [ # # ]: 0 : if (val)
2828 : 0 : bss->tdls |= TDLS_PROHIBIT;
2829 : : else
2830 : 0 : bss->tdls &= ~TDLS_PROHIBIT;
2831 [ - + ]: 2333 : } else if (os_strcmp(buf, "tdls_prohibit_chan_switch") == 0) {
2832 : 0 : int val = atoi(pos);
2833 [ # # ]: 0 : if (val)
2834 : 0 : bss->tdls |= TDLS_PROHIBIT_CHAN_SWITCH;
2835 : : else
2836 : 0 : bss->tdls &= ~TDLS_PROHIBIT_CHAN_SWITCH;
2837 : : #ifdef CONFIG_RSN_TESTING
2838 : : } else if (os_strcmp(buf, "rsn_testing") == 0) {
2839 : : extern int rsn_testing;
2840 : : rsn_testing = atoi(pos);
2841 : : #endif /* CONFIG_RSN_TESTING */
2842 [ + + ]: 2333 : } else if (os_strcmp(buf, "time_advertisement") == 0) {
2843 : 6 : bss->time_advertisement = atoi(pos);
2844 [ + + ]: 2327 : } else if (os_strcmp(buf, "time_zone") == 0) {
2845 : 6 : size_t tz_len = os_strlen(pos);
2846 [ + - ][ - + ]: 6 : if (tz_len < 4 || tz_len > 255) {
2847 : 0 : wpa_printf(MSG_DEBUG, "Line %d: invalid "
2848 : : "time_zone", line);
2849 : 0 : errors++;
2850 : 0 : return errors;
2851 : : }
2852 : 6 : os_free(bss->time_zone);
2853 : 6 : bss->time_zone = os_strdup(pos);
2854 [ - + ]: 6 : if (bss->time_zone == NULL)
2855 : 0 : errors++;
2856 : : #ifdef CONFIG_WNM
2857 [ + + ]: 2321 : } else if (os_strcmp(buf, "wnm_sleep_mode") == 0) {
2858 : 6 : bss->wnm_sleep_mode = atoi(pos);
2859 [ + + ]: 2315 : } else if (os_strcmp(buf, "bss_transition") == 0) {
2860 : 7 : bss->bss_transition = atoi(pos);
2861 : : #endif /* CONFIG_WNM */
2862 : : #ifdef CONFIG_INTERWORKING
2863 [ + + ]: 2308 : } else if (os_strcmp(buf, "interworking") == 0) {
2864 : 93 : bss->interworking = atoi(pos);
2865 [ + + ]: 2215 : } else if (os_strcmp(buf, "access_network_type") == 0) {
2866 : 93 : bss->access_network_type = atoi(pos);
2867 [ - + ][ + - ]: 93 : if (bss->access_network_type < 0 ||
2868 : 93 : bss->access_network_type > 15) {
2869 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2870 : : "access_network_type", line);
2871 : 0 : errors++;
2872 : : }
2873 [ + + ]: 2122 : } else if (os_strcmp(buf, "internet") == 0) {
2874 : 93 : bss->internet = atoi(pos);
2875 [ + + ]: 2029 : } else if (os_strcmp(buf, "asra") == 0) {
2876 : 93 : bss->asra = atoi(pos);
2877 [ + + ]: 1936 : } else if (os_strcmp(buf, "esr") == 0) {
2878 : 93 : bss->esr = atoi(pos);
2879 [ + + ]: 1843 : } else if (os_strcmp(buf, "uesa") == 0) {
2880 : 93 : bss->uesa = atoi(pos);
2881 [ + + ]: 1750 : } else if (os_strcmp(buf, "venue_group") == 0) {
2882 : 92 : bss->venue_group = atoi(pos);
2883 : 92 : bss->venue_info_set = 1;
2884 [ + + ]: 1658 : } else if (os_strcmp(buf, "venue_type") == 0) {
2885 : 92 : bss->venue_type = atoi(pos);
2886 : 92 : bss->venue_info_set = 1;
2887 [ + + ]: 1566 : } else if (os_strcmp(buf, "hessid") == 0) {
2888 [ - + ]: 40 : if (hwaddr_aton(pos, bss->hessid)) {
2889 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid "
2890 : : "hessid", line);
2891 : 0 : errors++;
2892 : : }
2893 [ + + ]: 1526 : } else if (os_strcmp(buf, "roaming_consortium") == 0) {
2894 [ - + ]: 363 : if (parse_roaming_consortium(bss, pos, line) < 0)
2895 : 0 : errors++;
2896 [ + + ]: 1163 : } else if (os_strcmp(buf, "venue_name") == 0) {
2897 [ - + ]: 186 : if (parse_venue_name(bss, pos, line) < 0)
2898 : 0 : errors++;
2899 [ + + ]: 977 : } else if (os_strcmp(buf, "network_auth_type") == 0) {
2900 : : u8 auth_type;
2901 : : u16 redirect_url_len;
2902 [ - + ]: 12 : if (hexstr2bin(pos, &auth_type, 1)) {
2903 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
2904 : : "network_auth_type '%s'",
2905 : : line, pos);
2906 : 0 : errors++;
2907 : 0 : return errors;
2908 : : }
2909 [ + - ][ + - ]: 12 : if (auth_type == 0 || auth_type == 2)
2910 : 12 : redirect_url_len = os_strlen(pos + 2);
2911 : : else
2912 : 0 : redirect_url_len = 0;
2913 : 12 : os_free(bss->network_auth_type);
2914 : 12 : bss->network_auth_type =
2915 : 12 : os_malloc(redirect_url_len + 3 + 1);
2916 [ - + ]: 12 : if (bss->network_auth_type == NULL) {
2917 : 0 : errors++;
2918 : 0 : return errors;
2919 : : }
2920 : 12 : *bss->network_auth_type = auth_type;
2921 : 12 : WPA_PUT_LE16(bss->network_auth_type + 1,
2922 : : redirect_url_len);
2923 [ + - ]: 12 : if (redirect_url_len)
2924 : 12 : os_memcpy(bss->network_auth_type + 3,
2925 : : pos + 2, redirect_url_len);
2926 : 12 : bss->network_auth_type_len = 3 + redirect_url_len;
2927 [ + + ]: 965 : } else if (os_strcmp(buf, "ipaddr_type_availability") == 0) {
2928 [ - + ]: 12 : if (hexstr2bin(pos, &bss->ipaddr_type_availability, 1))
2929 : : {
2930 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
2931 : : "ipaddr_type_availability '%s'",
2932 : : line, pos);
2933 : 0 : bss->ipaddr_type_configured = 0;
2934 : 0 : errors++;
2935 : 0 : return errors;
2936 : : }
2937 : 12 : bss->ipaddr_type_configured = 1;
2938 [ + + ]: 953 : } else if (os_strcmp(buf, "domain_name") == 0) {
2939 : 89 : int j, num_domains, domain_len, domain_list_len = 0;
2940 : : char *tok_start, *tok_prev;
2941 : : u8 *domain_list, *domain_ptr;
2942 : :
2943 : 89 : domain_list_len = os_strlen(pos) + 1;
2944 : 89 : domain_list = os_malloc(domain_list_len);
2945 [ - + ]: 89 : if (domain_list == NULL) {
2946 : 0 : errors++;
2947 : 0 : return errors;
2948 : : }
2949 : :
2950 : 89 : domain_ptr = domain_list;
2951 : 89 : tok_prev = pos;
2952 : 89 : num_domains = 1;
2953 [ + + ]: 160 : while ((tok_prev = os_strchr(tok_prev, ','))) {
2954 : 71 : num_domains++;
2955 : 71 : tok_prev++;
2956 : : }
2957 : 89 : tok_prev = pos;
2958 [ + + ]: 249 : for (j = 0; j < num_domains; j++) {
2959 : 160 : tok_start = os_strchr(tok_prev, ',');
2960 [ + + ]: 160 : if (tok_start) {
2961 : 71 : domain_len = tok_start - tok_prev;
2962 : 71 : *domain_ptr = domain_len;
2963 : 71 : os_memcpy(domain_ptr + 1, tok_prev,
2964 : : domain_len);
2965 : 71 : domain_ptr += domain_len + 1;
2966 : 71 : tok_prev = ++tok_start;
2967 : : } else {
2968 : 89 : domain_len = os_strlen(tok_prev);
2969 : 89 : *domain_ptr = domain_len;
2970 : 89 : os_memcpy(domain_ptr + 1, tok_prev,
2971 : : domain_len);
2972 : 89 : domain_ptr += domain_len + 1;
2973 : : }
2974 : : }
2975 : :
2976 : 89 : os_free(bss->domain_name);
2977 : 89 : bss->domain_name = domain_list;
2978 : 89 : bss->domain_name_len = domain_list_len;
2979 [ + + ]: 864 : } else if (os_strcmp(buf, "anqp_3gpp_cell_net") == 0) {
2980 [ - + ]: 92 : if (parse_3gpp_cell_net(bss, pos, line) < 0)
2981 : 0 : errors++;
2982 [ + + ]: 772 : } else if (os_strcmp(buf, "nai_realm") == 0) {
2983 [ - + ]: 162 : if (parse_nai_realm(bss, pos, line) < 0)
2984 : 0 : errors++;
2985 [ - + ]: 610 : } else if (os_strcmp(buf, "gas_frag_limit") == 0) {
2986 : 0 : bss->gas_frag_limit = atoi(pos);
2987 [ + + ]: 610 : } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
2988 : 1 : bss->gas_comeback_delay = atoi(pos);
2989 [ + + ]: 609 : } else if (os_strcmp(buf, "qos_map_set") == 0) {
2990 [ - + ]: 1 : if (parse_qos_map_set(bss, pos, line) < 0)
2991 : 0 : errors++;
2992 : : #endif /* CONFIG_INTERWORKING */
2993 : : #ifdef CONFIG_RADIUS_TEST
2994 : : } else if (os_strcmp(buf, "dump_msk_file") == 0) {
2995 : : os_free(bss->dump_msk_file);
2996 : : bss->dump_msk_file = os_strdup(pos);
2997 : : #endif /* CONFIG_RADIUS_TEST */
2998 : : #ifdef CONFIG_HS20
2999 [ + + ]: 608 : } else if (os_strcmp(buf, "hs20") == 0) {
3000 : 93 : bss->hs20 = atoi(pos);
3001 [ - + ]: 515 : } else if (os_strcmp(buf, "disable_dgaf") == 0) {
3002 : 0 : bss->disable_dgaf = atoi(pos);
3003 [ + + ]: 515 : } else if (os_strcmp(buf, "osen") == 0) {
3004 : 1 : bss->osen = atoi(pos);
3005 [ - + ]: 514 : } else if (os_strcmp(buf, "anqp_domain_id") == 0) {
3006 : 0 : bss->anqp_domain_id = atoi(pos);
3007 [ - + ]: 514 : } else if (os_strcmp(buf, "hs20_deauth_req_timeout") == 0) {
3008 : 0 : bss->hs20_deauth_req_timeout = atoi(pos);
3009 [ + + ]: 514 : } else if (os_strcmp(buf, "hs20_oper_friendly_name") == 0) {
3010 [ - + ]: 24 : if (hs20_parse_oper_friendly_name(bss, pos, line) < 0)
3011 : 0 : errors++;
3012 [ + + ]: 490 : } else if (os_strcmp(buf, "hs20_wan_metrics") == 0) {
3013 [ - + ]: 92 : if (hs20_parse_wan_metrics(bss, pos, line) < 0) {
3014 : 0 : errors++;
3015 : 0 : return errors;
3016 : : }
3017 [ + + ]: 398 : } else if (os_strcmp(buf, "hs20_conn_capab") == 0) {
3018 [ - + ]: 281 : if (hs20_parse_conn_capab(bss, pos, line) < 0) {
3019 : 0 : errors++;
3020 : 0 : return errors;
3021 : : }
3022 [ + + ]: 117 : } else if (os_strcmp(buf, "hs20_operating_class") == 0) {
3023 : : u8 *oper_class;
3024 : : size_t oper_class_len;
3025 : 93 : oper_class_len = os_strlen(pos);
3026 [ + - ][ - + ]: 93 : if (oper_class_len < 2 || (oper_class_len & 0x01)) {
3027 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3028 : : "hs20_operating_class '%s'",
3029 : : line, pos);
3030 : 0 : errors++;
3031 : 0 : return errors;
3032 : : }
3033 : 93 : oper_class_len /= 2;
3034 : 93 : oper_class = os_malloc(oper_class_len);
3035 [ - + ]: 93 : if (oper_class == NULL) {
3036 : 0 : errors++;
3037 : 0 : return errors;
3038 : : }
3039 [ - + ]: 93 : if (hexstr2bin(pos, oper_class, oper_class_len)) {
3040 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3041 : : "hs20_operating_class '%s'",
3042 : : line, pos);
3043 : 0 : os_free(oper_class);
3044 : 0 : errors++;
3045 : 0 : return errors;
3046 : : }
3047 : 93 : os_free(bss->hs20_operating_class);
3048 : 93 : bss->hs20_operating_class = oper_class;
3049 : 93 : bss->hs20_operating_class_len = oper_class_len;
3050 [ + + ]: 24 : } else if (os_strcmp(buf, "hs20_icon") == 0) {
3051 [ - + ]: 2 : if (hs20_parse_icon(bss, pos) < 0) {
3052 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3053 : : "hs20_icon '%s'", line, pos);
3054 : 0 : errors++;
3055 : 0 : return errors;
3056 : : }
3057 [ + + ]: 22 : } else if (os_strcmp(buf, "osu_ssid") == 0) {
3058 [ - + ]: 2 : if (hs20_parse_osu_ssid(bss, pos, line) < 0)
3059 : 0 : errors++;
3060 [ + + ]: 20 : } else if (os_strcmp(buf, "osu_server_uri") == 0) {
3061 [ - + ]: 2 : if (hs20_parse_osu_server_uri(bss, pos, line) < 0)
3062 : 0 : errors++;
3063 [ + + ]: 18 : } else if (os_strcmp(buf, "osu_friendly_name") == 0) {
3064 [ - + ]: 4 : if (hs20_parse_osu_friendly_name(bss, pos, line) < 0)
3065 : 0 : errors++;
3066 [ - + ]: 14 : } else if (os_strcmp(buf, "osu_nai") == 0) {
3067 [ # # ]: 0 : if (hs20_parse_osu_nai(bss, pos, line) < 0)
3068 : 0 : errors++;
3069 [ + + ]: 14 : } else if (os_strcmp(buf, "osu_method_list") == 0) {
3070 [ - + ]: 2 : if (hs20_parse_osu_method_list(bss, pos, line) < 0)
3071 : 0 : errors++;
3072 [ + + ]: 12 : } else if (os_strcmp(buf, "osu_icon") == 0) {
3073 [ - + ]: 2 : if (hs20_parse_osu_icon(bss, pos, line) < 0)
3074 : 0 : errors++;
3075 [ + + ]: 10 : } else if (os_strcmp(buf, "osu_service_desc") == 0) {
3076 [ - + ]: 4 : if (hs20_parse_osu_service_desc(bss, pos, line) < 0)
3077 : 0 : errors++;
3078 [ - + ]: 6 : } else if (os_strcmp(buf, "subscr_remediation_url") == 0) {
3079 : 0 : os_free(bss->subscr_remediation_url);
3080 : 0 : bss->subscr_remediation_url = os_strdup(pos);
3081 [ - + ]: 6 : } else if (os_strcmp(buf, "subscr_remediation_method") == 0) {
3082 : 0 : bss->subscr_remediation_method = atoi(pos);
3083 : : #endif /* CONFIG_HS20 */
3084 : : #ifdef CONFIG_TESTING_OPTIONS
3085 : : #define PARSE_TEST_PROBABILITY(_val) \
3086 : : } else if (os_strcmp(buf, #_val) == 0) { \
3087 : : char *end; \
3088 : : \
3089 : : conf->_val = strtod(pos, &end); \
3090 : : if (*end || conf->_val < 0.0d || \
3091 : : conf->_val > 1.0d) { \
3092 : : wpa_printf(MSG_ERROR, \
3093 : : "Line %d: Invalid value '%s'", \
3094 : : line, pos); \
3095 : : errors++; \
3096 : : return errors; \
3097 : : }
3098 [ - + ][ # # ]: 6 : PARSE_TEST_PROBABILITY(ignore_probe_probability)
[ # # ][ # # ]
3099 [ - + ][ # # ]: 6 : PARSE_TEST_PROBABILITY(ignore_auth_probability)
[ # # ][ # # ]
3100 [ - + ][ # # ]: 6 : PARSE_TEST_PROBABILITY(ignore_assoc_probability)
[ # # ][ # # ]
3101 [ - + ][ # # ]: 6 : PARSE_TEST_PROBABILITY(ignore_reassoc_probability)
[ # # ][ # # ]
3102 [ - + ][ # # ]: 6 : PARSE_TEST_PROBABILITY(corrupt_gtk_rekey_mic_probability)
[ # # ][ # # ]
3103 [ + + ]: 6 : } else if (os_strcmp(buf, "bss_load_test") == 0) {
3104 : 3 : WPA_PUT_LE16(bss->bss_load_test, atoi(pos));
3105 : 3 : pos = os_strchr(pos, ':');
3106 [ - + ]: 3 : if (pos == NULL) {
3107 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3108 : : "bss_load_test", line);
3109 : 0 : return 1;
3110 : : }
3111 : 3 : pos++;
3112 : 3 : bss->bss_load_test[2] = atoi(pos);
3113 : 3 : pos = os_strchr(pos, ':');
3114 [ - + ]: 3 : if (pos == NULL) {
3115 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3116 : : "bss_load_test", line);
3117 : 0 : return 1;
3118 : : }
3119 : 3 : pos++;
3120 : 3 : WPA_PUT_LE16(&bss->bss_load_test[3], atoi(pos));
3121 : 3 : bss->bss_load_test_set = 1;
3122 : : #endif /* CONFIG_TESTING_OPTIONS */
3123 [ - + ]: 3 : } else if (os_strcmp(buf, "vendor_elements") == 0) {
3124 : : struct wpabuf *elems;
3125 : 0 : size_t len = os_strlen(pos);
3126 [ # # ]: 0 : if (len & 0x01) {
3127 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3128 : : "vendor_elements '%s'", line, pos);
3129 : 0 : return 1;
3130 : : }
3131 : 0 : len /= 2;
3132 [ # # ]: 0 : if (len == 0) {
3133 : 0 : wpabuf_free(bss->vendor_elements);
3134 : 0 : bss->vendor_elements = NULL;
3135 : 0 : return 0;
3136 : : }
3137 : :
3138 : 0 : elems = wpabuf_alloc(len);
3139 [ # # ]: 0 : if (elems == NULL)
3140 : 0 : return 1;
3141 : :
3142 [ # # ]: 0 : if (hexstr2bin(pos, wpabuf_put(elems, len), len)) {
3143 : 0 : wpabuf_free(elems);
3144 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3145 : : "vendor_elements '%s'", line, pos);
3146 : 0 : return 1;
3147 : : }
3148 : :
3149 : 0 : wpabuf_free(bss->vendor_elements);
3150 : 0 : bss->vendor_elements = elems;
3151 [ + + ]: 3 : } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) {
3152 : 1 : bss->sae_anti_clogging_threshold = atoi(pos);
3153 [ + - ]: 2 : } else if (os_strcmp(buf, "sae_groups") == 0) {
3154 [ - + ]: 2 : if (hostapd_parse_intlist(&bss->sae_groups, pos)) {
3155 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid "
3156 : : "sae_groups value '%s'", line, pos);
3157 : 0 : return 1;
3158 : : }
3159 [ # # ]: 0 : } else if (os_strcmp(buf, "local_pwr_constraint") == 0) {
3160 : 0 : int val = atoi(pos);
3161 [ # # ][ # # ]: 0 : if (val < 0 || val > 255) {
3162 : 0 : wpa_printf(MSG_ERROR, "Line %d: Invalid local_pwr_constraint %d (expected 0..255)",
3163 : : line, val);
3164 : 0 : return 1;
3165 : : }
3166 : 0 : conf->local_pwr_constraint = val;
3167 [ # # ]: 0 : } else if (os_strcmp(buf, "spectrum_mgmt_required") == 0) {
3168 : 0 : conf->spectrum_mgmt_required = atoi(pos);
3169 : : } else {
3170 : 0 : wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
3171 : : "item '%s'", line, buf);
3172 : 0 : errors++;
3173 : : }
3174 : : }
3175 : :
3176 : 7053 : return errors;
3177 : : }
3178 : :
3179 : :
3180 : : /**
3181 : : * hostapd_config_read - Read and parse a configuration file
3182 : : * @fname: Configuration file name (including path, if needed)
3183 : : * Returns: Allocated configuration data structure
3184 : : */
3185 : 24 : struct hostapd_config * hostapd_config_read(const char *fname)
3186 : : {
3187 : : struct hostapd_config *conf;
3188 : : struct hostapd_bss_config *bss;
3189 : : FILE *f;
3190 : : char buf[512], *pos;
3191 : 24 : int line = 0;
3192 : 24 : int errors = 0;
3193 : : size_t i;
3194 : :
3195 : 24 : f = fopen(fname, "r");
3196 [ - + ]: 24 : if (f == NULL) {
3197 : 0 : wpa_printf(MSG_ERROR, "Could not open configuration file '%s' "
3198 : : "for reading.", fname);
3199 : 0 : return NULL;
3200 : : }
3201 : :
3202 : 24 : conf = hostapd_config_defaults();
3203 [ - + ]: 24 : if (conf == NULL) {
3204 : 0 : fclose(f);
3205 : 0 : return NULL;
3206 : : }
3207 : :
3208 : : /* set default driver based on configuration */
3209 : 24 : conf->driver = wpa_drivers[0];
3210 [ - + ]: 24 : if (conf->driver == NULL) {
3211 : 0 : wpa_printf(MSG_ERROR, "No driver wrappers registered!");
3212 : 0 : hostapd_config_free(conf);
3213 : 0 : fclose(f);
3214 : 0 : return NULL;
3215 : : }
3216 : :
3217 : 24 : bss = conf->last_bss = conf->bss[0];
3218 : :
3219 [ + + ]: 341 : while (fgets(buf, sizeof(buf), f)) {
3220 : 317 : bss = conf->last_bss;
3221 : 317 : line++;
3222 : :
3223 [ - + ]: 317 : if (buf[0] == '#')
3224 : 0 : continue;
3225 : 317 : pos = buf;
3226 [ + - ]: 4366 : while (*pos != '\0') {
3227 [ + + ]: 4366 : if (*pos == '\n') {
3228 : 317 : *pos = '\0';
3229 : 317 : break;
3230 : : }
3231 : 4049 : pos++;
3232 : : }
3233 [ + + ]: 317 : if (buf[0] == '\0')
3234 : 79 : continue;
3235 : :
3236 : 238 : pos = os_strchr(buf, '=');
3237 [ - + ]: 238 : if (pos == NULL) {
3238 : 0 : wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'",
3239 : : line, buf);
3240 : 0 : errors++;
3241 : 0 : continue;
3242 : : }
3243 : 238 : *pos = '\0';
3244 : 238 : pos++;
3245 : 238 : errors += hostapd_config_fill(conf, bss, buf, pos, line);
3246 : : }
3247 : :
3248 : 24 : fclose(f);
3249 : :
3250 [ + + ]: 54 : for (i = 0; i < conf->num_bss; i++)
3251 : 30 : hostapd_set_security_params(conf->bss[i]);
3252 : :
3253 [ - + ]: 24 : if (hostapd_config_check(conf, 1))
3254 : 0 : errors++;
3255 : :
3256 : : #ifndef WPA_IGNORE_CONFIG_ERRORS
3257 [ - + ]: 24 : if (errors) {
3258 : 0 : wpa_printf(MSG_ERROR, "%d errors found in configuration file "
3259 : : "'%s'", errors, fname);
3260 : 0 : hostapd_config_free(conf);
3261 : 0 : conf = NULL;
3262 : : }
3263 : : #endif /* WPA_IGNORE_CONFIG_ERRORS */
3264 : :
3265 : 24 : return conf;
3266 : : }
3267 : :
3268 : :
3269 : 6815 : int hostapd_set_iface(struct hostapd_config *conf,
3270 : : struct hostapd_bss_config *bss, char *field, char *value)
3271 : : {
3272 : : int errors;
3273 : : size_t i;
3274 : :
3275 : 6815 : errors = hostapd_config_fill(conf, bss, field, value, 0);
3276 [ - + ]: 6815 : if (errors) {
3277 : 0 : wpa_printf(MSG_INFO, "Failed to set configuration field '%s' "
3278 : : "to value '%s'", field, value);
3279 : 0 : return -1;
3280 : : }
3281 : :
3282 [ + + ]: 13638 : for (i = 0; i < conf->num_bss; i++)
3283 : 6823 : hostapd_set_security_params(conf->bss[i]);
3284 : :
3285 [ - + ]: 6815 : if (hostapd_config_check(conf, 0)) {
3286 : 0 : wpa_printf(MSG_ERROR, "Configuration check failed");
3287 : 0 : return -1;
3288 : : }
3289 : :
3290 : 6815 : return 0;
3291 : : }
|