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