1 /* 2 * WPA Supplicant / Configuration backend: text file 3 * Copyright (c) 2003-2012, 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 * This file implements a configuration backend for text files. All the 9 * configuration information is stored in a text file that uses a format 10 * described in the sample configuration file, wpa_supplicant.conf. 11 */ 12 13 #include "includes.h" 14 #ifdef ANDROID 15 #include <sys/stat.h> 16 #endif /* ANDROID */ 17 18 #include "common.h" 19 #include "config.h" 20 #include "base64.h" 21 #include "uuid.h" 22 #include "common/ieee802_1x_defs.h" 23 #include "p2p/p2p.h" 24 #include "eap_peer/eap_methods.h" 25 #include "eap_peer/eap.h" 26 27 28 static int newline_terminated(const char *buf, size_t buflen) 29 { 30 size_t len = os_strlen(buf); 31 if (len == 0) 32 return 0; 33 if (len == buflen - 1 && buf[buflen - 1] != '\r' && 34 buf[len - 1] != '\n') 35 return 0; 36 return 1; 37 } 38 39 40 static void skip_line_end(FILE *stream) 41 { 42 char buf[100]; 43 while (fgets(buf, sizeof(buf), stream)) { 44 buf[sizeof(buf) - 1] = '\0'; 45 if (newline_terminated(buf, sizeof(buf))) 46 return; 47 } 48 } 49 50 51 /** 52 * wpa_config_get_line - Read the next configuration file line 53 * @s: Buffer for the line 54 * @size: The buffer length 55 * @stream: File stream to read from 56 * @line: Pointer to a variable storing the file line number 57 * @_pos: Buffer for the pointer to the beginning of data on the text line or 58 * %NULL if not needed (returned value used instead) 59 * Returns: Pointer to the beginning of data on the text line or %NULL if no 60 * more text lines are available. 61 * 62 * This function reads the next non-empty line from the configuration file and 63 * removes comments. The returned string is guaranteed to be null-terminated. 64 */ 65 static char * wpa_config_get_line(char *s, int size, FILE *stream, int *line, 66 char **_pos) 67 { 68 char *pos, *end, *sstart; 69 70 while (fgets(s, size, stream)) { 71 (*line)++; 72 s[size - 1] = '\0'; 73 if (!newline_terminated(s, size)) { 74 /* 75 * The line was truncated - skip rest of it to avoid 76 * confusing error messages. 77 */ 78 wpa_printf(MSG_INFO, "Long line in configuration file " 79 "truncated"); 80 skip_line_end(stream); 81 } 82 pos = s; 83 84 /* Skip white space from the beginning of line. */ 85 while (*pos == ' ' || *pos == '\t' || *pos == '\r') 86 pos++; 87 88 /* Skip comment lines and empty lines */ 89 if (*pos == '#' || *pos == '\n' || *pos == '\0') 90 continue; 91 92 /* 93 * Remove # comments unless they are within a double quoted 94 * string. 95 */ 96 sstart = os_strchr(pos, '"'); 97 if (sstart) 98 sstart = os_strrchr(sstart + 1, '"'); 99 if (!sstart) 100 sstart = pos; 101 end = os_strchr(sstart, '#'); 102 if (end) 103 *end-- = '\0'; 104 else 105 end = pos + os_strlen(pos) - 1; 106 107 /* Remove trailing white space. */ 108 while (end > pos && 109 (*end == '\n' || *end == ' ' || *end == '\t' || 110 *end == '\r')) 111 *end-- = '\0'; 112 113 if (*pos == '\0') 114 continue; 115 116 if (_pos) 117 *_pos = pos; 118 return pos; 119 } 120 121 if (_pos) 122 *_pos = NULL; 123 return NULL; 124 } 125 126 127 static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) 128 { 129 int errors = 0; 130 131 if (ssid->passphrase) { 132 if (ssid->psk_set) { 133 wpa_printf(MSG_ERROR, "Line %d: both PSK and " 134 "passphrase configured.", line); 135 errors++; 136 } 137 wpa_config_update_psk(ssid); 138 } 139 140 if (ssid->disabled == 2) 141 ssid->p2p_persistent_group = 1; 142 143 if ((ssid->group_cipher & WPA_CIPHER_CCMP) && 144 !(ssid->pairwise_cipher & (WPA_CIPHER_CCMP | WPA_CIPHER_CCMP_256 | 145 WPA_CIPHER_GCMP | WPA_CIPHER_GCMP_256 | 146 WPA_CIPHER_NONE))) { 147 /* Group cipher cannot be stronger than the pairwise cipher. */ 148 wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher" 149 " list since it was not allowed for pairwise " 150 "cipher", line); 151 ssid->group_cipher &= ~WPA_CIPHER_CCMP; 152 } 153 154 if (ssid->mode == WPAS_MODE_MESH && 155 (ssid->key_mgmt != WPA_KEY_MGMT_NONE && 156 ssid->key_mgmt != WPA_KEY_MGMT_SAE)) { 157 wpa_printf(MSG_ERROR, 158 "Line %d: key_mgmt for mesh network should be open or SAE", 159 line); 160 errors++; 161 } 162 163 #ifdef CONFIG_OCV 164 if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION) { 165 wpa_printf(MSG_ERROR, 166 "Line %d: PMF needs to be enabled whenever using OCV", 167 line); 168 errors++; 169 } 170 #endif /* CONFIG_OCV */ 171 172 return errors; 173 } 174 175 176 static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id) 177 { 178 struct wpa_ssid *ssid; 179 int errors = 0, end = 0; 180 char buf[2000], *pos, *pos2; 181 182 wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block", 183 *line); 184 ssid = os_zalloc(sizeof(*ssid)); 185 if (ssid == NULL) 186 return NULL; 187 dl_list_init(&ssid->psk_list); 188 ssid->id = id; 189 190 wpa_config_set_network_defaults(ssid); 191 192 while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { 193 if (os_strcmp(pos, "}") == 0) { 194 end = 1; 195 break; 196 } 197 198 pos2 = os_strchr(pos, '='); 199 if (pos2 == NULL) { 200 wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line " 201 "'%s'.", *line, pos); 202 errors++; 203 continue; 204 } 205 206 *pos2++ = '\0'; 207 if (*pos2 == '"') { 208 if (os_strchr(pos2 + 1, '"') == NULL) { 209 wpa_printf(MSG_ERROR, "Line %d: invalid " 210 "quotation '%s'.", *line, pos2); 211 errors++; 212 continue; 213 } 214 } 215 216 if (wpa_config_set(ssid, pos, pos2, *line) < 0) 217 errors++; 218 } 219 220 if (!end) { 221 wpa_printf(MSG_ERROR, "Line %d: network block was not " 222 "terminated properly.", *line); 223 errors++; 224 } 225 226 errors += wpa_config_validate_network(ssid, *line); 227 228 if (errors) { 229 wpa_config_free_ssid(ssid); 230 ssid = NULL; 231 } 232 233 return ssid; 234 } 235 236 237 static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id) 238 { 239 struct wpa_cred *cred; 240 int errors = 0, end = 0; 241 char buf[256], *pos, *pos2; 242 243 wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line); 244 cred = os_zalloc(sizeof(*cred)); 245 if (cred == NULL) 246 return NULL; 247 cred->id = id; 248 cred->sim_num = DEFAULT_USER_SELECTED_SIM; 249 250 while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { 251 if (os_strcmp(pos, "}") == 0) { 252 end = 1; 253 break; 254 } 255 256 pos2 = os_strchr(pos, '='); 257 if (pos2 == NULL) { 258 wpa_printf(MSG_ERROR, "Line %d: Invalid cred line " 259 "'%s'.", *line, pos); 260 errors++; 261 continue; 262 } 263 264 *pos2++ = '\0'; 265 if (*pos2 == '"') { 266 if (os_strchr(pos2 + 1, '"') == NULL) { 267 wpa_printf(MSG_ERROR, "Line %d: invalid " 268 "quotation '%s'.", *line, pos2); 269 errors++; 270 continue; 271 } 272 } 273 274 if (wpa_config_set_cred(cred, pos, pos2, *line) < 0) 275 errors++; 276 } 277 278 if (!end) { 279 wpa_printf(MSG_ERROR, "Line %d: cred block was not " 280 "terminated properly.", *line); 281 errors++; 282 } 283 284 if (errors) { 285 wpa_config_free_cred(cred); 286 cred = NULL; 287 } 288 289 return cred; 290 } 291 292 293 #ifndef CONFIG_NO_CONFIG_BLOBS 294 static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line, 295 const char *name) 296 { 297 struct wpa_config_blob *blob; 298 char buf[256], *pos; 299 unsigned char *encoded = NULL, *nencoded; 300 int end = 0; 301 size_t encoded_len = 0, len; 302 303 wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'", 304 *line, name); 305 306 while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { 307 if (os_strcmp(pos, "}") == 0) { 308 end = 1; 309 break; 310 } 311 312 len = os_strlen(pos); 313 nencoded = os_realloc(encoded, encoded_len + len); 314 if (nencoded == NULL) { 315 wpa_printf(MSG_ERROR, "Line %d: not enough memory for " 316 "blob", *line); 317 os_free(encoded); 318 return NULL; 319 } 320 encoded = nencoded; 321 os_memcpy(encoded + encoded_len, pos, len); 322 encoded_len += len; 323 } 324 325 if (!end || !encoded) { 326 wpa_printf(MSG_ERROR, "Line %d: blob was not terminated " 327 "properly", *line); 328 os_free(encoded); 329 return NULL; 330 } 331 332 blob = os_zalloc(sizeof(*blob)); 333 if (blob == NULL) { 334 os_free(encoded); 335 return NULL; 336 } 337 blob->name = os_strdup(name); 338 blob->data = base64_decode(encoded, encoded_len, &blob->len); 339 os_free(encoded); 340 341 if (blob->name == NULL || blob->data == NULL) { 342 wpa_config_free_blob(blob); 343 return NULL; 344 } 345 346 return blob; 347 } 348 349 350 static int wpa_config_process_blob(struct wpa_config *config, FILE *f, 351 int *line, char *bname) 352 { 353 char *name_end; 354 struct wpa_config_blob *blob; 355 356 name_end = os_strchr(bname, '='); 357 if (name_end == NULL) { 358 wpa_printf(MSG_ERROR, "Line %d: no blob name terminator", 359 *line); 360 return -1; 361 } 362 *name_end = '\0'; 363 364 blob = wpa_config_read_blob(f, line, bname); 365 if (blob == NULL) { 366 wpa_printf(MSG_ERROR, "Line %d: failed to read blob %s", 367 *line, bname); 368 return -1; 369 } 370 wpa_config_set_blob(config, blob); 371 return 0; 372 } 373 #endif /* CONFIG_NO_CONFIG_BLOBS */ 374 375 376 struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp) 377 { 378 FILE *f; 379 char buf[512], *pos; 380 int errors = 0, line = 0; 381 struct wpa_ssid *ssid, *tail, *head; 382 struct wpa_cred *cred, *cred_tail, *cred_head; 383 struct wpa_config *config; 384 int id = 0; 385 int cred_id = 0; 386 387 if (name == NULL) 388 return NULL; 389 if (cfgp) 390 config = cfgp; 391 else 392 config = wpa_config_alloc_empty(NULL, NULL); 393 if (config == NULL) { 394 wpa_printf(MSG_ERROR, "Failed to allocate config file " 395 "structure"); 396 return NULL; 397 } 398 tail = head = config->ssid; 399 while (tail && tail->next) 400 tail = tail->next; 401 cred_tail = cred_head = config->cred; 402 while (cred_tail && cred_tail->next) 403 cred_tail = cred_tail->next; 404 405 wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); 406 f = fopen(name, "r"); 407 if (f == NULL) { 408 wpa_printf(MSG_ERROR, "Failed to open config file '%s', " 409 "error: %s", name, strerror(errno)); 410 if (config != cfgp) 411 os_free(config); 412 return NULL; 413 } 414 415 while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { 416 if (os_strcmp(pos, "network={") == 0) { 417 ssid = wpa_config_read_network(f, &line, id++); 418 if (ssid == NULL) { 419 wpa_printf(MSG_ERROR, "Line %d: failed to " 420 "parse network block.", line); 421 errors++; 422 continue; 423 } 424 if (head == NULL) { 425 head = tail = ssid; 426 } else { 427 tail->next = ssid; 428 tail = ssid; 429 } 430 if (wpa_config_add_prio_network(config, ssid)) { 431 wpa_printf(MSG_ERROR, "Line %d: failed to add " 432 "network block to priority list.", 433 line); 434 errors++; 435 continue; 436 } 437 } else if (os_strcmp(pos, "cred={") == 0) { 438 cred = wpa_config_read_cred(f, &line, cred_id++); 439 if (cred == NULL) { 440 wpa_printf(MSG_ERROR, "Line %d: failed to " 441 "parse cred block.", line); 442 errors++; 443 continue; 444 } 445 if (cred_head == NULL) { 446 cred_head = cred_tail = cred; 447 } else { 448 cred_tail->next = cred; 449 cred_tail = cred; 450 } 451 #ifndef CONFIG_NO_CONFIG_BLOBS 452 } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { 453 if (wpa_config_process_blob(config, f, &line, pos + 12) 454 < 0) { 455 wpa_printf(MSG_ERROR, "Line %d: failed to " 456 "process blob.", line); 457 errors++; 458 continue; 459 } 460 #endif /* CONFIG_NO_CONFIG_BLOBS */ 461 } else if (wpa_config_process_global(config, pos, line) < 0) { 462 wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " 463 "line '%s'.", line, pos); 464 errors++; 465 continue; 466 } 467 } 468 469 fclose(f); 470 471 config->ssid = head; 472 wpa_config_debug_dump_networks(config); 473 config->cred = cred_head; 474 475 #ifndef WPA_IGNORE_CONFIG_ERRORS 476 if (errors) { 477 if (config != cfgp) 478 wpa_config_free(config); 479 config = NULL; 480 head = NULL; 481 } 482 #endif /* WPA_IGNORE_CONFIG_ERRORS */ 483 484 return config; 485 } 486 487 488 #ifndef CONFIG_NO_CONFIG_WRITE 489 490 static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid) 491 { 492 char *value = wpa_config_get(ssid, field); 493 if (value == NULL) 494 return; 495 fprintf(f, "\t%s=%s\n", field, value); 496 str_clear_free(value); 497 } 498 499 500 static void write_int(FILE *f, const char *field, int value, int def) 501 { 502 if (value == def) 503 return; 504 fprintf(f, "\t%s=%d\n", field, value); 505 } 506 507 508 static void write_bssid(FILE *f, struct wpa_ssid *ssid) 509 { 510 char *value = wpa_config_get(ssid, "bssid"); 511 if (value == NULL) 512 return; 513 fprintf(f, "\tbssid=%s\n", value); 514 os_free(value); 515 } 516 517 518 static void write_bssid_hint(FILE *f, struct wpa_ssid *ssid) 519 { 520 char *value = wpa_config_get(ssid, "bssid_hint"); 521 522 if (!value) 523 return; 524 fprintf(f, "\tbssid_hint=%s\n", value); 525 os_free(value); 526 } 527 528 529 static void write_psk(FILE *f, struct wpa_ssid *ssid) 530 { 531 char *value; 532 533 if (ssid->mem_only_psk) 534 return; 535 536 value = wpa_config_get(ssid, "psk"); 537 if (value == NULL) 538 return; 539 fprintf(f, "\tpsk=%s\n", value); 540 os_free(value); 541 } 542 543 544 static void write_proto(FILE *f, struct wpa_ssid *ssid) 545 { 546 char *value; 547 548 if (ssid->proto == DEFAULT_PROTO) 549 return; 550 551 value = wpa_config_get(ssid, "proto"); 552 if (value == NULL) 553 return; 554 if (value[0]) 555 fprintf(f, "\tproto=%s\n", value); 556 os_free(value); 557 } 558 559 560 static void write_key_mgmt(FILE *f, struct wpa_ssid *ssid) 561 { 562 char *value; 563 564 if (ssid->key_mgmt == DEFAULT_KEY_MGMT) 565 return; 566 567 value = wpa_config_get(ssid, "key_mgmt"); 568 if (value == NULL) 569 return; 570 if (value[0]) 571 fprintf(f, "\tkey_mgmt=%s\n", value); 572 os_free(value); 573 } 574 575 576 static void write_pairwise(FILE *f, struct wpa_ssid *ssid) 577 { 578 char *value; 579 580 if (ssid->pairwise_cipher == DEFAULT_PAIRWISE) 581 return; 582 583 value = wpa_config_get(ssid, "pairwise"); 584 if (value == NULL) 585 return; 586 if (value[0]) 587 fprintf(f, "\tpairwise=%s\n", value); 588 os_free(value); 589 } 590 591 592 static void write_group(FILE *f, struct wpa_ssid *ssid) 593 { 594 char *value; 595 596 if (ssid->group_cipher == DEFAULT_GROUP) 597 return; 598 599 value = wpa_config_get(ssid, "group"); 600 if (value == NULL) 601 return; 602 if (value[0]) 603 fprintf(f, "\tgroup=%s\n", value); 604 os_free(value); 605 } 606 607 608 static void write_group_mgmt(FILE *f, struct wpa_ssid *ssid) 609 { 610 char *value; 611 612 if (!ssid->group_mgmt_cipher) 613 return; 614 615 value = wpa_config_get(ssid, "group_mgmt"); 616 if (!value) 617 return; 618 if (value[0]) 619 fprintf(f, "\tgroup_mgmt=%s\n", value); 620 os_free(value); 621 } 622 623 624 static void write_auth_alg(FILE *f, struct wpa_ssid *ssid) 625 { 626 char *value; 627 628 if (ssid->auth_alg == 0) 629 return; 630 631 value = wpa_config_get(ssid, "auth_alg"); 632 if (value == NULL) 633 return; 634 if (value[0]) 635 fprintf(f, "\tauth_alg=%s\n", value); 636 os_free(value); 637 } 638 639 640 #ifdef IEEE8021X_EAPOL 641 static void write_eap(FILE *f, struct wpa_ssid *ssid) 642 { 643 char *value; 644 645 value = wpa_config_get(ssid, "eap"); 646 if (value == NULL) 647 return; 648 649 if (value[0]) 650 fprintf(f, "\teap=%s\n", value); 651 os_free(value); 652 } 653 #endif /* IEEE8021X_EAPOL */ 654 655 656 static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) 657 { 658 char field[20], *value; 659 int res; 660 661 res = os_snprintf(field, sizeof(field), "wep_key%d", idx); 662 if (os_snprintf_error(sizeof(field), res)) 663 return; 664 value = wpa_config_get(ssid, field); 665 if (value) { 666 fprintf(f, "\t%s=%s\n", field, value); 667 os_free(value); 668 } 669 } 670 671 672 #ifdef CONFIG_P2P 673 674 static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid) 675 { 676 char *value = wpa_config_get(ssid, "go_p2p_dev_addr"); 677 if (value == NULL) 678 return; 679 fprintf(f, "\tgo_p2p_dev_addr=%s\n", value); 680 os_free(value); 681 } 682 683 static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) 684 { 685 char *value = wpa_config_get(ssid, "p2p_client_list"); 686 if (value == NULL) 687 return; 688 fprintf(f, "\tp2p_client_list=%s\n", value); 689 os_free(value); 690 } 691 692 693 static void write_psk_list(FILE *f, struct wpa_ssid *ssid) 694 { 695 struct psk_list_entry *psk; 696 char hex[32 * 2 + 1]; 697 698 dl_list_for_each(psk, &ssid->psk_list, struct psk_list_entry, list) { 699 wpa_snprintf_hex(hex, sizeof(hex), psk->psk, sizeof(psk->psk)); 700 fprintf(f, "\tpsk_list=%s" MACSTR "-%s\n", 701 psk->p2p ? "P2P-" : "", MAC2STR(psk->addr), hex); 702 } 703 } 704 705 #endif /* CONFIG_P2P */ 706 707 708 #ifdef CONFIG_MACSEC 709 710 static void write_mka_cak(FILE *f, struct wpa_ssid *ssid) 711 { 712 char *value; 713 714 if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK)) 715 return; 716 717 value = wpa_config_get(ssid, "mka_cak"); 718 if (!value) 719 return; 720 fprintf(f, "\tmka_cak=%s\n", value); 721 os_free(value); 722 } 723 724 725 static void write_mka_ckn(FILE *f, struct wpa_ssid *ssid) 726 { 727 char *value; 728 729 if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN)) 730 return; 731 732 value = wpa_config_get(ssid, "mka_ckn"); 733 if (!value) 734 return; 735 fprintf(f, "\tmka_ckn=%s\n", value); 736 os_free(value); 737 } 738 739 #endif /* CONFIG_MACSEC */ 740 741 742 static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) 743 { 744 int i; 745 746 #define STR(t) write_str(f, #t, ssid) 747 #define INT(t) write_int(f, #t, ssid->t, 0) 748 #define INTe(t) write_int(f, #t, ssid->eap.t, 0) 749 #define INT_DEF(t, def) write_int(f, #t, ssid->t, def) 750 #define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def) 751 752 STR(ssid); 753 INT(scan_ssid); 754 write_bssid(f, ssid); 755 write_bssid_hint(f, ssid); 756 write_str(f, "bssid_blacklist", ssid); 757 write_str(f, "bssid_whitelist", ssid); 758 write_psk(f, ssid); 759 INT(mem_only_psk); 760 STR(sae_password); 761 STR(sae_password_id); 762 write_proto(f, ssid); 763 write_key_mgmt(f, ssid); 764 INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD); 765 write_pairwise(f, ssid); 766 write_group(f, ssid); 767 write_group_mgmt(f, ssid); 768 write_auth_alg(f, ssid); 769 STR(bgscan); 770 STR(autoscan); 771 STR(scan_freq); 772 #ifdef IEEE8021X_EAPOL 773 write_eap(f, ssid); 774 STR(identity); 775 STR(anonymous_identity); 776 STR(imsi_identity); 777 STR(password); 778 STR(ca_cert); 779 STR(ca_path); 780 STR(client_cert); 781 STR(private_key); 782 STR(private_key_passwd); 783 STR(dh_file); 784 STR(subject_match); 785 STR(check_cert_subject); 786 STR(altsubject_match); 787 STR(domain_suffix_match); 788 STR(domain_match); 789 STR(ca_cert2); 790 STR(ca_path2); 791 STR(client_cert2); 792 STR(private_key2); 793 STR(private_key2_passwd); 794 STR(dh_file2); 795 STR(subject_match2); 796 STR(check_cert_subject2); 797 STR(altsubject_match2); 798 STR(domain_suffix_match2); 799 STR(domain_match2); 800 STR(phase1); 801 STR(phase2); 802 STR(pcsc); 803 STR(pin); 804 STR(engine_id); 805 STR(key_id); 806 STR(cert_id); 807 STR(ca_cert_id); 808 STR(key2_id); 809 STR(pin2); 810 STR(engine2_id); 811 STR(cert2_id); 812 STR(ca_cert2_id); 813 INTe(engine); 814 INTe(engine2); 815 INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS); 816 STR(openssl_ciphers); 817 INTe(erp); 818 #endif /* IEEE8021X_EAPOL */ 819 for (i = 0; i < 4; i++) 820 write_wep_key(f, i, ssid); 821 INT(wep_tx_keyidx); 822 INT(priority); 823 #ifdef IEEE8021X_EAPOL 824 INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND); 825 STR(pac_file); 826 INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE); 827 INTe(ocsp); 828 INT_DEFe(sim_num, DEFAULT_USER_SELECTED_SIM); 829 #endif /* IEEE8021X_EAPOL */ 830 INT(mode); 831 INT(no_auto_peer); 832 INT(frequency); 833 INT(fixed_freq); 834 #ifdef CONFIG_ACS 835 INT(acs); 836 #endif /* CONFIG_ACS */ 837 write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1); 838 INT(disabled); 839 INT(mixed_cell); 840 INT(vht); 841 INT_DEF(ht, 1); 842 INT(ht40); 843 INT_DEF(max_oper_chwidth, DEFAULT_MAX_OPER_CHWIDTH); 844 INT(vht_center_freq1); 845 INT(vht_center_freq2); 846 INT(pbss); 847 INT(wps_disabled); 848 INT(fils_dh_group); 849 #ifdef CONFIG_IEEE80211W 850 write_int(f, "ieee80211w", ssid->ieee80211w, 851 MGMT_FRAME_PROTECTION_DEFAULT); 852 #endif /* CONFIG_IEEE80211W */ 853 STR(id_str); 854 #ifdef CONFIG_P2P 855 write_go_p2p_dev_addr(f, ssid); 856 write_p2p_client_list(f, ssid); 857 write_psk_list(f, ssid); 858 #endif /* CONFIG_P2P */ 859 INT(ap_max_inactivity); 860 INT(dtim_period); 861 INT(beacon_int); 862 #ifdef CONFIG_MACSEC 863 INT(macsec_policy); 864 write_mka_cak(f, ssid); 865 write_mka_ckn(f, ssid); 866 INT(macsec_integ_only); 867 INT(macsec_replay_protect); 868 INT(macsec_replay_window); 869 INT(macsec_port); 870 INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); 871 #endif /* CONFIG_MACSEC */ 872 #ifdef CONFIG_HS20 873 INT(update_identifier); 874 STR(roaming_consortium_selection); 875 #endif /* CONFIG_HS20 */ 876 write_int(f, "mac_addr", ssid->mac_addr, -1); 877 #ifdef CONFIG_MESH 878 STR(mesh_basic_rates); 879 INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES); 880 INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT); 881 INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT); 882 INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT); 883 INT_DEF(mesh_rssi_threshold, DEFAULT_MESH_RSSI_THRESHOLD); 884 #endif /* CONFIG_MESH */ 885 INT(wpa_ptk_rekey); 886 INT(group_rekey); 887 INT(ignore_broadcast_ssid); 888 #ifdef CONFIG_DPP 889 STR(dpp_connector); 890 STR(dpp_netaccesskey); 891 INT(dpp_netaccesskey_expiry); 892 STR(dpp_csign); 893 #endif /* CONFIG_DPP */ 894 INT(owe_group); 895 INT(owe_only); 896 INT(multi_ap_backhaul_sta); 897 INT(ft_eap_pmksa_caching); 898 #ifdef CONFIG_HT_OVERRIDES 899 INT_DEF(disable_ht, DEFAULT_DISABLE_HT); 900 INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40); 901 INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI); 902 INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC); 903 INT(ht40_intolerant); 904 INT_DEF(tx_stbc, DEFAULT_TX_STBC); 905 INT_DEF(rx_stbc, DEFAULT_RX_STBC); 906 INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU); 907 INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR); 908 INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY); 909 STR(ht_mcs); 910 #endif /* CONFIG_HT_OVERRIDES */ 911 #ifdef CONFIG_VHT_OVERRIDES 912 INT(disable_vht); 913 INT(vht_capa); 914 INT(vht_capa_mask); 915 INT_DEF(vht_rx_mcs_nss_1, -1); 916 INT_DEF(vht_rx_mcs_nss_2, -1); 917 INT_DEF(vht_rx_mcs_nss_3, -1); 918 INT_DEF(vht_rx_mcs_nss_4, -1); 919 INT_DEF(vht_rx_mcs_nss_5, -1); 920 INT_DEF(vht_rx_mcs_nss_6, -1); 921 INT_DEF(vht_rx_mcs_nss_7, -1); 922 INT_DEF(vht_rx_mcs_nss_8, -1); 923 INT_DEF(vht_tx_mcs_nss_1, -1); 924 INT_DEF(vht_tx_mcs_nss_2, -1); 925 INT_DEF(vht_tx_mcs_nss_3, -1); 926 INT_DEF(vht_tx_mcs_nss_4, -1); 927 INT_DEF(vht_tx_mcs_nss_5, -1); 928 INT_DEF(vht_tx_mcs_nss_6, -1); 929 INT_DEF(vht_tx_mcs_nss_7, -1); 930 INT_DEF(vht_tx_mcs_nss_8, -1); 931 #endif /* CONFIG_VHT_OVERRIDES */ 932 933 #undef STR 934 #undef INT 935 #undef INT_DEF 936 } 937 938 939 static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) 940 { 941 size_t i; 942 943 if (cred->priority) 944 fprintf(f, "\tpriority=%d\n", cred->priority); 945 if (cred->pcsc) 946 fprintf(f, "\tpcsc=%d\n", cred->pcsc); 947 if (cred->realm) 948 fprintf(f, "\trealm=\"%s\"\n", cred->realm); 949 if (cred->username) 950 fprintf(f, "\tusername=\"%s\"\n", cred->username); 951 if (cred->password && cred->ext_password) 952 fprintf(f, "\tpassword=ext:%s\n", cred->password); 953 else if (cred->password) 954 fprintf(f, "\tpassword=\"%s\"\n", cred->password); 955 if (cred->ca_cert) 956 fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert); 957 if (cred->client_cert) 958 fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert); 959 if (cred->private_key) 960 fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key); 961 if (cred->private_key_passwd) 962 fprintf(f, "\tprivate_key_passwd=\"%s\"\n", 963 cred->private_key_passwd); 964 if (cred->imsi) 965 fprintf(f, "\timsi=\"%s\"\n", cred->imsi); 966 if (cred->milenage) 967 fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage); 968 for (i = 0; i < cred->num_domain; i++) 969 fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]); 970 if (cred->domain_suffix_match) 971 fprintf(f, "\tdomain_suffix_match=\"%s\"\n", 972 cred->domain_suffix_match); 973 if (cred->roaming_consortium_len) { 974 fprintf(f, "\troaming_consortium="); 975 for (i = 0; i < cred->roaming_consortium_len; i++) 976 fprintf(f, "%02x", cred->roaming_consortium[i]); 977 fprintf(f, "\n"); 978 } 979 if (cred->eap_method) { 980 const char *name; 981 name = eap_get_name(cred->eap_method[0].vendor, 982 cred->eap_method[0].method); 983 if (name) 984 fprintf(f, "\teap=%s\n", name); 985 } 986 if (cred->phase1) 987 fprintf(f, "\tphase1=\"%s\"\n", cred->phase1); 988 if (cred->phase2) 989 fprintf(f, "\tphase2=\"%s\"\n", cred->phase2); 990 if (cred->excluded_ssid) { 991 size_t j; 992 for (i = 0; i < cred->num_excluded_ssid; i++) { 993 struct excluded_ssid *e = &cred->excluded_ssid[i]; 994 fprintf(f, "\texcluded_ssid="); 995 for (j = 0; j < e->ssid_len; j++) 996 fprintf(f, "%02x", e->ssid[j]); 997 fprintf(f, "\n"); 998 } 999 } 1000 if (cred->roaming_partner) { 1001 for (i = 0; i < cred->num_roaming_partner; i++) { 1002 struct roaming_partner *p = &cred->roaming_partner[i]; 1003 fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n", 1004 p->fqdn, p->exact_match, p->priority, 1005 p->country); 1006 } 1007 } 1008 if (cred->update_identifier) 1009 fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier); 1010 1011 if (cred->provisioning_sp) 1012 fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp); 1013 if (cred->sp_priority) 1014 fprintf(f, "\tsp_priority=%d\n", cred->sp_priority); 1015 1016 if (cred->min_dl_bandwidth_home) 1017 fprintf(f, "\tmin_dl_bandwidth_home=%u\n", 1018 cred->min_dl_bandwidth_home); 1019 if (cred->min_ul_bandwidth_home) 1020 fprintf(f, "\tmin_ul_bandwidth_home=%u\n", 1021 cred->min_ul_bandwidth_home); 1022 if (cred->min_dl_bandwidth_roaming) 1023 fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n", 1024 cred->min_dl_bandwidth_roaming); 1025 if (cred->min_ul_bandwidth_roaming) 1026 fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n", 1027 cred->min_ul_bandwidth_roaming); 1028 1029 if (cred->max_bss_load) 1030 fprintf(f, "\tmax_bss_load=%u\n", 1031 cred->max_bss_load); 1032 1033 if (cred->ocsp) 1034 fprintf(f, "\tocsp=%d\n", cred->ocsp); 1035 1036 if (cred->num_req_conn_capab) { 1037 for (i = 0; i < cred->num_req_conn_capab; i++) { 1038 int *ports; 1039 1040 fprintf(f, "\treq_conn_capab=%u", 1041 cred->req_conn_capab_proto[i]); 1042 ports = cred->req_conn_capab_port[i]; 1043 if (ports) { 1044 int j; 1045 for (j = 0; ports[j] != -1; j++) { 1046 fprintf(f, "%s%d", j > 0 ? "," : ":", 1047 ports[j]); 1048 } 1049 } 1050 fprintf(f, "\n"); 1051 } 1052 } 1053 1054 if (cred->required_roaming_consortium_len) { 1055 fprintf(f, "\trequired_roaming_consortium="); 1056 for (i = 0; i < cred->required_roaming_consortium_len; i++) 1057 fprintf(f, "%02x", 1058 cred->required_roaming_consortium[i]); 1059 fprintf(f, "\n"); 1060 } 1061 1062 if (cred->num_roaming_consortiums) { 1063 size_t j; 1064 1065 fprintf(f, "\troaming_consortiums=\""); 1066 for (i = 0; i < cred->num_roaming_consortiums; i++) { 1067 if (i > 0) 1068 fprintf(f, ","); 1069 for (j = 0; j < cred->roaming_consortiums_len[i]; j++) 1070 fprintf(f, "%02x", 1071 cred->roaming_consortiums[i][j]); 1072 } 1073 fprintf(f, "\"\n"); 1074 } 1075 1076 if (cred->sim_num != DEFAULT_USER_SELECTED_SIM) 1077 fprintf(f, "\tsim_num=%d\n", cred->sim_num); 1078 } 1079 1080 1081 #ifndef CONFIG_NO_CONFIG_BLOBS 1082 static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob) 1083 { 1084 unsigned char *encoded; 1085 1086 encoded = base64_encode(blob->data, blob->len, NULL); 1087 if (encoded == NULL) 1088 return -1; 1089 1090 fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded); 1091 os_free(encoded); 1092 return 0; 1093 } 1094 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1095 1096 1097 static void write_global_bin(FILE *f, const char *field, 1098 const struct wpabuf *val) 1099 { 1100 size_t i; 1101 const u8 *pos; 1102 1103 if (val == NULL) 1104 return; 1105 1106 fprintf(f, "%s=", field); 1107 pos = wpabuf_head(val); 1108 for (i = 0; i < wpabuf_len(val); i++) 1109 fprintf(f, "%02X", *pos++); 1110 fprintf(f, "\n"); 1111 } 1112 1113 1114 static void wpa_config_write_global(FILE *f, struct wpa_config *config) 1115 { 1116 #ifdef CONFIG_CTRL_IFACE 1117 if (config->ctrl_interface) 1118 fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface); 1119 if (config->ctrl_interface_group) 1120 fprintf(f, "ctrl_interface_group=%s\n", 1121 config->ctrl_interface_group); 1122 #endif /* CONFIG_CTRL_IFACE */ 1123 if (config->eapol_version != DEFAULT_EAPOL_VERSION) 1124 fprintf(f, "eapol_version=%d\n", config->eapol_version); 1125 if (config->ap_scan != DEFAULT_AP_SCAN) 1126 fprintf(f, "ap_scan=%d\n", config->ap_scan); 1127 if (config->disable_scan_offload) 1128 fprintf(f, "disable_scan_offload=%d\n", 1129 config->disable_scan_offload); 1130 if (config->fast_reauth != DEFAULT_FAST_REAUTH) 1131 fprintf(f, "fast_reauth=%d\n", config->fast_reauth); 1132 if (config->opensc_engine_path) 1133 fprintf(f, "opensc_engine_path=%s\n", 1134 config->opensc_engine_path); 1135 if (config->pkcs11_engine_path) 1136 fprintf(f, "pkcs11_engine_path=%s\n", 1137 config->pkcs11_engine_path); 1138 if (config->pkcs11_module_path) 1139 fprintf(f, "pkcs11_module_path=%s\n", 1140 config->pkcs11_module_path); 1141 if (config->openssl_ciphers) 1142 fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers); 1143 if (config->pcsc_reader) 1144 fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader); 1145 if (config->pcsc_pin) 1146 fprintf(f, "pcsc_pin=%s\n", config->pcsc_pin); 1147 if (config->driver_param) 1148 fprintf(f, "driver_param=%s\n", config->driver_param); 1149 if (config->dot11RSNAConfigPMKLifetime) 1150 fprintf(f, "dot11RSNAConfigPMKLifetime=%u\n", 1151 config->dot11RSNAConfigPMKLifetime); 1152 if (config->dot11RSNAConfigPMKReauthThreshold) 1153 fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%u\n", 1154 config->dot11RSNAConfigPMKReauthThreshold); 1155 if (config->dot11RSNAConfigSATimeout) 1156 fprintf(f, "dot11RSNAConfigSATimeout=%u\n", 1157 config->dot11RSNAConfigSATimeout); 1158 if (config->update_config) 1159 fprintf(f, "update_config=%d\n", config->update_config); 1160 #ifdef CONFIG_WPS 1161 if (!is_nil_uuid(config->uuid)) { 1162 char buf[40]; 1163 uuid_bin2str(config->uuid, buf, sizeof(buf)); 1164 fprintf(f, "uuid=%s\n", buf); 1165 } 1166 if (config->auto_uuid) 1167 fprintf(f, "auto_uuid=%d\n", config->auto_uuid); 1168 if (config->device_name) 1169 fprintf(f, "device_name=%s\n", config->device_name); 1170 if (config->manufacturer) 1171 fprintf(f, "manufacturer=%s\n", config->manufacturer); 1172 if (config->model_name) 1173 fprintf(f, "model_name=%s\n", config->model_name); 1174 if (config->model_number) 1175 fprintf(f, "model_number=%s\n", config->model_number); 1176 if (config->serial_number) 1177 fprintf(f, "serial_number=%s\n", config->serial_number); 1178 { 1179 char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; 1180 buf = wps_dev_type_bin2str(config->device_type, 1181 _buf, sizeof(_buf)); 1182 if (os_strcmp(buf, "0-00000000-0") != 0) 1183 fprintf(f, "device_type=%s\n", buf); 1184 } 1185 if (WPA_GET_BE32(config->os_version)) 1186 fprintf(f, "os_version=%08x\n", 1187 WPA_GET_BE32(config->os_version)); 1188 if (config->config_methods) 1189 fprintf(f, "config_methods=%s\n", config->config_methods); 1190 if (config->wps_cred_processing) 1191 fprintf(f, "wps_cred_processing=%d\n", 1192 config->wps_cred_processing); 1193 if (config->wps_cred_add_sae) 1194 fprintf(f, "wps_cred_add_sae=%d\n", 1195 config->wps_cred_add_sae); 1196 if (config->wps_vendor_ext_m1) { 1197 int i, len = wpabuf_len(config->wps_vendor_ext_m1); 1198 const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1); 1199 if (len > 0) { 1200 fprintf(f, "wps_vendor_ext_m1="); 1201 for (i = 0; i < len; i++) 1202 fprintf(f, "%02x", *p++); 1203 fprintf(f, "\n"); 1204 } 1205 } 1206 #endif /* CONFIG_WPS */ 1207 #ifdef CONFIG_P2P 1208 { 1209 int i; 1210 char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; 1211 1212 for (i = 0; i < config->num_sec_device_types; i++) { 1213 buf = wps_dev_type_bin2str(config->sec_device_type[i], 1214 _buf, sizeof(_buf)); 1215 if (buf) 1216 fprintf(f, "sec_device_type=%s\n", buf); 1217 } 1218 } 1219 if (config->p2p_listen_reg_class) 1220 fprintf(f, "p2p_listen_reg_class=%d\n", 1221 config->p2p_listen_reg_class); 1222 if (config->p2p_listen_channel) 1223 fprintf(f, "p2p_listen_channel=%d\n", 1224 config->p2p_listen_channel); 1225 if (config->p2p_oper_reg_class) 1226 fprintf(f, "p2p_oper_reg_class=%d\n", 1227 config->p2p_oper_reg_class); 1228 if (config->p2p_oper_channel) 1229 fprintf(f, "p2p_oper_channel=%d\n", config->p2p_oper_channel); 1230 if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT) 1231 fprintf(f, "p2p_go_intent=%d\n", config->p2p_go_intent); 1232 if (config->p2p_ssid_postfix) 1233 fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix); 1234 if (config->persistent_reconnect) 1235 fprintf(f, "persistent_reconnect=%d\n", 1236 config->persistent_reconnect); 1237 if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS) 1238 fprintf(f, "p2p_intra_bss=%d\n", config->p2p_intra_bss); 1239 if (config->p2p_group_idle) 1240 fprintf(f, "p2p_group_idle=%d\n", config->p2p_group_idle); 1241 if (config->p2p_passphrase_len) 1242 fprintf(f, "p2p_passphrase_len=%u\n", 1243 config->p2p_passphrase_len); 1244 if (config->p2p_pref_chan) { 1245 unsigned int i; 1246 fprintf(f, "p2p_pref_chan="); 1247 for (i = 0; i < config->num_p2p_pref_chan; i++) { 1248 fprintf(f, "%s%u:%u", i > 0 ? "," : "", 1249 config->p2p_pref_chan[i].op_class, 1250 config->p2p_pref_chan[i].chan); 1251 } 1252 fprintf(f, "\n"); 1253 } 1254 if (config->p2p_no_go_freq.num) { 1255 char *val = freq_range_list_str(&config->p2p_no_go_freq); 1256 if (val) { 1257 fprintf(f, "p2p_no_go_freq=%s\n", val); 1258 os_free(val); 1259 } 1260 } 1261 if (config->p2p_add_cli_chan) 1262 fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan); 1263 if (config->p2p_optimize_listen_chan != 1264 DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN) 1265 fprintf(f, "p2p_optimize_listen_chan=%d\n", 1266 config->p2p_optimize_listen_chan); 1267 if (config->p2p_go_ht40) 1268 fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40); 1269 if (config->p2p_go_vht) 1270 fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht); 1271 if (config->p2p_go_he) 1272 fprintf(f, "p2p_go_he=%d\n", config->p2p_go_he); 1273 if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW) 1274 fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow); 1275 if (config->p2p_disabled) 1276 fprintf(f, "p2p_disabled=%d\n", config->p2p_disabled); 1277 if (config->p2p_no_group_iface) 1278 fprintf(f, "p2p_no_group_iface=%d\n", 1279 config->p2p_no_group_iface); 1280 if (config->p2p_ignore_shared_freq) 1281 fprintf(f, "p2p_ignore_shared_freq=%d\n", 1282 config->p2p_ignore_shared_freq); 1283 if (config->p2p_cli_probe) 1284 fprintf(f, "p2p_cli_probe=%d\n", config->p2p_cli_probe); 1285 if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE) 1286 fprintf(f, "p2p_go_freq_change_policy=%u\n", 1287 config->p2p_go_freq_change_policy); 1288 if (WPA_GET_BE32(config->ip_addr_go)) 1289 fprintf(f, "ip_addr_go=%u.%u.%u.%u\n", 1290 config->ip_addr_go[0], config->ip_addr_go[1], 1291 config->ip_addr_go[2], config->ip_addr_go[3]); 1292 if (WPA_GET_BE32(config->ip_addr_mask)) 1293 fprintf(f, "ip_addr_mask=%u.%u.%u.%u\n", 1294 config->ip_addr_mask[0], config->ip_addr_mask[1], 1295 config->ip_addr_mask[2], config->ip_addr_mask[3]); 1296 if (WPA_GET_BE32(config->ip_addr_start)) 1297 fprintf(f, "ip_addr_start=%u.%u.%u.%u\n", 1298 config->ip_addr_start[0], config->ip_addr_start[1], 1299 config->ip_addr_start[2], config->ip_addr_start[3]); 1300 if (WPA_GET_BE32(config->ip_addr_end)) 1301 fprintf(f, "ip_addr_end=%u.%u.%u.%u\n", 1302 config->ip_addr_end[0], config->ip_addr_end[1], 1303 config->ip_addr_end[2], config->ip_addr_end[3]); 1304 #endif /* CONFIG_P2P */ 1305 if (config->country[0] && config->country[1]) { 1306 fprintf(f, "country=%c%c\n", 1307 config->country[0], config->country[1]); 1308 } 1309 if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT) 1310 fprintf(f, "bss_max_count=%u\n", config->bss_max_count); 1311 if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE) 1312 fprintf(f, "bss_expiration_age=%u\n", 1313 config->bss_expiration_age); 1314 if (config->bss_expiration_scan_count != 1315 DEFAULT_BSS_EXPIRATION_SCAN_COUNT) 1316 fprintf(f, "bss_expiration_scan_count=%u\n", 1317 config->bss_expiration_scan_count); 1318 if (config->filter_ssids) 1319 fprintf(f, "filter_ssids=%d\n", config->filter_ssids); 1320 if (config->filter_rssi) 1321 fprintf(f, "filter_rssi=%d\n", config->filter_rssi); 1322 if (config->max_num_sta != DEFAULT_MAX_NUM_STA) 1323 fprintf(f, "max_num_sta=%u\n", config->max_num_sta); 1324 if (config->ap_isolate != DEFAULT_AP_ISOLATE) 1325 fprintf(f, "ap_isolate=%u\n", config->ap_isolate); 1326 if (config->disassoc_low_ack) 1327 fprintf(f, "disassoc_low_ack=%d\n", config->disassoc_low_ack); 1328 #ifdef CONFIG_HS20 1329 if (config->hs20) 1330 fprintf(f, "hs20=1\n"); 1331 #endif /* CONFIG_HS20 */ 1332 #ifdef CONFIG_INTERWORKING 1333 if (config->interworking) 1334 fprintf(f, "interworking=%d\n", config->interworking); 1335 if (!is_zero_ether_addr(config->hessid)) 1336 fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid)); 1337 if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE) 1338 fprintf(f, "access_network_type=%d\n", 1339 config->access_network_type); 1340 if (config->go_interworking) 1341 fprintf(f, "go_interworking=%d\n", config->go_interworking); 1342 if (config->go_access_network_type) 1343 fprintf(f, "go_access_network_type=%d\n", 1344 config->go_access_network_type); 1345 if (config->go_internet) 1346 fprintf(f, "go_internet=%d\n", config->go_internet); 1347 if (config->go_venue_group) 1348 fprintf(f, "go_venue_group=%d\n", config->go_venue_group); 1349 if (config->go_venue_type) 1350 fprintf(f, "go_venue_type=%d\n", config->go_venue_type); 1351 #endif /* CONFIG_INTERWORKING */ 1352 if (config->pbc_in_m1) 1353 fprintf(f, "pbc_in_m1=%d\n", config->pbc_in_m1); 1354 if (config->wps_nfc_pw_from_config) { 1355 if (config->wps_nfc_dev_pw_id) 1356 fprintf(f, "wps_nfc_dev_pw_id=%d\n", 1357 config->wps_nfc_dev_pw_id); 1358 write_global_bin(f, "wps_nfc_dh_pubkey", 1359 config->wps_nfc_dh_pubkey); 1360 write_global_bin(f, "wps_nfc_dh_privkey", 1361 config->wps_nfc_dh_privkey); 1362 write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw); 1363 } 1364 1365 if (config->ext_password_backend) 1366 fprintf(f, "ext_password_backend=%s\n", 1367 config->ext_password_backend); 1368 if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY) 1369 fprintf(f, "p2p_go_max_inactivity=%d\n", 1370 config->p2p_go_max_inactivity); 1371 if (config->auto_interworking) 1372 fprintf(f, "auto_interworking=%d\n", 1373 config->auto_interworking); 1374 if (config->okc) 1375 fprintf(f, "okc=%d\n", config->okc); 1376 if (config->pmf) 1377 fprintf(f, "pmf=%d\n", config->pmf); 1378 if (config->dtim_period) 1379 fprintf(f, "dtim_period=%d\n", config->dtim_period); 1380 if (config->beacon_int) 1381 fprintf(f, "beacon_int=%d\n", config->beacon_int); 1382 1383 if (config->sae_groups) { 1384 int i; 1385 fprintf(f, "sae_groups="); 1386 for (i = 0; config->sae_groups[i] > 0; i++) { 1387 fprintf(f, "%s%d", i > 0 ? " " : "", 1388 config->sae_groups[i]); 1389 } 1390 fprintf(f, "\n"); 1391 } 1392 1393 if (config->ap_vendor_elements) { 1394 int i, len = wpabuf_len(config->ap_vendor_elements); 1395 const u8 *p = wpabuf_head_u8(config->ap_vendor_elements); 1396 if (len > 0) { 1397 fprintf(f, "ap_vendor_elements="); 1398 for (i = 0; i < len; i++) 1399 fprintf(f, "%02x", *p++); 1400 fprintf(f, "\n"); 1401 } 1402 } 1403 1404 if (config->ignore_old_scan_res) 1405 fprintf(f, "ignore_old_scan_res=%d\n", 1406 config->ignore_old_scan_res); 1407 1408 if (config->freq_list && config->freq_list[0]) { 1409 int i; 1410 fprintf(f, "freq_list="); 1411 for (i = 0; config->freq_list[i]; i++) { 1412 fprintf(f, "%s%d", i > 0 ? " " : "", 1413 config->freq_list[i]); 1414 } 1415 fprintf(f, "\n"); 1416 } 1417 if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ) 1418 fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq); 1419 1420 if (config->sched_scan_interval) 1421 fprintf(f, "sched_scan_interval=%u\n", 1422 config->sched_scan_interval); 1423 1424 if (config->sched_scan_start_delay) 1425 fprintf(f, "sched_scan_start_delay=%u\n", 1426 config->sched_scan_start_delay); 1427 1428 if (config->external_sim) 1429 fprintf(f, "external_sim=%d\n", config->external_sim); 1430 1431 if (config->tdls_external_control) 1432 fprintf(f, "tdls_external_control=%d\n", 1433 config->tdls_external_control); 1434 1435 if (config->wowlan_triggers) 1436 fprintf(f, "wowlan_triggers=%s\n", 1437 config->wowlan_triggers); 1438 1439 if (config->bgscan) 1440 fprintf(f, "bgscan=\"%s\"\n", config->bgscan); 1441 1442 if (config->autoscan) 1443 fprintf(f, "autoscan=%s\n", config->autoscan); 1444 1445 if (config->p2p_search_delay != DEFAULT_P2P_SEARCH_DELAY) 1446 fprintf(f, "p2p_search_delay=%u\n", 1447 config->p2p_search_delay); 1448 1449 if (config->mac_addr) 1450 fprintf(f, "mac_addr=%d\n", config->mac_addr); 1451 1452 if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME) 1453 fprintf(f, "rand_addr_lifetime=%u\n", 1454 config->rand_addr_lifetime); 1455 1456 if (config->preassoc_mac_addr) 1457 fprintf(f, "preassoc_mac_addr=%d\n", config->preassoc_mac_addr); 1458 1459 if (config->key_mgmt_offload != DEFAULT_KEY_MGMT_OFFLOAD) 1460 fprintf(f, "key_mgmt_offload=%d\n", config->key_mgmt_offload); 1461 1462 if (config->user_mpm != DEFAULT_USER_MPM) 1463 fprintf(f, "user_mpm=%d\n", config->user_mpm); 1464 1465 if (config->max_peer_links != DEFAULT_MAX_PEER_LINKS) 1466 fprintf(f, "max_peer_links=%d\n", config->max_peer_links); 1467 1468 if (config->cert_in_cb != DEFAULT_CERT_IN_CB) 1469 fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb); 1470 1471 if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY) 1472 fprintf(f, "mesh_max_inactivity=%d\n", 1473 config->mesh_max_inactivity); 1474 1475 if (config->dot11RSNASAERetransPeriod != 1476 DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD) 1477 fprintf(f, "dot11RSNASAERetransPeriod=%d\n", 1478 config->dot11RSNASAERetransPeriod); 1479 1480 if (config->passive_scan) 1481 fprintf(f, "passive_scan=%d\n", config->passive_scan); 1482 1483 if (config->reassoc_same_bss_optim) 1484 fprintf(f, "reassoc_same_bss_optim=%d\n", 1485 config->reassoc_same_bss_optim); 1486 1487 if (config->wps_priority) 1488 fprintf(f, "wps_priority=%d\n", config->wps_priority); 1489 1490 if (config->wpa_rsc_relaxation != DEFAULT_WPA_RSC_RELAXATION) 1491 fprintf(f, "wpa_rsc_relaxation=%d\n", 1492 config->wpa_rsc_relaxation); 1493 1494 if (config->sched_scan_plans) 1495 fprintf(f, "sched_scan_plans=%s\n", config->sched_scan_plans); 1496 1497 #ifdef CONFIG_MBO 1498 if (config->non_pref_chan) 1499 fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan); 1500 if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA) 1501 fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa); 1502 if (config->disassoc_imminent_rssi_threshold != 1503 DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD) 1504 fprintf(f, "disassoc_imminent_rssi_threshold=%d\n", 1505 config->disassoc_imminent_rssi_threshold); 1506 if (config->oce != DEFAULT_OCE_SUPPORT) 1507 fprintf(f, "oce=%u\n", config->oce); 1508 #endif /* CONFIG_MBO */ 1509 1510 if (config->gas_address3) 1511 fprintf(f, "gas_address3=%d\n", config->gas_address3); 1512 1513 if (config->ftm_responder) 1514 fprintf(f, "ftm_responder=%d\n", config->ftm_responder); 1515 if (config->ftm_initiator) 1516 fprintf(f, "ftm_initiator=%d\n", config->ftm_initiator); 1517 1518 if (config->osu_dir) 1519 fprintf(f, "osu_dir=%s\n", config->osu_dir); 1520 1521 if (config->fst_group_id) 1522 fprintf(f, "fst_group_id=%s\n", config->fst_group_id); 1523 if (config->fst_priority) 1524 fprintf(f, "fst_priority=%d\n", config->fst_priority); 1525 if (config->fst_llt) 1526 fprintf(f, "fst_llt=%d\n", config->fst_llt); 1527 1528 if (config->gas_rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME) 1529 fprintf(f, "gas_rand_addr_lifetime=%u\n", 1530 config->gas_rand_addr_lifetime); 1531 if (config->gas_rand_mac_addr) 1532 fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr); 1533 if (config->dpp_config_processing) 1534 fprintf(f, "dpp_config_processing=%d\n", 1535 config->dpp_config_processing); 1536 if (config->coloc_intf_reporting) 1537 fprintf(f, "coloc_intf_reporting=%d\n", 1538 config->coloc_intf_reporting); 1539 if (config->p2p_device_random_mac_addr) 1540 fprintf(f, "p2p_device_random_mac_addr=%d\n", 1541 config->p2p_device_random_mac_addr); 1542 if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr)) 1543 fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n", 1544 MAC2STR(config->p2p_device_persistent_mac_addr)); 1545 if (config->p2p_interface_random_mac_addr) 1546 fprintf(f, "p2p_interface_random_mac_addr=%d\n", 1547 config->p2p_interface_random_mac_addr); 1548 if (config->disable_btm) 1549 fprintf(f, "disable_btm=1\n"); 1550 } 1551 1552 #endif /* CONFIG_NO_CONFIG_WRITE */ 1553 1554 1555 int wpa_config_write(const char *name, struct wpa_config *config) 1556 { 1557 #ifndef CONFIG_NO_CONFIG_WRITE 1558 FILE *f; 1559 struct wpa_ssid *ssid; 1560 struct wpa_cred *cred; 1561 #ifndef CONFIG_NO_CONFIG_BLOBS 1562 struct wpa_config_blob *blob; 1563 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1564 int ret = 0; 1565 const char *orig_name = name; 1566 int tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */ 1567 char *tmp_name = os_malloc(tmp_len); 1568 1569 if (tmp_name) { 1570 os_snprintf(tmp_name, tmp_len, "%s.tmp", name); 1571 name = tmp_name; 1572 } 1573 1574 wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); 1575 1576 f = fopen(name, "w"); 1577 if (f == NULL) { 1578 wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); 1579 os_free(tmp_name); 1580 return -1; 1581 } 1582 1583 wpa_config_write_global(f, config); 1584 1585 for (cred = config->cred; cred; cred = cred->next) { 1586 if (cred->temporary) 1587 continue; 1588 fprintf(f, "\ncred={\n"); 1589 wpa_config_write_cred(f, cred); 1590 fprintf(f, "}\n"); 1591 } 1592 1593 for (ssid = config->ssid; ssid; ssid = ssid->next) { 1594 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) 1595 continue; /* do not save temporary networks */ 1596 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && 1597 !ssid->passphrase) 1598 continue; /* do not save invalid network */ 1599 fprintf(f, "\nnetwork={\n"); 1600 wpa_config_write_network(f, ssid); 1601 fprintf(f, "}\n"); 1602 } 1603 1604 #ifndef CONFIG_NO_CONFIG_BLOBS 1605 for (blob = config->blobs; blob; blob = blob->next) { 1606 ret = wpa_config_write_blob(f, blob); 1607 if (ret) 1608 break; 1609 } 1610 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1611 1612 os_fdatasync(f); 1613 1614 fclose(f); 1615 1616 if (tmp_name) { 1617 int chmod_ret = 0; 1618 1619 #ifdef ANDROID 1620 chmod_ret = chmod(tmp_name, 1621 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 1622 #endif /* ANDROID */ 1623 if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0) 1624 ret = -1; 1625 1626 os_free(tmp_name); 1627 } 1628 1629 wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", 1630 orig_name, ret ? "un" : ""); 1631 return ret; 1632 #else /* CONFIG_NO_CONFIG_WRITE */ 1633 return -1; 1634 #endif /* CONFIG_NO_CONFIG_WRITE */ 1635 } 1636