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