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