1 /* 2 * WPA Supplicant / Configuration parser and common functions 3 * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "wpa.h" 19 #include "sha1.h" 20 #include "eap_peer/eap.h" 21 #include "config.h" 22 23 24 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE) 25 #define NO_CONFIG_WRITE 26 #endif 27 28 /* 29 * Structure for network configuration parsing. This data is used to implement 30 * a generic parser for each network block variable. The table of configuration 31 * variables is defined below in this file (ssid_fields[]). 32 */ 33 struct parse_data { 34 /* Configuration variable name */ 35 char *name; 36 37 /* Parser function for this variable */ 38 int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid, 39 int line, const char *value); 40 41 #ifndef NO_CONFIG_WRITE 42 /* Writer function (i.e., to get the variable in text format from 43 * internal presentation). */ 44 char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid); 45 #endif /* NO_CONFIG_WRITE */ 46 47 /* Variable specific parameters for the parser. */ 48 void *param1, *param2, *param3, *param4; 49 50 /* 0 = this variable can be included in debug output and ctrl_iface 51 * 1 = this variable contains key/private data and it must not be 52 * included in debug output unless explicitly requested. In 53 * addition, this variable will not be readable through the 54 * ctrl_iface. 55 */ 56 int key_data; 57 }; 58 59 60 static char * wpa_config_parse_string(const char *value, size_t *len) 61 { 62 if (*value == '"') { 63 const char *pos; 64 char *str; 65 value++; 66 pos = os_strrchr(value, '"'); 67 if (pos == NULL || pos[1] != '\0') 68 return NULL; 69 *len = pos - value; 70 str = os_malloc(*len + 1); 71 if (str == NULL) 72 return NULL; 73 os_memcpy(str, value, *len); 74 str[*len] = '\0'; 75 return str; 76 } else { 77 u8 *str; 78 size_t tlen, hlen = os_strlen(value); 79 if (hlen & 1) 80 return NULL; 81 tlen = hlen / 2; 82 str = os_malloc(tlen + 1); 83 if (str == NULL) 84 return NULL; 85 if (hexstr2bin(value, str, tlen)) { 86 os_free(str); 87 return NULL; 88 } 89 str[tlen] = '\0'; 90 *len = tlen; 91 return (char *) str; 92 } 93 } 94 95 96 static int wpa_config_parse_str(const struct parse_data *data, 97 struct wpa_ssid *ssid, 98 int line, const char *value) 99 { 100 size_t res_len, *dst_len; 101 char **dst, *tmp; 102 103 if (os_strcmp(value, "NULL") == 0) { 104 wpa_printf(MSG_DEBUG, "Unset configuration string '%s'", 105 data->name); 106 tmp = NULL; 107 res_len = 0; 108 goto set; 109 } 110 111 tmp = wpa_config_parse_string(value, &res_len); 112 if (tmp == NULL) { 113 wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.", 114 line, data->name, 115 data->key_data ? "[KEY DATA REMOVED]" : value); 116 return -1; 117 } 118 119 if (data->key_data) { 120 wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name, 121 (u8 *) tmp, res_len); 122 } else { 123 wpa_hexdump_ascii(MSG_MSGDUMP, data->name, 124 (u8 *) tmp, res_len); 125 } 126 127 if (data->param3 && res_len < (size_t) data->param3) { 128 wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu " 129 "min_len=%ld)", line, data->name, 130 (unsigned long) res_len, (long) data->param3); 131 os_free(tmp); 132 return -1; 133 } 134 135 if (data->param4 && res_len > (size_t) data->param4) { 136 wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu " 137 "max_len=%ld)", line, data->name, 138 (unsigned long) res_len, (long) data->param4); 139 os_free(tmp); 140 return -1; 141 } 142 143 set: 144 dst = (char **) (((u8 *) ssid) + (long) data->param1); 145 dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2); 146 os_free(*dst); 147 *dst = tmp; 148 if (data->param2) 149 *dst_len = res_len; 150 151 return 0; 152 } 153 154 155 #ifndef NO_CONFIG_WRITE 156 static int is_hex(const u8 *data, size_t len) 157 { 158 size_t i; 159 160 for (i = 0; i < len; i++) { 161 if (data[i] < 32 || data[i] >= 127) 162 return 1; 163 } 164 return 0; 165 } 166 167 168 static char * wpa_config_write_string_ascii(const u8 *value, size_t len) 169 { 170 char *buf; 171 172 buf = os_malloc(len + 3); 173 if (buf == NULL) 174 return NULL; 175 buf[0] = '"'; 176 os_memcpy(buf + 1, value, len); 177 buf[len + 1] = '"'; 178 buf[len + 2] = '\0'; 179 180 return buf; 181 } 182 183 184 static char * wpa_config_write_string_hex(const u8 *value, size_t len) 185 { 186 char *buf; 187 188 buf = os_zalloc(2 * len + 1); 189 if (buf == NULL) 190 return NULL; 191 wpa_snprintf_hex(buf, 2 * len + 1, value, len); 192 193 return buf; 194 } 195 196 197 static char * wpa_config_write_string(const u8 *value, size_t len) 198 { 199 if (value == NULL) 200 return NULL; 201 202 if (is_hex(value, len)) 203 return wpa_config_write_string_hex(value, len); 204 else 205 return wpa_config_write_string_ascii(value, len); 206 } 207 208 209 static char * wpa_config_write_str(const struct parse_data *data, 210 struct wpa_ssid *ssid) 211 { 212 size_t len; 213 char **src; 214 215 src = (char **) (((u8 *) ssid) + (long) data->param1); 216 if (*src == NULL) 217 return NULL; 218 219 if (data->param2) 220 len = *((size_t *) (((u8 *) ssid) + (long) data->param2)); 221 else 222 len = os_strlen(*src); 223 224 return wpa_config_write_string((const u8 *) *src, len); 225 } 226 #endif /* NO_CONFIG_WRITE */ 227 228 229 static int wpa_config_parse_int(const struct parse_data *data, 230 struct wpa_ssid *ssid, 231 int line, const char *value) 232 { 233 int *dst; 234 235 dst = (int *) (((u8 *) ssid) + (long) data->param1); 236 *dst = atoi(value); 237 wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst); 238 239 if (data->param3 && *dst < (long) data->param3) { 240 wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d " 241 "min_value=%ld)", line, data->name, *dst, 242 (long) data->param3); 243 *dst = (long) data->param3; 244 return -1; 245 } 246 247 if (data->param4 && *dst > (long) data->param4) { 248 wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d " 249 "max_value=%ld)", line, data->name, *dst, 250 (long) data->param4); 251 *dst = (long) data->param4; 252 return -1; 253 } 254 255 return 0; 256 } 257 258 259 #ifndef NO_CONFIG_WRITE 260 static char * wpa_config_write_int(const struct parse_data *data, 261 struct wpa_ssid *ssid) 262 { 263 int *src, res; 264 char *value; 265 266 src = (int *) (((u8 *) ssid) + (long) data->param1); 267 268 value = os_malloc(20); 269 if (value == NULL) 270 return NULL; 271 res = os_snprintf(value, 20, "%d", *src); 272 if (res < 0 || res >= 20) { 273 os_free(value); 274 return NULL; 275 } 276 value[20 - 1] = '\0'; 277 return value; 278 } 279 #endif /* NO_CONFIG_WRITE */ 280 281 282 static int wpa_config_parse_bssid(const struct parse_data *data, 283 struct wpa_ssid *ssid, int line, 284 const char *value) 285 { 286 if (hwaddr_aton(value, ssid->bssid)) { 287 wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.", 288 line, value); 289 return -1; 290 } 291 ssid->bssid_set = 1; 292 wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN); 293 return 0; 294 } 295 296 297 #ifndef NO_CONFIG_WRITE 298 static char * wpa_config_write_bssid(const struct parse_data *data, 299 struct wpa_ssid *ssid) 300 { 301 char *value; 302 int res; 303 304 if (!ssid->bssid_set) 305 return NULL; 306 307 value = os_malloc(20); 308 if (value == NULL) 309 return NULL; 310 res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid)); 311 if (res < 0 || res >= 20) { 312 os_free(value); 313 return NULL; 314 } 315 value[20 - 1] = '\0'; 316 return value; 317 } 318 #endif /* NO_CONFIG_WRITE */ 319 320 321 static int wpa_config_parse_psk(const struct parse_data *data, 322 struct wpa_ssid *ssid, int line, 323 const char *value) 324 { 325 if (*value == '"') { 326 #ifndef CONFIG_NO_PBKDF2 327 const char *pos; 328 size_t len; 329 330 value++; 331 pos = os_strrchr(value, '"'); 332 if (pos) 333 len = pos - value; 334 else 335 len = os_strlen(value); 336 if (len < 8 || len > 63) { 337 wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase " 338 "length %lu (expected: 8..63) '%s'.", 339 line, (unsigned long) len, value); 340 return -1; 341 } 342 wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)", 343 (u8 *) value, len); 344 if (ssid->passphrase && os_strlen(ssid->passphrase) == len && 345 os_memcmp(ssid->passphrase, value, len) == 0) 346 return 0; 347 ssid->psk_set = 0; 348 os_free(ssid->passphrase); 349 ssid->passphrase = os_malloc(len + 1); 350 if (ssid->passphrase == NULL) 351 return -1; 352 os_memcpy(ssid->passphrase, value, len); 353 ssid->passphrase[len] = '\0'; 354 return 0; 355 #else /* CONFIG_NO_PBKDF2 */ 356 wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not " 357 "supported.", line); 358 return -1; 359 #endif /* CONFIG_NO_PBKDF2 */ 360 } 361 362 if (hexstr2bin(value, ssid->psk, PMK_LEN) || 363 value[PMK_LEN * 2] != '\0') { 364 wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.", 365 line, value); 366 return -1; 367 } 368 369 os_free(ssid->passphrase); 370 ssid->passphrase = NULL; 371 372 ssid->psk_set = 1; 373 wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN); 374 return 0; 375 } 376 377 378 #ifndef NO_CONFIG_WRITE 379 static char * wpa_config_write_psk(const struct parse_data *data, 380 struct wpa_ssid *ssid) 381 { 382 if (ssid->passphrase) 383 return wpa_config_write_string_ascii( 384 (const u8 *) ssid->passphrase, 385 os_strlen(ssid->passphrase)); 386 387 if (ssid->psk_set) 388 return wpa_config_write_string_hex(ssid->psk, PMK_LEN); 389 390 return NULL; 391 } 392 #endif /* NO_CONFIG_WRITE */ 393 394 395 static int wpa_config_parse_proto(const struct parse_data *data, 396 struct wpa_ssid *ssid, int line, 397 const char *value) 398 { 399 int val = 0, last, errors = 0; 400 char *start, *end, *buf; 401 402 buf = os_strdup(value); 403 if (buf == NULL) 404 return -1; 405 start = buf; 406 407 while (*start != '\0') { 408 while (*start == ' ' || *start == '\t') 409 start++; 410 if (*start == '\0') 411 break; 412 end = start; 413 while (*end != ' ' && *end != '\t' && *end != '\0') 414 end++; 415 last = *end == '\0'; 416 *end = '\0'; 417 if (os_strcmp(start, "WPA") == 0) 418 val |= WPA_PROTO_WPA; 419 else if (os_strcmp(start, "RSN") == 0 || 420 os_strcmp(start, "WPA2") == 0) 421 val |= WPA_PROTO_RSN; 422 else { 423 wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'", 424 line, start); 425 errors++; 426 } 427 428 if (last) 429 break; 430 start = end + 1; 431 } 432 os_free(buf); 433 434 if (val == 0) { 435 wpa_printf(MSG_ERROR, 436 "Line %d: no proto values configured.", line); 437 errors++; 438 } 439 440 wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val); 441 ssid->proto = val; 442 return errors ? -1 : 0; 443 } 444 445 446 #ifndef NO_CONFIG_WRITE 447 static char * wpa_config_write_proto(const struct parse_data *data, 448 struct wpa_ssid *ssid) 449 { 450 int first = 1, ret; 451 char *buf, *pos, *end; 452 453 pos = buf = os_zalloc(10); 454 if (buf == NULL) 455 return NULL; 456 end = buf + 10; 457 458 if (ssid->proto & WPA_PROTO_WPA) { 459 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " "); 460 if (ret < 0 || ret >= end - pos) 461 return buf; 462 pos += ret; 463 first = 0; 464 } 465 466 if (ssid->proto & WPA_PROTO_RSN) { 467 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " "); 468 if (ret < 0 || ret >= end - pos) 469 return buf; 470 pos += ret; 471 first = 0; 472 } 473 474 return buf; 475 } 476 #endif /* NO_CONFIG_WRITE */ 477 478 479 static int wpa_config_parse_key_mgmt(const struct parse_data *data, 480 struct wpa_ssid *ssid, int line, 481 const char *value) 482 { 483 int val = 0, last, errors = 0; 484 char *start, *end, *buf; 485 486 buf = os_strdup(value); 487 if (buf == NULL) 488 return -1; 489 start = buf; 490 491 while (*start != '\0') { 492 while (*start == ' ' || *start == '\t') 493 start++; 494 if (*start == '\0') 495 break; 496 end = start; 497 while (*end != ' ' && *end != '\t' && *end != '\0') 498 end++; 499 last = *end == '\0'; 500 *end = '\0'; 501 if (os_strcmp(start, "WPA-PSK") == 0) 502 val |= WPA_KEY_MGMT_PSK; 503 else if (os_strcmp(start, "WPA-EAP") == 0) 504 val |= WPA_KEY_MGMT_IEEE8021X; 505 else if (os_strcmp(start, "IEEE8021X") == 0) 506 val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA; 507 else if (os_strcmp(start, "NONE") == 0) 508 val |= WPA_KEY_MGMT_NONE; 509 else if (os_strcmp(start, "WPA-NONE") == 0) 510 val |= WPA_KEY_MGMT_WPA_NONE; 511 #ifdef CONFIG_IEEE80211R 512 else if (os_strcmp(start, "FT-PSK") == 0) 513 val |= WPA_KEY_MGMT_FT_PSK; 514 else if (os_strcmp(start, "FT-EAP") == 0) 515 val |= WPA_KEY_MGMT_FT_IEEE8021X; 516 #endif /* CONFIG_IEEE80211R */ 517 #ifdef CONFIG_IEEE80211W 518 else if (os_strcmp(start, "WPA-PSK-SHA256") == 0) 519 val |= WPA_KEY_MGMT_PSK_SHA256; 520 else if (os_strcmp(start, "WPA-EAP-SHA256") == 0) 521 val |= WPA_KEY_MGMT_IEEE8021X_SHA256; 522 #endif /* CONFIG_IEEE80211W */ 523 #ifdef CONFIG_WPS 524 else if (os_strcmp(start, "WPS") == 0) 525 val |= WPA_KEY_MGMT_WPS; 526 #endif /* CONFIG_WPS */ 527 else { 528 wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'", 529 line, start); 530 errors++; 531 } 532 533 if (last) 534 break; 535 start = end + 1; 536 } 537 os_free(buf); 538 539 if (val == 0) { 540 wpa_printf(MSG_ERROR, 541 "Line %d: no key_mgmt values configured.", line); 542 errors++; 543 } 544 545 wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val); 546 ssid->key_mgmt = val; 547 return errors ? -1 : 0; 548 } 549 550 551 #ifndef NO_CONFIG_WRITE 552 static char * wpa_config_write_key_mgmt(const struct parse_data *data, 553 struct wpa_ssid *ssid) 554 { 555 char *buf, *pos, *end; 556 int ret; 557 558 pos = buf = os_zalloc(50); 559 if (buf == NULL) 560 return NULL; 561 end = buf + 50; 562 563 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) { 564 ret = os_snprintf(pos, end - pos, "%sWPA-PSK", 565 pos == buf ? "" : " "); 566 if (ret < 0 || ret >= end - pos) { 567 end[-1] = '\0'; 568 return buf; 569 } 570 pos += ret; 571 } 572 573 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) { 574 ret = os_snprintf(pos, end - pos, "%sWPA-EAP", 575 pos == buf ? "" : " "); 576 if (ret < 0 || ret >= end - pos) { 577 end[-1] = '\0'; 578 return buf; 579 } 580 pos += ret; 581 } 582 583 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 584 ret = os_snprintf(pos, end - pos, "%sIEEE8021X", 585 pos == buf ? "" : " "); 586 if (ret < 0 || ret >= end - pos) { 587 end[-1] = '\0'; 588 return buf; 589 } 590 pos += ret; 591 } 592 593 if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) { 594 ret = os_snprintf(pos, end - pos, "%sNONE", 595 pos == buf ? "" : " "); 596 if (ret < 0 || ret >= end - pos) { 597 end[-1] = '\0'; 598 return buf; 599 } 600 pos += ret; 601 } 602 603 if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) { 604 ret = os_snprintf(pos, end - pos, "%sWPA-NONE", 605 pos == buf ? "" : " "); 606 if (ret < 0 || ret >= end - pos) { 607 end[-1] = '\0'; 608 return buf; 609 } 610 pos += ret; 611 } 612 613 #ifdef CONFIG_IEEE80211R 614 if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) 615 pos += os_snprintf(pos, end - pos, "%sFT-PSK", 616 pos == buf ? "" : " "); 617 618 if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) 619 pos += os_snprintf(pos, end - pos, "%sFT-EAP", 620 pos == buf ? "" : " "); 621 #endif /* CONFIG_IEEE80211R */ 622 623 #ifdef CONFIG_IEEE80211W 624 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) 625 pos += os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256", 626 pos == buf ? "" : " "); 627 628 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) 629 pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256", 630 pos == buf ? "" : " "); 631 #endif /* CONFIG_IEEE80211W */ 632 633 #ifdef CONFIG_WPS 634 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) 635 pos += os_snprintf(pos, end - pos, "%sWPS", 636 pos == buf ? "" : " "); 637 #endif /* CONFIG_WPS */ 638 639 return buf; 640 } 641 #endif /* NO_CONFIG_WRITE */ 642 643 644 static int wpa_config_parse_cipher(int line, const char *value) 645 { 646 int val = 0, last; 647 char *start, *end, *buf; 648 649 buf = os_strdup(value); 650 if (buf == NULL) 651 return -1; 652 start = buf; 653 654 while (*start != '\0') { 655 while (*start == ' ' || *start == '\t') 656 start++; 657 if (*start == '\0') 658 break; 659 end = start; 660 while (*end != ' ' && *end != '\t' && *end != '\0') 661 end++; 662 last = *end == '\0'; 663 *end = '\0'; 664 if (os_strcmp(start, "CCMP") == 0) 665 val |= WPA_CIPHER_CCMP; 666 else if (os_strcmp(start, "TKIP") == 0) 667 val |= WPA_CIPHER_TKIP; 668 else if (os_strcmp(start, "WEP104") == 0) 669 val |= WPA_CIPHER_WEP104; 670 else if (os_strcmp(start, "WEP40") == 0) 671 val |= WPA_CIPHER_WEP40; 672 else if (os_strcmp(start, "NONE") == 0) 673 val |= WPA_CIPHER_NONE; 674 else { 675 wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.", 676 line, start); 677 os_free(buf); 678 return -1; 679 } 680 681 if (last) 682 break; 683 start = end + 1; 684 } 685 os_free(buf); 686 687 if (val == 0) { 688 wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.", 689 line); 690 return -1; 691 } 692 return val; 693 } 694 695 696 #ifndef NO_CONFIG_WRITE 697 static char * wpa_config_write_cipher(int cipher) 698 { 699 char *buf, *pos, *end; 700 int ret; 701 702 pos = buf = os_zalloc(50); 703 if (buf == NULL) 704 return NULL; 705 end = buf + 50; 706 707 if (cipher & WPA_CIPHER_CCMP) { 708 ret = os_snprintf(pos, end - pos, "%sCCMP", 709 pos == buf ? "" : " "); 710 if (ret < 0 || ret >= end - pos) { 711 end[-1] = '\0'; 712 return buf; 713 } 714 pos += ret; 715 } 716 717 if (cipher & WPA_CIPHER_TKIP) { 718 ret = os_snprintf(pos, end - pos, "%sTKIP", 719 pos == buf ? "" : " "); 720 if (ret < 0 || ret >= end - pos) { 721 end[-1] = '\0'; 722 return buf; 723 } 724 pos += ret; 725 } 726 727 if (cipher & WPA_CIPHER_WEP104) { 728 ret = os_snprintf(pos, end - pos, "%sWEP104", 729 pos == buf ? "" : " "); 730 if (ret < 0 || ret >= end - pos) { 731 end[-1] = '\0'; 732 return buf; 733 } 734 pos += ret; 735 } 736 737 if (cipher & WPA_CIPHER_WEP40) { 738 ret = os_snprintf(pos, end - pos, "%sWEP40", 739 pos == buf ? "" : " "); 740 if (ret < 0 || ret >= end - pos) { 741 end[-1] = '\0'; 742 return buf; 743 } 744 pos += ret; 745 } 746 747 if (cipher & WPA_CIPHER_NONE) { 748 ret = os_snprintf(pos, end - pos, "%sNONE", 749 pos == buf ? "" : " "); 750 if (ret < 0 || ret >= end - pos) { 751 end[-1] = '\0'; 752 return buf; 753 } 754 pos += ret; 755 } 756 757 return buf; 758 } 759 #endif /* NO_CONFIG_WRITE */ 760 761 762 static int wpa_config_parse_pairwise(const struct parse_data *data, 763 struct wpa_ssid *ssid, int line, 764 const char *value) 765 { 766 int val; 767 val = wpa_config_parse_cipher(line, value); 768 if (val == -1) 769 return -1; 770 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) { 771 wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher " 772 "(0x%x).", line, val); 773 return -1; 774 } 775 776 wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val); 777 ssid->pairwise_cipher = val; 778 return 0; 779 } 780 781 782 #ifndef NO_CONFIG_WRITE 783 static char * wpa_config_write_pairwise(const struct parse_data *data, 784 struct wpa_ssid *ssid) 785 { 786 return wpa_config_write_cipher(ssid->pairwise_cipher); 787 } 788 #endif /* NO_CONFIG_WRITE */ 789 790 791 static int wpa_config_parse_group(const struct parse_data *data, 792 struct wpa_ssid *ssid, int line, 793 const char *value) 794 { 795 int val; 796 val = wpa_config_parse_cipher(line, value); 797 if (val == -1) 798 return -1; 799 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 | 800 WPA_CIPHER_WEP40)) { 801 wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher " 802 "(0x%x).", line, val); 803 return -1; 804 } 805 806 wpa_printf(MSG_MSGDUMP, "group: 0x%x", val); 807 ssid->group_cipher = val; 808 return 0; 809 } 810 811 812 #ifndef NO_CONFIG_WRITE 813 static char * wpa_config_write_group(const struct parse_data *data, 814 struct wpa_ssid *ssid) 815 { 816 return wpa_config_write_cipher(ssid->group_cipher); 817 } 818 #endif /* NO_CONFIG_WRITE */ 819 820 821 static int wpa_config_parse_auth_alg(const struct parse_data *data, 822 struct wpa_ssid *ssid, int line, 823 const char *value) 824 { 825 int val = 0, last, errors = 0; 826 char *start, *end, *buf; 827 828 buf = os_strdup(value); 829 if (buf == NULL) 830 return -1; 831 start = buf; 832 833 while (*start != '\0') { 834 while (*start == ' ' || *start == '\t') 835 start++; 836 if (*start == '\0') 837 break; 838 end = start; 839 while (*end != ' ' && *end != '\t' && *end != '\0') 840 end++; 841 last = *end == '\0'; 842 *end = '\0'; 843 if (os_strcmp(start, "OPEN") == 0) 844 val |= WPA_AUTH_ALG_OPEN; 845 else if (os_strcmp(start, "SHARED") == 0) 846 val |= WPA_AUTH_ALG_SHARED; 847 else if (os_strcmp(start, "LEAP") == 0) 848 val |= WPA_AUTH_ALG_LEAP; 849 else { 850 wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'", 851 line, start); 852 errors++; 853 } 854 855 if (last) 856 break; 857 start = end + 1; 858 } 859 os_free(buf); 860 861 if (val == 0) { 862 wpa_printf(MSG_ERROR, 863 "Line %d: no auth_alg values configured.", line); 864 errors++; 865 } 866 867 wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val); 868 ssid->auth_alg = val; 869 return errors ? -1 : 0; 870 } 871 872 873 #ifndef NO_CONFIG_WRITE 874 static char * wpa_config_write_auth_alg(const struct parse_data *data, 875 struct wpa_ssid *ssid) 876 { 877 char *buf, *pos, *end; 878 int ret; 879 880 pos = buf = os_zalloc(30); 881 if (buf == NULL) 882 return NULL; 883 end = buf + 30; 884 885 if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) { 886 ret = os_snprintf(pos, end - pos, "%sOPEN", 887 pos == buf ? "" : " "); 888 if (ret < 0 || ret >= end - pos) { 889 end[-1] = '\0'; 890 return buf; 891 } 892 pos += ret; 893 } 894 895 if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) { 896 ret = os_snprintf(pos, end - pos, "%sSHARED", 897 pos == buf ? "" : " "); 898 if (ret < 0 || ret >= end - pos) { 899 end[-1] = '\0'; 900 return buf; 901 } 902 pos += ret; 903 } 904 905 if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) { 906 ret = os_snprintf(pos, end - pos, "%sLEAP", 907 pos == buf ? "" : " "); 908 if (ret < 0 || ret >= end - pos) { 909 end[-1] = '\0'; 910 return buf; 911 } 912 pos += ret; 913 } 914 915 return buf; 916 } 917 #endif /* NO_CONFIG_WRITE */ 918 919 920 #ifdef IEEE8021X_EAPOL 921 static int wpa_config_parse_eap(const struct parse_data *data, 922 struct wpa_ssid *ssid, int line, 923 const char *value) 924 { 925 int last, errors = 0; 926 char *start, *end, *buf; 927 struct eap_method_type *methods = NULL, *tmp; 928 size_t num_methods = 0; 929 930 buf = os_strdup(value); 931 if (buf == NULL) 932 return -1; 933 start = buf; 934 935 while (*start != '\0') { 936 while (*start == ' ' || *start == '\t') 937 start++; 938 if (*start == '\0') 939 break; 940 end = start; 941 while (*end != ' ' && *end != '\t' && *end != '\0') 942 end++; 943 last = *end == '\0'; 944 *end = '\0'; 945 tmp = methods; 946 methods = os_realloc(methods, 947 (num_methods + 1) * sizeof(*methods)); 948 if (methods == NULL) { 949 os_free(tmp); 950 os_free(buf); 951 return -1; 952 } 953 methods[num_methods].method = eap_peer_get_type( 954 start, &methods[num_methods].vendor); 955 if (methods[num_methods].vendor == EAP_VENDOR_IETF && 956 methods[num_methods].method == EAP_TYPE_NONE) { 957 wpa_printf(MSG_ERROR, "Line %d: unknown EAP method " 958 "'%s'", line, start); 959 wpa_printf(MSG_ERROR, "You may need to add support for" 960 " this EAP method during wpa_supplicant\n" 961 "build time configuration.\n" 962 "See README for more information."); 963 errors++; 964 } else if (methods[num_methods].vendor == EAP_VENDOR_IETF && 965 methods[num_methods].method == EAP_TYPE_LEAP) 966 ssid->leap++; 967 else 968 ssid->non_leap++; 969 num_methods++; 970 if (last) 971 break; 972 start = end + 1; 973 } 974 os_free(buf); 975 976 tmp = methods; 977 methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods)); 978 if (methods == NULL) { 979 os_free(tmp); 980 return -1; 981 } 982 methods[num_methods].vendor = EAP_VENDOR_IETF; 983 methods[num_methods].method = EAP_TYPE_NONE; 984 num_methods++; 985 986 wpa_hexdump(MSG_MSGDUMP, "eap methods", 987 (u8 *) methods, num_methods * sizeof(*methods)); 988 ssid->eap.eap_methods = methods; 989 return errors ? -1 : 0; 990 } 991 992 993 static char * wpa_config_write_eap(const struct parse_data *data, 994 struct wpa_ssid *ssid) 995 { 996 int i, ret; 997 char *buf, *pos, *end; 998 const struct eap_method_type *eap_methods = ssid->eap.eap_methods; 999 const char *name; 1000 1001 if (eap_methods == NULL) 1002 return NULL; 1003 1004 pos = buf = os_zalloc(100); 1005 if (buf == NULL) 1006 return NULL; 1007 end = buf + 100; 1008 1009 for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF || 1010 eap_methods[i].method != EAP_TYPE_NONE; i++) { 1011 name = eap_get_name(eap_methods[i].vendor, 1012 eap_methods[i].method); 1013 if (name) { 1014 ret = os_snprintf(pos, end - pos, "%s%s", 1015 pos == buf ? "" : " ", name); 1016 if (ret < 0 || ret >= end - pos) 1017 break; 1018 pos += ret; 1019 } 1020 } 1021 1022 end[-1] = '\0'; 1023 1024 return buf; 1025 } 1026 1027 1028 static int wpa_config_parse_password(const struct parse_data *data, 1029 struct wpa_ssid *ssid, int line, 1030 const char *value) 1031 { 1032 u8 *hash; 1033 1034 if (os_strcmp(value, "NULL") == 0) { 1035 wpa_printf(MSG_DEBUG, "Unset configuration string 'password'"); 1036 os_free(ssid->eap.password); 1037 ssid->eap.password = NULL; 1038 ssid->eap.password_len = 0; 1039 return 0; 1040 } 1041 1042 if (os_strncmp(value, "hash:", 5) != 0) { 1043 char *tmp; 1044 size_t res_len; 1045 1046 tmp = wpa_config_parse_string(value, &res_len); 1047 if (tmp == NULL) { 1048 wpa_printf(MSG_ERROR, "Line %d: failed to parse " 1049 "password.", line); 1050 return -1; 1051 } 1052 wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name, 1053 (u8 *) tmp, res_len); 1054 1055 os_free(ssid->eap.password); 1056 ssid->eap.password = (u8 *) tmp; 1057 ssid->eap.password_len = res_len; 1058 ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH; 1059 1060 return 0; 1061 } 1062 1063 1064 /* NtPasswordHash: hash:<32 hex digits> */ 1065 if (os_strlen(value + 5) != 2 * 16) { 1066 wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length " 1067 "(expected 32 hex digits)", line); 1068 return -1; 1069 } 1070 1071 hash = os_malloc(16); 1072 if (hash == NULL) 1073 return -1; 1074 1075 if (hexstr2bin(value + 5, hash, 16)) { 1076 os_free(hash); 1077 wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line); 1078 return -1; 1079 } 1080 1081 wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16); 1082 1083 os_free(ssid->eap.password); 1084 ssid->eap.password = hash; 1085 ssid->eap.password_len = 16; 1086 ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH; 1087 1088 return 0; 1089 } 1090 1091 1092 static char * wpa_config_write_password(const struct parse_data *data, 1093 struct wpa_ssid *ssid) 1094 { 1095 char *buf; 1096 1097 if (ssid->eap.password == NULL) 1098 return NULL; 1099 1100 if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) { 1101 return wpa_config_write_string( 1102 ssid->eap.password, ssid->eap.password_len); 1103 } 1104 1105 buf = os_malloc(5 + 32 + 1); 1106 if (buf == NULL) 1107 return NULL; 1108 1109 os_memcpy(buf, "hash:", 5); 1110 wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16); 1111 1112 return buf; 1113 } 1114 #endif /* IEEE8021X_EAPOL */ 1115 1116 1117 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line, 1118 const char *value, int idx) 1119 { 1120 char *buf, title[20]; 1121 int res; 1122 1123 buf = wpa_config_parse_string(value, len); 1124 if (buf == NULL) { 1125 wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.", 1126 line, idx, value); 1127 return -1; 1128 } 1129 if (*len > MAX_WEP_KEY_LEN) { 1130 wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.", 1131 line, idx, value); 1132 os_free(buf); 1133 return -1; 1134 } 1135 os_memcpy(key, buf, *len); 1136 os_free(buf); 1137 res = os_snprintf(title, sizeof(title), "wep_key%d", idx); 1138 if (res >= 0 && (size_t) res < sizeof(title)) 1139 wpa_hexdump_key(MSG_MSGDUMP, title, key, *len); 1140 return 0; 1141 } 1142 1143 1144 static int wpa_config_parse_wep_key0(const struct parse_data *data, 1145 struct wpa_ssid *ssid, int line, 1146 const char *value) 1147 { 1148 return wpa_config_parse_wep_key(ssid->wep_key[0], 1149 &ssid->wep_key_len[0], line, 1150 value, 0); 1151 } 1152 1153 1154 static int wpa_config_parse_wep_key1(const struct parse_data *data, 1155 struct wpa_ssid *ssid, int line, 1156 const char *value) 1157 { 1158 return wpa_config_parse_wep_key(ssid->wep_key[1], 1159 &ssid->wep_key_len[1], line, 1160 value, 1); 1161 } 1162 1163 1164 static int wpa_config_parse_wep_key2(const struct parse_data *data, 1165 struct wpa_ssid *ssid, int line, 1166 const char *value) 1167 { 1168 return wpa_config_parse_wep_key(ssid->wep_key[2], 1169 &ssid->wep_key_len[2], line, 1170 value, 2); 1171 } 1172 1173 1174 static int wpa_config_parse_wep_key3(const struct parse_data *data, 1175 struct wpa_ssid *ssid, int line, 1176 const char *value) 1177 { 1178 return wpa_config_parse_wep_key(ssid->wep_key[3], 1179 &ssid->wep_key_len[3], line, 1180 value, 3); 1181 } 1182 1183 1184 #ifndef NO_CONFIG_WRITE 1185 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx) 1186 { 1187 if (ssid->wep_key_len[idx] == 0) 1188 return NULL; 1189 return wpa_config_write_string(ssid->wep_key[idx], 1190 ssid->wep_key_len[idx]); 1191 } 1192 1193 1194 static char * wpa_config_write_wep_key0(const struct parse_data *data, 1195 struct wpa_ssid *ssid) 1196 { 1197 return wpa_config_write_wep_key(ssid, 0); 1198 } 1199 1200 1201 static char * wpa_config_write_wep_key1(const struct parse_data *data, 1202 struct wpa_ssid *ssid) 1203 { 1204 return wpa_config_write_wep_key(ssid, 1); 1205 } 1206 1207 1208 static char * wpa_config_write_wep_key2(const struct parse_data *data, 1209 struct wpa_ssid *ssid) 1210 { 1211 return wpa_config_write_wep_key(ssid, 2); 1212 } 1213 1214 1215 static char * wpa_config_write_wep_key3(const struct parse_data *data, 1216 struct wpa_ssid *ssid) 1217 { 1218 return wpa_config_write_wep_key(ssid, 3); 1219 } 1220 #endif /* NO_CONFIG_WRITE */ 1221 1222 1223 /* Helper macros for network block parser */ 1224 1225 #ifdef OFFSET 1226 #undef OFFSET 1227 #endif /* OFFSET */ 1228 /* OFFSET: Get offset of a variable within the wpa_ssid structure */ 1229 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v) 1230 1231 /* STR: Define a string variable for an ASCII string; f = field name */ 1232 #ifdef NO_CONFIG_WRITE 1233 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f) 1234 #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f) 1235 #else /* NO_CONFIG_WRITE */ 1236 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f) 1237 #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f) 1238 #endif /* NO_CONFIG_WRITE */ 1239 #define STR(f) _STR(f), NULL, NULL, NULL, 0 1240 #define STRe(f) _STRe(f), NULL, NULL, NULL, 0 1241 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1 1242 #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1 1243 1244 /* STR_LEN: Define a string variable with a separate variable for storing the 1245 * data length. Unlike STR(), this can be used to store arbitrary binary data 1246 * (i.e., even nul termination character). */ 1247 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len) 1248 #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len) 1249 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0 1250 #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0 1251 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1 1252 1253 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length 1254 * explicitly specified. */ 1255 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max) 1256 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0 1257 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1 1258 1259 #ifdef NO_CONFIG_WRITE 1260 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0 1261 #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0 1262 #else /* NO_CONFIG_WRITE */ 1263 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \ 1264 OFFSET(f), (void *) 0 1265 #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \ 1266 OFFSET(eap.f), (void *) 0 1267 #endif /* NO_CONFIG_WRITE */ 1268 1269 /* INT: Define an integer variable */ 1270 #define INT(f) _INT(f), NULL, NULL, 0 1271 #define INTe(f) _INTe(f), NULL, NULL, 0 1272 1273 /* INT_RANGE: Define an integer variable with allowed value range */ 1274 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0 1275 1276 /* FUNC: Define a configuration variable that uses a custom function for 1277 * parsing and writing the value. */ 1278 #ifdef NO_CONFIG_WRITE 1279 #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL 1280 #else /* NO_CONFIG_WRITE */ 1281 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \ 1282 NULL, NULL, NULL, NULL 1283 #endif /* NO_CONFIG_WRITE */ 1284 #define FUNC(f) _FUNC(f), 0 1285 #define FUNC_KEY(f) _FUNC(f), 1 1286 1287 /* 1288 * Table of network configuration variables. This table is used to parse each 1289 * network configuration variable, e.g., each line in wpa_supplicant.conf file 1290 * that is inside a network block. 1291 * 1292 * This table is generated using the helper macros defined above and with 1293 * generous help from the C pre-processor. The field name is stored as a string 1294 * into .name and for STR and INT types, the offset of the target buffer within 1295 * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar 1296 * offset to the field containing the length of the configuration variable. 1297 * .param3 and .param4 can be used to mark the allowed range (length for STR 1298 * and value for INT). 1299 * 1300 * For each configuration line in wpa_supplicant.conf, the parser goes through 1301 * this table and select the entry that matches with the field name. The parser 1302 * function (.parser) is then called to parse the actual value of the field. 1303 * 1304 * This kind of mechanism makes it easy to add new configuration parameters, 1305 * since only one line needs to be added into this table and into the 1306 * struct wpa_ssid definition if the new variable is either a string or 1307 * integer. More complex types will need to use their own parser and writer 1308 * functions. 1309 */ 1310 static const struct parse_data ssid_fields[] = { 1311 { STR_RANGE(ssid, 0, MAX_SSID_LEN) }, 1312 { INT_RANGE(scan_ssid, 0, 1) }, 1313 { FUNC(bssid) }, 1314 { FUNC_KEY(psk) }, 1315 { FUNC(proto) }, 1316 { FUNC(key_mgmt) }, 1317 { FUNC(pairwise) }, 1318 { FUNC(group) }, 1319 { FUNC(auth_alg) }, 1320 #ifdef IEEE8021X_EAPOL 1321 { FUNC(eap) }, 1322 { STR_LENe(identity) }, 1323 { STR_LENe(anonymous_identity) }, 1324 { FUNC_KEY(password) }, 1325 { STRe(ca_cert) }, 1326 { STRe(ca_path) }, 1327 { STRe(client_cert) }, 1328 { STRe(private_key) }, 1329 { STR_KEYe(private_key_passwd) }, 1330 { STRe(dh_file) }, 1331 { STRe(subject_match) }, 1332 { STRe(altsubject_match) }, 1333 { STRe(ca_cert2) }, 1334 { STRe(ca_path2) }, 1335 { STRe(client_cert2) }, 1336 { STRe(private_key2) }, 1337 { STR_KEYe(private_key2_passwd) }, 1338 { STRe(dh_file2) }, 1339 { STRe(subject_match2) }, 1340 { STRe(altsubject_match2) }, 1341 { STRe(phase1) }, 1342 { STRe(phase2) }, 1343 { STRe(pcsc) }, 1344 { STR_KEYe(pin) }, 1345 { STRe(engine_id) }, 1346 { STRe(key_id) }, 1347 { STRe(cert_id) }, 1348 { STRe(ca_cert_id) }, 1349 { STR_KEYe(pin2) }, 1350 { STRe(engine2_id) }, 1351 { STRe(key2_id) }, 1352 { STRe(cert2_id) }, 1353 { STRe(ca_cert2_id) }, 1354 { INTe(engine) }, 1355 { INTe(engine2) }, 1356 { INT(eapol_flags) }, 1357 #endif /* IEEE8021X_EAPOL */ 1358 { FUNC_KEY(wep_key0) }, 1359 { FUNC_KEY(wep_key1) }, 1360 { FUNC_KEY(wep_key2) }, 1361 { FUNC_KEY(wep_key3) }, 1362 { INT(wep_tx_keyidx) }, 1363 { INT(priority) }, 1364 #ifdef IEEE8021X_EAPOL 1365 { INT(eap_workaround) }, 1366 { STRe(pac_file) }, 1367 { INTe(fragment_size) }, 1368 #endif /* IEEE8021X_EAPOL */ 1369 { INT_RANGE(mode, 0, 1) }, 1370 { INT_RANGE(proactive_key_caching, 0, 1) }, 1371 { INT_RANGE(disabled, 0, 1) }, 1372 { STR(id_str) }, 1373 #ifdef CONFIG_IEEE80211W 1374 { INT_RANGE(ieee80211w, 0, 2) }, 1375 #endif /* CONFIG_IEEE80211W */ 1376 { INT_RANGE(peerkey, 0, 1) }, 1377 { INT_RANGE(mixed_cell, 0, 1) }, 1378 { INT_RANGE(frequency, 0, 10000) }, 1379 { INT(wpa_ptk_rekey) } 1380 }; 1381 1382 #undef OFFSET 1383 #undef _STR 1384 #undef STR 1385 #undef STR_KEY 1386 #undef _STR_LEN 1387 #undef STR_LEN 1388 #undef STR_LEN_KEY 1389 #undef _STR_RANGE 1390 #undef STR_RANGE 1391 #undef STR_RANGE_KEY 1392 #undef _INT 1393 #undef INT 1394 #undef INT_RANGE 1395 #undef _FUNC 1396 #undef FUNC 1397 #undef FUNC_KEY 1398 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0])) 1399 1400 1401 /** 1402 * wpa_config_add_prio_network - Add a network to priority lists 1403 * @config: Configuration data from wpa_config_read() 1404 * @ssid: Pointer to the network configuration to be added to the list 1405 * Returns: 0 on success, -1 on failure 1406 * 1407 * This function is used to add a network block to the priority list of 1408 * networks. This must be called for each network when reading in the full 1409 * configuration. In addition, this can be used indirectly when updating 1410 * priorities by calling wpa_config_update_prio_list(). 1411 */ 1412 int wpa_config_add_prio_network(struct wpa_config *config, 1413 struct wpa_ssid *ssid) 1414 { 1415 int prio; 1416 struct wpa_ssid *prev, **nlist; 1417 1418 /* 1419 * Add to an existing priority list if one is available for the 1420 * configured priority level for this network. 1421 */ 1422 for (prio = 0; prio < config->num_prio; prio++) { 1423 prev = config->pssid[prio]; 1424 if (prev->priority == ssid->priority) { 1425 while (prev->pnext) 1426 prev = prev->pnext; 1427 prev->pnext = ssid; 1428 return 0; 1429 } 1430 } 1431 1432 /* First network for this priority - add a new priority list */ 1433 nlist = os_realloc(config->pssid, 1434 (config->num_prio + 1) * sizeof(struct wpa_ssid *)); 1435 if (nlist == NULL) 1436 return -1; 1437 1438 for (prio = 0; prio < config->num_prio; prio++) { 1439 if (nlist[prio]->priority < ssid->priority) 1440 break; 1441 } 1442 1443 os_memmove(&nlist[prio + 1], &nlist[prio], 1444 (config->num_prio - prio) * sizeof(struct wpa_ssid *)); 1445 1446 nlist[prio] = ssid; 1447 config->num_prio++; 1448 config->pssid = nlist; 1449 1450 return 0; 1451 } 1452 1453 1454 /** 1455 * wpa_config_update_prio_list - Update network priority list 1456 * @config: Configuration data from wpa_config_read() 1457 * Returns: 0 on success, -1 on failure 1458 * 1459 * This function is called to update the priority list of networks in the 1460 * configuration when a network is being added or removed. This is also called 1461 * if a priority for a network is changed. 1462 */ 1463 static int wpa_config_update_prio_list(struct wpa_config *config) 1464 { 1465 struct wpa_ssid *ssid; 1466 int ret = 0; 1467 1468 os_free(config->pssid); 1469 config->pssid = NULL; 1470 config->num_prio = 0; 1471 1472 ssid = config->ssid; 1473 while (ssid) { 1474 ssid->pnext = NULL; 1475 if (wpa_config_add_prio_network(config, ssid) < 0) 1476 ret = -1; 1477 ssid = ssid->next; 1478 } 1479 1480 return ret; 1481 } 1482 1483 1484 #ifdef IEEE8021X_EAPOL 1485 static void eap_peer_config_free(struct eap_peer_config *eap) 1486 { 1487 os_free(eap->eap_methods); 1488 os_free(eap->identity); 1489 os_free(eap->anonymous_identity); 1490 os_free(eap->password); 1491 os_free(eap->ca_cert); 1492 os_free(eap->ca_path); 1493 os_free(eap->client_cert); 1494 os_free(eap->private_key); 1495 os_free(eap->private_key_passwd); 1496 os_free(eap->dh_file); 1497 os_free(eap->subject_match); 1498 os_free(eap->altsubject_match); 1499 os_free(eap->ca_cert2); 1500 os_free(eap->ca_path2); 1501 os_free(eap->client_cert2); 1502 os_free(eap->private_key2); 1503 os_free(eap->private_key2_passwd); 1504 os_free(eap->dh_file2); 1505 os_free(eap->subject_match2); 1506 os_free(eap->altsubject_match2); 1507 os_free(eap->phase1); 1508 os_free(eap->phase2); 1509 os_free(eap->pcsc); 1510 os_free(eap->pin); 1511 os_free(eap->engine_id); 1512 os_free(eap->key_id); 1513 os_free(eap->cert_id); 1514 os_free(eap->ca_cert_id); 1515 os_free(eap->key2_id); 1516 os_free(eap->cert2_id); 1517 os_free(eap->ca_cert2_id); 1518 os_free(eap->pin2); 1519 os_free(eap->engine2_id); 1520 os_free(eap->otp); 1521 os_free(eap->pending_req_otp); 1522 os_free(eap->pac_file); 1523 os_free(eap->new_password); 1524 } 1525 #endif /* IEEE8021X_EAPOL */ 1526 1527 1528 /** 1529 * wpa_config_free_ssid - Free network/ssid configuration data 1530 * @ssid: Configuration data for the network 1531 * 1532 * This function frees all resources allocated for the network configuration 1533 * data. 1534 */ 1535 void wpa_config_free_ssid(struct wpa_ssid *ssid) 1536 { 1537 os_free(ssid->ssid); 1538 os_free(ssid->passphrase); 1539 #ifdef IEEE8021X_EAPOL 1540 eap_peer_config_free(&ssid->eap); 1541 #endif /* IEEE8021X_EAPOL */ 1542 os_free(ssid->id_str); 1543 os_free(ssid); 1544 } 1545 1546 1547 /** 1548 * wpa_config_free - Free configuration data 1549 * @config: Configuration data from wpa_config_read() 1550 * 1551 * This function frees all resources allocated for the configuration data by 1552 * wpa_config_read(). 1553 */ 1554 void wpa_config_free(struct wpa_config *config) 1555 { 1556 #ifndef CONFIG_NO_CONFIG_BLOBS 1557 struct wpa_config_blob *blob, *prevblob; 1558 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1559 struct wpa_ssid *ssid, *prev = NULL; 1560 ssid = config->ssid; 1561 while (ssid) { 1562 prev = ssid; 1563 ssid = ssid->next; 1564 wpa_config_free_ssid(prev); 1565 } 1566 1567 #ifndef CONFIG_NO_CONFIG_BLOBS 1568 blob = config->blobs; 1569 prevblob = NULL; 1570 while (blob) { 1571 prevblob = blob; 1572 blob = blob->next; 1573 wpa_config_free_blob(prevblob); 1574 } 1575 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1576 1577 os_free(config->ctrl_interface); 1578 os_free(config->ctrl_interface_group); 1579 #ifdef EAP_TLS_OPENSSL 1580 os_free(config->opensc_engine_path); 1581 os_free(config->pkcs11_engine_path); 1582 os_free(config->pkcs11_module_path); 1583 #endif /* EAP_TLS_OPENSSL */ 1584 os_free(config->driver_param); 1585 os_free(config->device_name); 1586 os_free(config->manufacturer); 1587 os_free(config->model_name); 1588 os_free(config->model_number); 1589 os_free(config->serial_number); 1590 os_free(config->device_type); 1591 os_free(config->pssid); 1592 os_free(config); 1593 } 1594 1595 1596 /** 1597 * wpa_config_get_network - Get configured network based on id 1598 * @config: Configuration data from wpa_config_read() 1599 * @id: Unique network id to search for 1600 * Returns: Network configuration or %NULL if not found 1601 */ 1602 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id) 1603 { 1604 struct wpa_ssid *ssid; 1605 1606 ssid = config->ssid; 1607 while (ssid) { 1608 if (id == ssid->id) 1609 break; 1610 ssid = ssid->next; 1611 } 1612 1613 return ssid; 1614 } 1615 1616 1617 /** 1618 * wpa_config_add_network - Add a new network with empty configuration 1619 * @config: Configuration data from wpa_config_read() 1620 * Returns: The new network configuration or %NULL if operation failed 1621 */ 1622 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config) 1623 { 1624 int id; 1625 struct wpa_ssid *ssid, *last = NULL; 1626 1627 id = -1; 1628 ssid = config->ssid; 1629 while (ssid) { 1630 if (ssid->id > id) 1631 id = ssid->id; 1632 last = ssid; 1633 ssid = ssid->next; 1634 } 1635 id++; 1636 1637 ssid = os_zalloc(sizeof(*ssid)); 1638 if (ssid == NULL) 1639 return NULL; 1640 ssid->id = id; 1641 if (last) 1642 last->next = ssid; 1643 else 1644 config->ssid = ssid; 1645 1646 wpa_config_update_prio_list(config); 1647 1648 return ssid; 1649 } 1650 1651 1652 /** 1653 * wpa_config_remove_network - Remove a configured network based on id 1654 * @config: Configuration data from wpa_config_read() 1655 * @id: Unique network id to search for 1656 * Returns: 0 on success, or -1 if the network was not found 1657 */ 1658 int wpa_config_remove_network(struct wpa_config *config, int id) 1659 { 1660 struct wpa_ssid *ssid, *prev = NULL; 1661 1662 ssid = config->ssid; 1663 while (ssid) { 1664 if (id == ssid->id) 1665 break; 1666 prev = ssid; 1667 ssid = ssid->next; 1668 } 1669 1670 if (ssid == NULL) 1671 return -1; 1672 1673 if (prev) 1674 prev->next = ssid->next; 1675 else 1676 config->ssid = ssid->next; 1677 1678 wpa_config_update_prio_list(config); 1679 wpa_config_free_ssid(ssid); 1680 return 0; 1681 } 1682 1683 1684 /** 1685 * wpa_config_set_network_defaults - Set network default values 1686 * @ssid: Pointer to network configuration data 1687 */ 1688 void wpa_config_set_network_defaults(struct wpa_ssid *ssid) 1689 { 1690 ssid->proto = DEFAULT_PROTO; 1691 ssid->pairwise_cipher = DEFAULT_PAIRWISE; 1692 ssid->group_cipher = DEFAULT_GROUP; 1693 ssid->key_mgmt = DEFAULT_KEY_MGMT; 1694 #ifdef IEEE8021X_EAPOL 1695 ssid->eapol_flags = DEFAULT_EAPOL_FLAGS; 1696 ssid->eap_workaround = DEFAULT_EAP_WORKAROUND; 1697 ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE; 1698 #endif /* IEEE8021X_EAPOL */ 1699 } 1700 1701 1702 /** 1703 * wpa_config_set - Set a variable in network configuration 1704 * @ssid: Pointer to network configuration data 1705 * @var: Variable name, e.g., "ssid" 1706 * @value: Variable value 1707 * @line: Line number in configuration file or 0 if not used 1708 * Returns: 0 on success, -1 on failure 1709 * 1710 * This function can be used to set network configuration variables based on 1711 * both the configuration file and management interface input. The value 1712 * parameter must be in the same format as the text-based configuration file is 1713 * using. For example, strings are using double quotation marks. 1714 */ 1715 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, 1716 int line) 1717 { 1718 size_t i; 1719 int ret = 0; 1720 1721 if (ssid == NULL || var == NULL || value == NULL) 1722 return -1; 1723 1724 for (i = 0; i < NUM_SSID_FIELDS; i++) { 1725 const struct parse_data *field = &ssid_fields[i]; 1726 if (os_strcmp(var, field->name) != 0) 1727 continue; 1728 1729 if (field->parser(field, ssid, line, value)) { 1730 if (line) { 1731 wpa_printf(MSG_ERROR, "Line %d: failed to " 1732 "parse %s '%s'.", line, var, value); 1733 } 1734 ret = -1; 1735 } 1736 break; 1737 } 1738 if (i == NUM_SSID_FIELDS) { 1739 if (line) { 1740 wpa_printf(MSG_ERROR, "Line %d: unknown network field " 1741 "'%s'.", line, var); 1742 } 1743 ret = -1; 1744 } 1745 1746 return ret; 1747 } 1748 1749 1750 #ifndef NO_CONFIG_WRITE 1751 /** 1752 * wpa_config_get - Get a variable in network configuration 1753 * @ssid: Pointer to network configuration data 1754 * @var: Variable name, e.g., "ssid" 1755 * Returns: Value of the variable or %NULL on failure 1756 * 1757 * This function can be used to get network configuration variables. The 1758 * returned value is a copy of the configuration variable in text format, i.e,. 1759 * the same format that the text-based configuration file and wpa_config_set() 1760 * are using for the value. The caller is responsible for freeing the returned 1761 * value. 1762 */ 1763 char * wpa_config_get(struct wpa_ssid *ssid, const char *var) 1764 { 1765 size_t i; 1766 1767 if (ssid == NULL || var == NULL) 1768 return NULL; 1769 1770 for (i = 0; i < NUM_SSID_FIELDS; i++) { 1771 const struct parse_data *field = &ssid_fields[i]; 1772 if (os_strcmp(var, field->name) == 0) 1773 return field->writer(field, ssid); 1774 } 1775 1776 return NULL; 1777 } 1778 1779 1780 /** 1781 * wpa_config_get_no_key - Get a variable in network configuration (no keys) 1782 * @ssid: Pointer to network configuration data 1783 * @var: Variable name, e.g., "ssid" 1784 * Returns: Value of the variable or %NULL on failure 1785 * 1786 * This function can be used to get network configuration variable like 1787 * wpa_config_get(). The only difference is that this functions does not expose 1788 * key/password material from the configuration. In case a key/password field 1789 * is requested, the returned value is an empty string or %NULL if the variable 1790 * is not set or "*" if the variable is set (regardless of its value). The 1791 * returned value is a copy of the configuration variable in text format, i.e,. 1792 * the same format that the text-based configuration file and wpa_config_set() 1793 * are using for the value. The caller is responsible for freeing the returned 1794 * value. 1795 */ 1796 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var) 1797 { 1798 size_t i; 1799 1800 if (ssid == NULL || var == NULL) 1801 return NULL; 1802 1803 for (i = 0; i < NUM_SSID_FIELDS; i++) { 1804 const struct parse_data *field = &ssid_fields[i]; 1805 if (os_strcmp(var, field->name) == 0) { 1806 char *res = field->writer(field, ssid); 1807 if (field->key_data) { 1808 if (res && res[0]) { 1809 wpa_printf(MSG_DEBUG, "Do not allow " 1810 "key_data field to be " 1811 "exposed"); 1812 os_free(res); 1813 return os_strdup("*"); 1814 } 1815 1816 os_free(res); 1817 return NULL; 1818 } 1819 return res; 1820 } 1821 } 1822 1823 return NULL; 1824 } 1825 #endif /* NO_CONFIG_WRITE */ 1826 1827 1828 /** 1829 * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID 1830 * @ssid: Pointer to network configuration data 1831 * 1832 * This function must be called to update WPA PSK when either SSID or the 1833 * passphrase has changed for the network configuration. 1834 */ 1835 void wpa_config_update_psk(struct wpa_ssid *ssid) 1836 { 1837 #ifndef CONFIG_NO_PBKDF2 1838 pbkdf2_sha1(ssid->passphrase, 1839 (char *) ssid->ssid, ssid->ssid_len, 4096, 1840 ssid->psk, PMK_LEN); 1841 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)", 1842 ssid->psk, PMK_LEN); 1843 ssid->psk_set = 1; 1844 #endif /* CONFIG_NO_PBKDF2 */ 1845 } 1846 1847 1848 #ifndef CONFIG_NO_CONFIG_BLOBS 1849 /** 1850 * wpa_config_get_blob - Get a named configuration blob 1851 * @config: Configuration data from wpa_config_read() 1852 * @name: Name of the blob 1853 * Returns: Pointer to blob data or %NULL if not found 1854 */ 1855 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config, 1856 const char *name) 1857 { 1858 struct wpa_config_blob *blob = config->blobs; 1859 1860 while (blob) { 1861 if (os_strcmp(blob->name, name) == 0) 1862 return blob; 1863 blob = blob->next; 1864 } 1865 return NULL; 1866 } 1867 1868 1869 /** 1870 * wpa_config_set_blob - Set or add a named configuration blob 1871 * @config: Configuration data from wpa_config_read() 1872 * @blob: New value for the blob 1873 * 1874 * Adds a new configuration blob or replaces the current value of an existing 1875 * blob. 1876 */ 1877 void wpa_config_set_blob(struct wpa_config *config, 1878 struct wpa_config_blob *blob) 1879 { 1880 wpa_config_remove_blob(config, blob->name); 1881 blob->next = config->blobs; 1882 config->blobs = blob; 1883 } 1884 1885 1886 /** 1887 * wpa_config_free_blob - Free blob data 1888 * @blob: Pointer to blob to be freed 1889 */ 1890 void wpa_config_free_blob(struct wpa_config_blob *blob) 1891 { 1892 if (blob) { 1893 os_free(blob->name); 1894 os_free(blob->data); 1895 os_free(blob); 1896 } 1897 } 1898 1899 1900 /** 1901 * wpa_config_remove_blob - Remove a named configuration blob 1902 * @config: Configuration data from wpa_config_read() 1903 * @name: Name of the blob to remove 1904 * Returns: 0 if blob was removed or -1 if blob was not found 1905 */ 1906 int wpa_config_remove_blob(struct wpa_config *config, const char *name) 1907 { 1908 struct wpa_config_blob *pos = config->blobs, *prev = NULL; 1909 1910 while (pos) { 1911 if (os_strcmp(pos->name, name) == 0) { 1912 if (prev) 1913 prev->next = pos->next; 1914 else 1915 config->blobs = pos->next; 1916 wpa_config_free_blob(pos); 1917 return 0; 1918 } 1919 prev = pos; 1920 pos = pos->next; 1921 } 1922 1923 return -1; 1924 } 1925 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1926 1927 1928 /** 1929 * wpa_config_alloc_empty - Allocate an empty configuration 1930 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain 1931 * socket 1932 * @driver_param: Driver parameters 1933 * Returns: Pointer to allocated configuration data or %NULL on failure 1934 */ 1935 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, 1936 const char *driver_param) 1937 { 1938 struct wpa_config *config; 1939 1940 config = os_zalloc(sizeof(*config)); 1941 if (config == NULL) 1942 return NULL; 1943 config->eapol_version = DEFAULT_EAPOL_VERSION; 1944 config->ap_scan = DEFAULT_AP_SCAN; 1945 config->fast_reauth = DEFAULT_FAST_REAUTH; 1946 1947 if (ctrl_interface) 1948 config->ctrl_interface = os_strdup(ctrl_interface); 1949 if (driver_param) 1950 config->driver_param = os_strdup(driver_param); 1951 1952 return config; 1953 } 1954 1955 1956 #ifndef CONFIG_NO_STDOUT_DEBUG 1957 /** 1958 * wpa_config_debug_dump_networks - Debug dump of configured networks 1959 * @config: Configuration data from wpa_config_read() 1960 */ 1961 void wpa_config_debug_dump_networks(struct wpa_config *config) 1962 { 1963 int prio; 1964 struct wpa_ssid *ssid; 1965 1966 for (prio = 0; prio < config->num_prio; prio++) { 1967 ssid = config->pssid[prio]; 1968 wpa_printf(MSG_DEBUG, "Priority group %d", 1969 ssid->priority); 1970 while (ssid) { 1971 wpa_printf(MSG_DEBUG, " id=%d ssid='%s'", 1972 ssid->id, 1973 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1974 ssid = ssid->pnext; 1975 } 1976 } 1977 } 1978 #endif /* CONFIG_NO_STDOUT_DEBUG */ 1979