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 #ifdef CONFIG_HT_OVERRIDES 898 INT_DEF(disable_ht, DEFAULT_DISABLE_HT); 899 INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40); 900 INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI); 901 INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC); 902 INT(ht40_intolerant); 903 INT_DEF(tx_stbc, DEFAULT_TX_STBC); 904 INT_DEF(rx_stbc, DEFAULT_RX_STBC); 905 INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU); 906 INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR); 907 INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY); 908 STR(ht_mcs); 909 #endif /* CONFIG_HT_OVERRIDES */ 910 #ifdef CONFIG_VHT_OVERRIDES 911 INT(disable_vht); 912 INT(vht_capa); 913 INT(vht_capa_mask); 914 INT_DEF(vht_rx_mcs_nss_1, -1); 915 INT_DEF(vht_rx_mcs_nss_2, -1); 916 INT_DEF(vht_rx_mcs_nss_3, -1); 917 INT_DEF(vht_rx_mcs_nss_4, -1); 918 INT_DEF(vht_rx_mcs_nss_5, -1); 919 INT_DEF(vht_rx_mcs_nss_6, -1); 920 INT_DEF(vht_rx_mcs_nss_7, -1); 921 INT_DEF(vht_rx_mcs_nss_8, -1); 922 INT_DEF(vht_tx_mcs_nss_1, -1); 923 INT_DEF(vht_tx_mcs_nss_2, -1); 924 INT_DEF(vht_tx_mcs_nss_3, -1); 925 INT_DEF(vht_tx_mcs_nss_4, -1); 926 INT_DEF(vht_tx_mcs_nss_5, -1); 927 INT_DEF(vht_tx_mcs_nss_6, -1); 928 INT_DEF(vht_tx_mcs_nss_7, -1); 929 INT_DEF(vht_tx_mcs_nss_8, -1); 930 #endif /* CONFIG_VHT_OVERRIDES */ 931 932 #undef STR 933 #undef INT 934 #undef INT_DEF 935 } 936 937 938 static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) 939 { 940 size_t i; 941 942 if (cred->priority) 943 fprintf(f, "\tpriority=%d\n", cred->priority); 944 if (cred->pcsc) 945 fprintf(f, "\tpcsc=%d\n", cred->pcsc); 946 if (cred->realm) 947 fprintf(f, "\trealm=\"%s\"\n", cred->realm); 948 if (cred->username) 949 fprintf(f, "\tusername=\"%s\"\n", cred->username); 950 if (cred->password && cred->ext_password) 951 fprintf(f, "\tpassword=ext:%s\n", cred->password); 952 else if (cred->password) 953 fprintf(f, "\tpassword=\"%s\"\n", cred->password); 954 if (cred->ca_cert) 955 fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert); 956 if (cred->client_cert) 957 fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert); 958 if (cred->private_key) 959 fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key); 960 if (cred->private_key_passwd) 961 fprintf(f, "\tprivate_key_passwd=\"%s\"\n", 962 cred->private_key_passwd); 963 if (cred->imsi) 964 fprintf(f, "\timsi=\"%s\"\n", cred->imsi); 965 if (cred->milenage) 966 fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage); 967 for (i = 0; i < cred->num_domain; i++) 968 fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]); 969 if (cred->domain_suffix_match) 970 fprintf(f, "\tdomain_suffix_match=\"%s\"\n", 971 cred->domain_suffix_match); 972 if (cred->roaming_consortium_len) { 973 fprintf(f, "\troaming_consortium="); 974 for (i = 0; i < cred->roaming_consortium_len; i++) 975 fprintf(f, "%02x", cred->roaming_consortium[i]); 976 fprintf(f, "\n"); 977 } 978 if (cred->eap_method) { 979 const char *name; 980 name = eap_get_name(cred->eap_method[0].vendor, 981 cred->eap_method[0].method); 982 if (name) 983 fprintf(f, "\teap=%s\n", name); 984 } 985 if (cred->phase1) 986 fprintf(f, "\tphase1=\"%s\"\n", cred->phase1); 987 if (cred->phase2) 988 fprintf(f, "\tphase2=\"%s\"\n", cred->phase2); 989 if (cred->excluded_ssid) { 990 size_t j; 991 for (i = 0; i < cred->num_excluded_ssid; i++) { 992 struct excluded_ssid *e = &cred->excluded_ssid[i]; 993 fprintf(f, "\texcluded_ssid="); 994 for (j = 0; j < e->ssid_len; j++) 995 fprintf(f, "%02x", e->ssid[j]); 996 fprintf(f, "\n"); 997 } 998 } 999 if (cred->roaming_partner) { 1000 for (i = 0; i < cred->num_roaming_partner; i++) { 1001 struct roaming_partner *p = &cred->roaming_partner[i]; 1002 fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n", 1003 p->fqdn, p->exact_match, p->priority, 1004 p->country); 1005 } 1006 } 1007 if (cred->update_identifier) 1008 fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier); 1009 1010 if (cred->provisioning_sp) 1011 fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp); 1012 if (cred->sp_priority) 1013 fprintf(f, "\tsp_priority=%d\n", cred->sp_priority); 1014 1015 if (cred->min_dl_bandwidth_home) 1016 fprintf(f, "\tmin_dl_bandwidth_home=%u\n", 1017 cred->min_dl_bandwidth_home); 1018 if (cred->min_ul_bandwidth_home) 1019 fprintf(f, "\tmin_ul_bandwidth_home=%u\n", 1020 cred->min_ul_bandwidth_home); 1021 if (cred->min_dl_bandwidth_roaming) 1022 fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n", 1023 cred->min_dl_bandwidth_roaming); 1024 if (cred->min_ul_bandwidth_roaming) 1025 fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n", 1026 cred->min_ul_bandwidth_roaming); 1027 1028 if (cred->max_bss_load) 1029 fprintf(f, "\tmax_bss_load=%u\n", 1030 cred->max_bss_load); 1031 1032 if (cred->ocsp) 1033 fprintf(f, "\tocsp=%d\n", cred->ocsp); 1034 1035 if (cred->num_req_conn_capab) { 1036 for (i = 0; i < cred->num_req_conn_capab; i++) { 1037 int *ports; 1038 1039 fprintf(f, "\treq_conn_capab=%u", 1040 cred->req_conn_capab_proto[i]); 1041 ports = cred->req_conn_capab_port[i]; 1042 if (ports) { 1043 int j; 1044 for (j = 0; ports[j] != -1; j++) { 1045 fprintf(f, "%s%d", j > 0 ? "," : ":", 1046 ports[j]); 1047 } 1048 } 1049 fprintf(f, "\n"); 1050 } 1051 } 1052 1053 if (cred->required_roaming_consortium_len) { 1054 fprintf(f, "\trequired_roaming_consortium="); 1055 for (i = 0; i < cred->required_roaming_consortium_len; i++) 1056 fprintf(f, "%02x", 1057 cred->required_roaming_consortium[i]); 1058 fprintf(f, "\n"); 1059 } 1060 1061 if (cred->num_roaming_consortiums) { 1062 size_t j; 1063 1064 fprintf(f, "\troaming_consortiums=\""); 1065 for (i = 0; i < cred->num_roaming_consortiums; i++) { 1066 if (i > 0) 1067 fprintf(f, ","); 1068 for (j = 0; j < cred->roaming_consortiums_len[i]; j++) 1069 fprintf(f, "%02x", 1070 cred->roaming_consortiums[i][j]); 1071 } 1072 fprintf(f, "\"\n"); 1073 } 1074 1075 if (cred->sim_num != DEFAULT_USER_SELECTED_SIM) 1076 fprintf(f, "\tsim_num=%d\n", cred->sim_num); 1077 } 1078 1079 1080 #ifndef CONFIG_NO_CONFIG_BLOBS 1081 static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob) 1082 { 1083 unsigned char *encoded; 1084 1085 encoded = base64_encode(blob->data, blob->len, NULL); 1086 if (encoded == NULL) 1087 return -1; 1088 1089 fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded); 1090 os_free(encoded); 1091 return 0; 1092 } 1093 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1094 1095 1096 static void write_global_bin(FILE *f, const char *field, 1097 const struct wpabuf *val) 1098 { 1099 size_t i; 1100 const u8 *pos; 1101 1102 if (val == NULL) 1103 return; 1104 1105 fprintf(f, "%s=", field); 1106 pos = wpabuf_head(val); 1107 for (i = 0; i < wpabuf_len(val); i++) 1108 fprintf(f, "%02X", *pos++); 1109 fprintf(f, "\n"); 1110 } 1111 1112 1113 static void wpa_config_write_global(FILE *f, struct wpa_config *config) 1114 { 1115 #ifdef CONFIG_CTRL_IFACE 1116 if (config->ctrl_interface) 1117 fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface); 1118 if (config->ctrl_interface_group) 1119 fprintf(f, "ctrl_interface_group=%s\n", 1120 config->ctrl_interface_group); 1121 #endif /* CONFIG_CTRL_IFACE */ 1122 if (config->eapol_version != DEFAULT_EAPOL_VERSION) 1123 fprintf(f, "eapol_version=%d\n", config->eapol_version); 1124 if (config->ap_scan != DEFAULT_AP_SCAN) 1125 fprintf(f, "ap_scan=%d\n", config->ap_scan); 1126 if (config->disable_scan_offload) 1127 fprintf(f, "disable_scan_offload=%d\n", 1128 config->disable_scan_offload); 1129 if (config->fast_reauth != DEFAULT_FAST_REAUTH) 1130 fprintf(f, "fast_reauth=%d\n", config->fast_reauth); 1131 if (config->opensc_engine_path) 1132 fprintf(f, "opensc_engine_path=%s\n", 1133 config->opensc_engine_path); 1134 if (config->pkcs11_engine_path) 1135 fprintf(f, "pkcs11_engine_path=%s\n", 1136 config->pkcs11_engine_path); 1137 if (config->pkcs11_module_path) 1138 fprintf(f, "pkcs11_module_path=%s\n", 1139 config->pkcs11_module_path); 1140 if (config->openssl_ciphers) 1141 fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers); 1142 if (config->pcsc_reader) 1143 fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader); 1144 if (config->pcsc_pin) 1145 fprintf(f, "pcsc_pin=%s\n", config->pcsc_pin); 1146 if (config->driver_param) 1147 fprintf(f, "driver_param=%s\n", config->driver_param); 1148 if (config->dot11RSNAConfigPMKLifetime) 1149 fprintf(f, "dot11RSNAConfigPMKLifetime=%u\n", 1150 config->dot11RSNAConfigPMKLifetime); 1151 if (config->dot11RSNAConfigPMKReauthThreshold) 1152 fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%u\n", 1153 config->dot11RSNAConfigPMKReauthThreshold); 1154 if (config->dot11RSNAConfigSATimeout) 1155 fprintf(f, "dot11RSNAConfigSATimeout=%u\n", 1156 config->dot11RSNAConfigSATimeout); 1157 if (config->update_config) 1158 fprintf(f, "update_config=%d\n", config->update_config); 1159 #ifdef CONFIG_WPS 1160 if (!is_nil_uuid(config->uuid)) { 1161 char buf[40]; 1162 uuid_bin2str(config->uuid, buf, sizeof(buf)); 1163 fprintf(f, "uuid=%s\n", buf); 1164 } 1165 if (config->auto_uuid) 1166 fprintf(f, "auto_uuid=%d\n", config->auto_uuid); 1167 if (config->device_name) 1168 fprintf(f, "device_name=%s\n", config->device_name); 1169 if (config->manufacturer) 1170 fprintf(f, "manufacturer=%s\n", config->manufacturer); 1171 if (config->model_name) 1172 fprintf(f, "model_name=%s\n", config->model_name); 1173 if (config->model_number) 1174 fprintf(f, "model_number=%s\n", config->model_number); 1175 if (config->serial_number) 1176 fprintf(f, "serial_number=%s\n", config->serial_number); 1177 { 1178 char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; 1179 buf = wps_dev_type_bin2str(config->device_type, 1180 _buf, sizeof(_buf)); 1181 if (os_strcmp(buf, "0-00000000-0") != 0) 1182 fprintf(f, "device_type=%s\n", buf); 1183 } 1184 if (WPA_GET_BE32(config->os_version)) 1185 fprintf(f, "os_version=%08x\n", 1186 WPA_GET_BE32(config->os_version)); 1187 if (config->config_methods) 1188 fprintf(f, "config_methods=%s\n", config->config_methods); 1189 if (config->wps_cred_processing) 1190 fprintf(f, "wps_cred_processing=%d\n", 1191 config->wps_cred_processing); 1192 if (config->wps_cred_add_sae) 1193 fprintf(f, "wps_cred_add_sae=%d\n", 1194 config->wps_cred_add_sae); 1195 if (config->wps_vendor_ext_m1) { 1196 int i, len = wpabuf_len(config->wps_vendor_ext_m1); 1197 const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1); 1198 if (len > 0) { 1199 fprintf(f, "wps_vendor_ext_m1="); 1200 for (i = 0; i < len; i++) 1201 fprintf(f, "%02x", *p++); 1202 fprintf(f, "\n"); 1203 } 1204 } 1205 #endif /* CONFIG_WPS */ 1206 #ifdef CONFIG_P2P 1207 { 1208 int i; 1209 char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; 1210 1211 for (i = 0; i < config->num_sec_device_types; i++) { 1212 buf = wps_dev_type_bin2str(config->sec_device_type[i], 1213 _buf, sizeof(_buf)); 1214 if (buf) 1215 fprintf(f, "sec_device_type=%s\n", buf); 1216 } 1217 } 1218 if (config->p2p_listen_reg_class) 1219 fprintf(f, "p2p_listen_reg_class=%d\n", 1220 config->p2p_listen_reg_class); 1221 if (config->p2p_listen_channel) 1222 fprintf(f, "p2p_listen_channel=%d\n", 1223 config->p2p_listen_channel); 1224 if (config->p2p_oper_reg_class) 1225 fprintf(f, "p2p_oper_reg_class=%d\n", 1226 config->p2p_oper_reg_class); 1227 if (config->p2p_oper_channel) 1228 fprintf(f, "p2p_oper_channel=%d\n", config->p2p_oper_channel); 1229 if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT) 1230 fprintf(f, "p2p_go_intent=%d\n", config->p2p_go_intent); 1231 if (config->p2p_ssid_postfix) 1232 fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix); 1233 if (config->persistent_reconnect) 1234 fprintf(f, "persistent_reconnect=%d\n", 1235 config->persistent_reconnect); 1236 if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS) 1237 fprintf(f, "p2p_intra_bss=%d\n", config->p2p_intra_bss); 1238 if (config->p2p_group_idle) 1239 fprintf(f, "p2p_group_idle=%d\n", config->p2p_group_idle); 1240 if (config->p2p_passphrase_len) 1241 fprintf(f, "p2p_passphrase_len=%u\n", 1242 config->p2p_passphrase_len); 1243 if (config->p2p_pref_chan) { 1244 unsigned int i; 1245 fprintf(f, "p2p_pref_chan="); 1246 for (i = 0; i < config->num_p2p_pref_chan; i++) { 1247 fprintf(f, "%s%u:%u", i > 0 ? "," : "", 1248 config->p2p_pref_chan[i].op_class, 1249 config->p2p_pref_chan[i].chan); 1250 } 1251 fprintf(f, "\n"); 1252 } 1253 if (config->p2p_no_go_freq.num) { 1254 char *val = freq_range_list_str(&config->p2p_no_go_freq); 1255 if (val) { 1256 fprintf(f, "p2p_no_go_freq=%s\n", val); 1257 os_free(val); 1258 } 1259 } 1260 if (config->p2p_add_cli_chan) 1261 fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan); 1262 if (config->p2p_optimize_listen_chan != 1263 DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN) 1264 fprintf(f, "p2p_optimize_listen_chan=%d\n", 1265 config->p2p_optimize_listen_chan); 1266 if (config->p2p_go_ht40) 1267 fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40); 1268 if (config->p2p_go_vht) 1269 fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht); 1270 if (config->p2p_go_he) 1271 fprintf(f, "p2p_go_he=%d\n", config->p2p_go_he); 1272 if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW) 1273 fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow); 1274 if (config->p2p_disabled) 1275 fprintf(f, "p2p_disabled=%d\n", config->p2p_disabled); 1276 if (config->p2p_no_group_iface) 1277 fprintf(f, "p2p_no_group_iface=%d\n", 1278 config->p2p_no_group_iface); 1279 if (config->p2p_ignore_shared_freq) 1280 fprintf(f, "p2p_ignore_shared_freq=%d\n", 1281 config->p2p_ignore_shared_freq); 1282 if (config->p2p_cli_probe) 1283 fprintf(f, "p2p_cli_probe=%d\n", config->p2p_cli_probe); 1284 if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE) 1285 fprintf(f, "p2p_go_freq_change_policy=%u\n", 1286 config->p2p_go_freq_change_policy); 1287 if (WPA_GET_BE32(config->ip_addr_go)) 1288 fprintf(f, "ip_addr_go=%u.%u.%u.%u\n", 1289 config->ip_addr_go[0], config->ip_addr_go[1], 1290 config->ip_addr_go[2], config->ip_addr_go[3]); 1291 if (WPA_GET_BE32(config->ip_addr_mask)) 1292 fprintf(f, "ip_addr_mask=%u.%u.%u.%u\n", 1293 config->ip_addr_mask[0], config->ip_addr_mask[1], 1294 config->ip_addr_mask[2], config->ip_addr_mask[3]); 1295 if (WPA_GET_BE32(config->ip_addr_start)) 1296 fprintf(f, "ip_addr_start=%u.%u.%u.%u\n", 1297 config->ip_addr_start[0], config->ip_addr_start[1], 1298 config->ip_addr_start[2], config->ip_addr_start[3]); 1299 if (WPA_GET_BE32(config->ip_addr_end)) 1300 fprintf(f, "ip_addr_end=%u.%u.%u.%u\n", 1301 config->ip_addr_end[0], config->ip_addr_end[1], 1302 config->ip_addr_end[2], config->ip_addr_end[3]); 1303 #endif /* CONFIG_P2P */ 1304 if (config->country[0] && config->country[1]) { 1305 fprintf(f, "country=%c%c\n", 1306 config->country[0], config->country[1]); 1307 } 1308 if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT) 1309 fprintf(f, "bss_max_count=%u\n", config->bss_max_count); 1310 if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE) 1311 fprintf(f, "bss_expiration_age=%u\n", 1312 config->bss_expiration_age); 1313 if (config->bss_expiration_scan_count != 1314 DEFAULT_BSS_EXPIRATION_SCAN_COUNT) 1315 fprintf(f, "bss_expiration_scan_count=%u\n", 1316 config->bss_expiration_scan_count); 1317 if (config->filter_ssids) 1318 fprintf(f, "filter_ssids=%d\n", config->filter_ssids); 1319 if (config->filter_rssi) 1320 fprintf(f, "filter_rssi=%d\n", config->filter_rssi); 1321 if (config->max_num_sta != DEFAULT_MAX_NUM_STA) 1322 fprintf(f, "max_num_sta=%u\n", config->max_num_sta); 1323 if (config->ap_isolate != DEFAULT_AP_ISOLATE) 1324 fprintf(f, "ap_isolate=%u\n", config->ap_isolate); 1325 if (config->disassoc_low_ack) 1326 fprintf(f, "disassoc_low_ack=%d\n", config->disassoc_low_ack); 1327 #ifdef CONFIG_HS20 1328 if (config->hs20) 1329 fprintf(f, "hs20=1\n"); 1330 #endif /* CONFIG_HS20 */ 1331 #ifdef CONFIG_INTERWORKING 1332 if (config->interworking) 1333 fprintf(f, "interworking=%d\n", config->interworking); 1334 if (!is_zero_ether_addr(config->hessid)) 1335 fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid)); 1336 if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE) 1337 fprintf(f, "access_network_type=%d\n", 1338 config->access_network_type); 1339 if (config->go_interworking) 1340 fprintf(f, "go_interworking=%d\n", config->go_interworking); 1341 if (config->go_access_network_type) 1342 fprintf(f, "go_access_network_type=%d\n", 1343 config->go_access_network_type); 1344 if (config->go_internet) 1345 fprintf(f, "go_internet=%d\n", config->go_internet); 1346 if (config->go_venue_group) 1347 fprintf(f, "go_venue_group=%d\n", config->go_venue_group); 1348 if (config->go_venue_type) 1349 fprintf(f, "go_venue_type=%d\n", config->go_venue_type); 1350 #endif /* CONFIG_INTERWORKING */ 1351 if (config->pbc_in_m1) 1352 fprintf(f, "pbc_in_m1=%d\n", config->pbc_in_m1); 1353 if (config->wps_nfc_pw_from_config) { 1354 if (config->wps_nfc_dev_pw_id) 1355 fprintf(f, "wps_nfc_dev_pw_id=%d\n", 1356 config->wps_nfc_dev_pw_id); 1357 write_global_bin(f, "wps_nfc_dh_pubkey", 1358 config->wps_nfc_dh_pubkey); 1359 write_global_bin(f, "wps_nfc_dh_privkey", 1360 config->wps_nfc_dh_privkey); 1361 write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw); 1362 } 1363 1364 if (config->ext_password_backend) 1365 fprintf(f, "ext_password_backend=%s\n", 1366 config->ext_password_backend); 1367 if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY) 1368 fprintf(f, "p2p_go_max_inactivity=%d\n", 1369 config->p2p_go_max_inactivity); 1370 if (config->auto_interworking) 1371 fprintf(f, "auto_interworking=%d\n", 1372 config->auto_interworking); 1373 if (config->okc) 1374 fprintf(f, "okc=%d\n", config->okc); 1375 if (config->pmf) 1376 fprintf(f, "pmf=%d\n", config->pmf); 1377 if (config->dtim_period) 1378 fprintf(f, "dtim_period=%d\n", config->dtim_period); 1379 if (config->beacon_int) 1380 fprintf(f, "beacon_int=%d\n", config->beacon_int); 1381 1382 if (config->sae_groups) { 1383 int i; 1384 fprintf(f, "sae_groups="); 1385 for (i = 0; config->sae_groups[i] > 0; i++) { 1386 fprintf(f, "%s%d", i > 0 ? " " : "", 1387 config->sae_groups[i]); 1388 } 1389 fprintf(f, "\n"); 1390 } 1391 1392 if (config->ap_vendor_elements) { 1393 int i, len = wpabuf_len(config->ap_vendor_elements); 1394 const u8 *p = wpabuf_head_u8(config->ap_vendor_elements); 1395 if (len > 0) { 1396 fprintf(f, "ap_vendor_elements="); 1397 for (i = 0; i < len; i++) 1398 fprintf(f, "%02x", *p++); 1399 fprintf(f, "\n"); 1400 } 1401 } 1402 1403 if (config->ignore_old_scan_res) 1404 fprintf(f, "ignore_old_scan_res=%d\n", 1405 config->ignore_old_scan_res); 1406 1407 if (config->freq_list && config->freq_list[0]) { 1408 int i; 1409 fprintf(f, "freq_list="); 1410 for (i = 0; config->freq_list[i]; i++) { 1411 fprintf(f, "%s%d", i > 0 ? " " : "", 1412 config->freq_list[i]); 1413 } 1414 fprintf(f, "\n"); 1415 } 1416 if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ) 1417 fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq); 1418 1419 if (config->sched_scan_interval) 1420 fprintf(f, "sched_scan_interval=%u\n", 1421 config->sched_scan_interval); 1422 1423 if (config->sched_scan_start_delay) 1424 fprintf(f, "sched_scan_start_delay=%u\n", 1425 config->sched_scan_start_delay); 1426 1427 if (config->external_sim) 1428 fprintf(f, "external_sim=%d\n", config->external_sim); 1429 1430 if (config->tdls_external_control) 1431 fprintf(f, "tdls_external_control=%d\n", 1432 config->tdls_external_control); 1433 1434 if (config->wowlan_triggers) 1435 fprintf(f, "wowlan_triggers=%s\n", 1436 config->wowlan_triggers); 1437 1438 if (config->bgscan) 1439 fprintf(f, "bgscan=\"%s\"\n", config->bgscan); 1440 1441 if (config->autoscan) 1442 fprintf(f, "autoscan=%s\n", config->autoscan); 1443 1444 if (config->p2p_search_delay != DEFAULT_P2P_SEARCH_DELAY) 1445 fprintf(f, "p2p_search_delay=%u\n", 1446 config->p2p_search_delay); 1447 1448 if (config->mac_addr) 1449 fprintf(f, "mac_addr=%d\n", config->mac_addr); 1450 1451 if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME) 1452 fprintf(f, "rand_addr_lifetime=%u\n", 1453 config->rand_addr_lifetime); 1454 1455 if (config->preassoc_mac_addr) 1456 fprintf(f, "preassoc_mac_addr=%d\n", config->preassoc_mac_addr); 1457 1458 if (config->key_mgmt_offload != DEFAULT_KEY_MGMT_OFFLOAD) 1459 fprintf(f, "key_mgmt_offload=%d\n", config->key_mgmt_offload); 1460 1461 if (config->user_mpm != DEFAULT_USER_MPM) 1462 fprintf(f, "user_mpm=%d\n", config->user_mpm); 1463 1464 if (config->max_peer_links != DEFAULT_MAX_PEER_LINKS) 1465 fprintf(f, "max_peer_links=%d\n", config->max_peer_links); 1466 1467 if (config->cert_in_cb != DEFAULT_CERT_IN_CB) 1468 fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb); 1469 1470 if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY) 1471 fprintf(f, "mesh_max_inactivity=%d\n", 1472 config->mesh_max_inactivity); 1473 1474 if (config->dot11RSNASAERetransPeriod != 1475 DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD) 1476 fprintf(f, "dot11RSNASAERetransPeriod=%d\n", 1477 config->dot11RSNASAERetransPeriod); 1478 1479 if (config->passive_scan) 1480 fprintf(f, "passive_scan=%d\n", config->passive_scan); 1481 1482 if (config->reassoc_same_bss_optim) 1483 fprintf(f, "reassoc_same_bss_optim=%d\n", 1484 config->reassoc_same_bss_optim); 1485 1486 if (config->wps_priority) 1487 fprintf(f, "wps_priority=%d\n", config->wps_priority); 1488 1489 if (config->wpa_rsc_relaxation != DEFAULT_WPA_RSC_RELAXATION) 1490 fprintf(f, "wpa_rsc_relaxation=%d\n", 1491 config->wpa_rsc_relaxation); 1492 1493 if (config->sched_scan_plans) 1494 fprintf(f, "sched_scan_plans=%s\n", config->sched_scan_plans); 1495 1496 #ifdef CONFIG_MBO 1497 if (config->non_pref_chan) 1498 fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan); 1499 if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA) 1500 fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa); 1501 if (config->disassoc_imminent_rssi_threshold != 1502 DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD) 1503 fprintf(f, "disassoc_imminent_rssi_threshold=%d\n", 1504 config->disassoc_imminent_rssi_threshold); 1505 if (config->oce != DEFAULT_OCE_SUPPORT) 1506 fprintf(f, "oce=%u\n", config->oce); 1507 #endif /* CONFIG_MBO */ 1508 1509 if (config->gas_address3) 1510 fprintf(f, "gas_address3=%d\n", config->gas_address3); 1511 1512 if (config->ftm_responder) 1513 fprintf(f, "ftm_responder=%d\n", config->ftm_responder); 1514 if (config->ftm_initiator) 1515 fprintf(f, "ftm_initiator=%d\n", config->ftm_initiator); 1516 1517 if (config->osu_dir) 1518 fprintf(f, "osu_dir=%s\n", config->osu_dir); 1519 1520 if (config->fst_group_id) 1521 fprintf(f, "fst_group_id=%s\n", config->fst_group_id); 1522 if (config->fst_priority) 1523 fprintf(f, "fst_priority=%d\n", config->fst_priority); 1524 if (config->fst_llt) 1525 fprintf(f, "fst_llt=%d\n", config->fst_llt); 1526 1527 if (config->gas_rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME) 1528 fprintf(f, "gas_rand_addr_lifetime=%u\n", 1529 config->gas_rand_addr_lifetime); 1530 if (config->gas_rand_mac_addr) 1531 fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr); 1532 if (config->dpp_config_processing) 1533 fprintf(f, "dpp_config_processing=%d\n", 1534 config->dpp_config_processing); 1535 if (config->coloc_intf_reporting) 1536 fprintf(f, "coloc_intf_reporting=%d\n", 1537 config->coloc_intf_reporting); 1538 if (config->p2p_device_random_mac_addr) 1539 fprintf(f, "p2p_device_random_mac_addr=%d\n", 1540 config->p2p_device_random_mac_addr); 1541 if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr)) 1542 fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n", 1543 MAC2STR(config->p2p_device_persistent_mac_addr)); 1544 if (config->p2p_interface_random_mac_addr) 1545 fprintf(f, "p2p_interface_random_mac_addr=%d\n", 1546 config->p2p_interface_random_mac_addr); 1547 } 1548 1549 #endif /* CONFIG_NO_CONFIG_WRITE */ 1550 1551 1552 int wpa_config_write(const char *name, struct wpa_config *config) 1553 { 1554 #ifndef CONFIG_NO_CONFIG_WRITE 1555 FILE *f; 1556 struct wpa_ssid *ssid; 1557 struct wpa_cred *cred; 1558 #ifndef CONFIG_NO_CONFIG_BLOBS 1559 struct wpa_config_blob *blob; 1560 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1561 int ret = 0; 1562 const char *orig_name = name; 1563 int tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */ 1564 char *tmp_name = os_malloc(tmp_len); 1565 1566 if (tmp_name) { 1567 os_snprintf(tmp_name, tmp_len, "%s.tmp", name); 1568 name = tmp_name; 1569 } 1570 1571 wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); 1572 1573 f = fopen(name, "w"); 1574 if (f == NULL) { 1575 wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); 1576 os_free(tmp_name); 1577 return -1; 1578 } 1579 1580 wpa_config_write_global(f, config); 1581 1582 for (cred = config->cred; cred; cred = cred->next) { 1583 if (cred->temporary) 1584 continue; 1585 fprintf(f, "\ncred={\n"); 1586 wpa_config_write_cred(f, cred); 1587 fprintf(f, "}\n"); 1588 } 1589 1590 for (ssid = config->ssid; ssid; ssid = ssid->next) { 1591 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) 1592 continue; /* do not save temporary networks */ 1593 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && 1594 !ssid->passphrase) 1595 continue; /* do not save invalid network */ 1596 fprintf(f, "\nnetwork={\n"); 1597 wpa_config_write_network(f, ssid); 1598 fprintf(f, "}\n"); 1599 } 1600 1601 #ifndef CONFIG_NO_CONFIG_BLOBS 1602 for (blob = config->blobs; blob; blob = blob->next) { 1603 ret = wpa_config_write_blob(f, blob); 1604 if (ret) 1605 break; 1606 } 1607 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1608 1609 os_fdatasync(f); 1610 1611 fclose(f); 1612 1613 if (tmp_name) { 1614 int chmod_ret = 0; 1615 1616 #ifdef ANDROID 1617 chmod_ret = chmod(tmp_name, 1618 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 1619 #endif /* ANDROID */ 1620 if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0) 1621 ret = -1; 1622 1623 os_free(tmp_name); 1624 } 1625 1626 wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", 1627 orig_name, ret ? "un" : ""); 1628 return ret; 1629 #else /* CONFIG_NO_CONFIG_WRITE */ 1630 return -1; 1631 #endif /* CONFIG_NO_CONFIG_WRITE */ 1632 } 1633