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 "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 */ 33struct 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 60static 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 96static 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 143set: 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 156static 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 168static 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 184static 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 197static 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 209static 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 228static 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 249static 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 280static 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 302static 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 318static 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 341static 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 399static 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 415static 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 467static 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 499static 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 572static 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 664static 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 717static 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 782static 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 803static 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 811static 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 833static 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 841static 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 894static 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 941static 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 1013static 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 1048static 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 1112static 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 1137static 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 1164static 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 1174static 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 1184static 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 1194static 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 1205static 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 1214static 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 1221static 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 1228static 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 1235static 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 */ 1339static 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 */ 1454int 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 */ 1505int 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 1527static 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 */ 1577void 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 */ 1596void 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 */ 1644struct 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 */ 1664struct 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 */ 1700int 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 */ 1730void 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 */ 1757int 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 */ 1805char * 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 */ 1838char * 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 */ 1877void 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 */ 1897const 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 */ 1919void 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 */ 1932void 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 */ 1948int 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 */ 1977struct 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 */ 2003void 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