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