00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "includes.h"
00037
00038 #include "common.h"
00039 #include "uuid.h"
00040 #include "config.h"
00041
00042 #ifndef WPA_KEY_ROOT
00043 #define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
00044 #endif
00045 #ifndef WPA_KEY_PREFIX
00046 #define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
00047 #endif
00048
00049 #ifdef UNICODE
00050 #define TSTR "%S"
00051 #else
00052 #define TSTR "%s"
00053 #endif
00054
00055
00056 static int wpa_config_read_blobs(struct wpa_config *config, HKEY hk)
00057 {
00058 struct wpa_config_blob *blob;
00059 int errors = 0;
00060 HKEY bhk;
00061 LONG ret;
00062 DWORD i;
00063
00064 ret = RegOpenKeyEx(hk, TEXT("blobs"), 0, KEY_QUERY_VALUE, &bhk);
00065 if (ret != ERROR_SUCCESS) {
00066 wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
00067 "blobs key");
00068 return 0;
00069 }
00070
00071 for (i = 0; ; i++) {
00072 #define TNAMELEN 255
00073 TCHAR name[TNAMELEN];
00074 char data[4096];
00075 DWORD namelen, datalen, type;
00076
00077 namelen = TNAMELEN;
00078 datalen = sizeof(data);
00079 ret = RegEnumValue(bhk, i, name, &namelen, NULL, &type,
00080 (LPBYTE) data, &datalen);
00081
00082 if (ret == ERROR_NO_MORE_ITEMS)
00083 break;
00084
00085 if (ret != ERROR_SUCCESS) {
00086 wpa_printf(MSG_DEBUG, "RegEnumValue failed: 0x%x",
00087 (unsigned int) ret);
00088 break;
00089 }
00090
00091 if (namelen >= TNAMELEN)
00092 namelen = TNAMELEN - 1;
00093 name[namelen] = TEXT('\0');
00094 wpa_unicode2ascii_inplace(name);
00095
00096 if (datalen >= sizeof(data))
00097 datalen = sizeof(data) - 1;
00098
00099 wpa_printf(MSG_MSGDUMP, "blob %d: field='%s' len %d",
00100 (int) i, name, (int) datalen);
00101
00102 blob = os_zalloc(sizeof(*blob));
00103 if (blob == NULL) {
00104 errors++;
00105 break;
00106 }
00107 blob->name = os_strdup((char *) name);
00108 blob->data = os_malloc(datalen);
00109 if (blob->name == NULL || blob->data == NULL) {
00110 wpa_config_free_blob(blob);
00111 errors++;
00112 break;
00113 }
00114 os_memcpy(blob->data, data, datalen);
00115 blob->len = datalen;
00116
00117 wpa_config_set_blob(config, blob);
00118 }
00119
00120 RegCloseKey(bhk);
00121
00122 return errors ? -1 : 0;
00123 }
00124
00125
00126 static int wpa_config_read_reg_dword(HKEY hk, const TCHAR *name, int *_val)
00127 {
00128 DWORD val, buflen;
00129 LONG ret;
00130
00131 buflen = sizeof(val);
00132 ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) &val, &buflen);
00133 if (ret == ERROR_SUCCESS && buflen == sizeof(val)) {
00134 wpa_printf(MSG_DEBUG, TSTR "=%d", name, (int) val);
00135 *_val = val;
00136 return 0;
00137 }
00138
00139 return -1;
00140 }
00141
00142
00143 static char * wpa_config_read_reg_string(HKEY hk, const TCHAR *name)
00144 {
00145 DWORD buflen;
00146 LONG ret;
00147 TCHAR *val;
00148
00149 buflen = 0;
00150 ret = RegQueryValueEx(hk, name, NULL, NULL, NULL, &buflen);
00151 if (ret != ERROR_SUCCESS)
00152 return NULL;
00153 val = os_malloc(buflen);
00154 if (val == NULL)
00155 return NULL;
00156
00157 ret = RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE) val, &buflen);
00158 if (ret != ERROR_SUCCESS) {
00159 os_free(val);
00160 return NULL;
00161 }
00162
00163 wpa_unicode2ascii_inplace(val);
00164 wpa_printf(MSG_DEBUG, TSTR "=%s", name, (char *) val);
00165 return (char *) val;
00166 }
00167
00168
00169 #ifdef CONFIG_WPS
00170 static int wpa_config_read_global_uuid(struct wpa_config *config, HKEY hk)
00171 {
00172 char *str;
00173 int ret = 0;
00174
00175 str = wpa_config_read_reg_string(hk, TEXT("uuid"));
00176 if (str == NULL)
00177 return 0;
00178
00179 if (uuid_str2bin(str, config->uuid))
00180 ret = -1;
00181
00182 os_free(str);
00183
00184 return ret;
00185 }
00186
00187
00188 static int wpa_config_read_global_os_version(struct wpa_config *config,
00189 HKEY hk)
00190 {
00191 char *str;
00192 int ret = 0;
00193
00194 str = wpa_config_read_reg_string(hk, TEXT("os_version"));
00195 if (str == NULL)
00196 return 0;
00197
00198 if (hexstr2bin(str, config->os_version, 4))
00199 ret = -1;
00200
00201 os_free(str);
00202
00203 return ret;
00204 }
00205 #endif
00206
00207
00208 static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
00209 {
00210 int errors = 0;
00211
00212 wpa_config_read_reg_dword(hk, TEXT("ap_scan"), &config->ap_scan);
00213 wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
00214 &config->fast_reauth);
00215 wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
00216 (int *) &config->dot11RSNAConfigPMKLifetime);
00217 wpa_config_read_reg_dword(hk,
00218 TEXT("dot11RSNAConfigPMKReauthThreshold"),
00219 (int *)
00220 &config->dot11RSNAConfigPMKReauthThreshold);
00221 wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
00222 (int *) &config->dot11RSNAConfigSATimeout);
00223 wpa_config_read_reg_dword(hk, TEXT("update_config"),
00224 &config->update_config);
00225
00226 if (wpa_config_read_reg_dword(hk, TEXT("eapol_version"),
00227 &config->eapol_version) == 0) {
00228 if (config->eapol_version < 1 ||
00229 config->eapol_version > 2) {
00230 wpa_printf(MSG_ERROR, "Invalid EAPOL version (%d)",
00231 config->eapol_version);
00232 errors++;
00233 }
00234 }
00235
00236 config->ctrl_interface = wpa_config_read_reg_string(
00237 hk, TEXT("ctrl_interface"));
00238
00239 #ifdef CONFIG_WPS
00240 if (wpa_config_read_global_uuid(config, hk))
00241 errors++;
00242 config->device_name = wpa_config_read_reg_string(
00243 hk, TEXT("device_name"));
00244 config->manufacturer = wpa_config_read_reg_string(
00245 hk, TEXT("manufacturer"));
00246 config->model_name = wpa_config_read_reg_string(
00247 hk, TEXT("model_name"));
00248 config->serial_number = wpa_config_read_reg_string(
00249 hk, TEXT("serial_number"));
00250 config->device_type = wpa_config_read_reg_string(
00251 hk, TEXT("device_type"));
00252 config->config_methods = wpa_config_read_reg_string(
00253 hk, TEXT("config_methods"));
00254 if (wpa_config_read_global_os_version(config, hk))
00255 errors++;
00256 wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
00257 &config->wps_cred_processing);
00258 #endif
00259
00260 wpa_config_read_reg_dword(hk, TEXT("bss_max_count"),
00261 &config->bss_max_count);
00262 wpa_config_read_reg_dword(hk, TEXT("filter_ssids"),
00263 &config->filter_ssids);
00264
00265 return errors ? -1 : 0;
00266 }
00267
00268
00269 static struct wpa_ssid * wpa_config_read_network(HKEY hk, const TCHAR *netw,
00270 int id)
00271 {
00272 HKEY nhk;
00273 LONG ret;
00274 DWORD i;
00275 struct wpa_ssid *ssid;
00276 int errors = 0;
00277
00278 ret = RegOpenKeyEx(hk, netw, 0, KEY_QUERY_VALUE, &nhk);
00279 if (ret != ERROR_SUCCESS) {
00280 wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config "
00281 "network '" TSTR "'", netw);
00282 return NULL;
00283 }
00284
00285 wpa_printf(MSG_MSGDUMP, "Start of a new network '" TSTR "'", netw);
00286 ssid = os_zalloc(sizeof(*ssid));
00287 if (ssid == NULL) {
00288 RegCloseKey(nhk);
00289 return NULL;
00290 }
00291 ssid->id = id;
00292
00293 wpa_config_set_network_defaults(ssid);
00294
00295 for (i = 0; ; i++) {
00296 TCHAR name[255], data[1024];
00297 DWORD namelen, datalen, type;
00298
00299 namelen = 255;
00300 datalen = sizeof(data);
00301 ret = RegEnumValue(nhk, i, name, &namelen, NULL, &type,
00302 (LPBYTE) data, &datalen);
00303
00304 if (ret == ERROR_NO_MORE_ITEMS)
00305 break;
00306
00307 if (ret != ERROR_SUCCESS) {
00308 wpa_printf(MSG_ERROR, "RegEnumValue failed: 0x%x",
00309 (unsigned int) ret);
00310 break;
00311 }
00312
00313 if (namelen >= 255)
00314 namelen = 255 - 1;
00315 name[namelen] = TEXT('\0');
00316
00317 if (datalen >= 1024)
00318 datalen = 1024 - 1;
00319 data[datalen] = TEXT('\0');
00320
00321 wpa_unicode2ascii_inplace(name);
00322 wpa_unicode2ascii_inplace(data);
00323 if (wpa_config_set(ssid, (char *) name, (char *) data, 0) < 0)
00324 errors++;
00325 }
00326
00327 RegCloseKey(nhk);
00328
00329 if (ssid->passphrase) {
00330 if (ssid->psk_set) {
00331 wpa_printf(MSG_ERROR, "Both PSK and passphrase "
00332 "configured for network '" TSTR "'.", netw);
00333 errors++;
00334 }
00335 wpa_config_update_psk(ssid);
00336 }
00337
00338 if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
00339 WPA_KEY_MGMT_PSK_SHA256)) &&
00340 !ssid->psk_set) {
00341 wpa_printf(MSG_ERROR, "WPA-PSK accepted for key management, "
00342 "but no PSK configured for network '" TSTR "'.",
00343 netw);
00344 errors++;
00345 }
00346
00347 if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
00348 !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
00349 !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) {
00350
00351 wpa_printf(MSG_DEBUG, "Removed CCMP from group cipher "
00352 "list since it was not allowed for pairwise "
00353 "cipher for network '" TSTR "'.", netw);
00354 ssid->group_cipher &= ~WPA_CIPHER_CCMP;
00355 }
00356
00357 if (errors) {
00358 wpa_config_free_ssid(ssid);
00359 ssid = NULL;
00360 }
00361
00362 return ssid;
00363 }
00364
00365
00366 static int wpa_config_read_networks(struct wpa_config *config, HKEY hk)
00367 {
00368 HKEY nhk;
00369 struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
00370 int errors = 0;
00371 LONG ret;
00372 DWORD i;
00373
00374 ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_ENUMERATE_SUB_KEYS,
00375 &nhk);
00376 if (ret != ERROR_SUCCESS) {
00377 wpa_printf(MSG_ERROR, "Could not open wpa_supplicant networks "
00378 "registry key");
00379 return -1;
00380 }
00381
00382 for (i = 0; ; i++) {
00383 TCHAR name[255];
00384 DWORD namelen;
00385
00386 namelen = 255;
00387 ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
00388 NULL);
00389
00390 if (ret == ERROR_NO_MORE_ITEMS)
00391 break;
00392
00393 if (ret != ERROR_SUCCESS) {
00394 wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x",
00395 (unsigned int) ret);
00396 break;
00397 }
00398
00399 if (namelen >= 255)
00400 namelen = 255 - 1;
00401 name[namelen] = '\0';
00402
00403 ssid = wpa_config_read_network(nhk, name, i);
00404 if (ssid == NULL) {
00405 wpa_printf(MSG_ERROR, "Failed to parse network "
00406 "profile '%s'.", name);
00407 errors++;
00408 continue;
00409 }
00410 if (head == NULL) {
00411 head = tail = ssid;
00412 } else {
00413 tail->next = ssid;
00414 tail = ssid;
00415 }
00416 if (wpa_config_add_prio_network(config, ssid)) {
00417 wpa_printf(MSG_ERROR, "Failed to add network profile "
00418 "'%s' to priority list.", name);
00419 errors++;
00420 continue;
00421 }
00422 }
00423
00424 RegCloseKey(nhk);
00425
00426 config->ssid = head;
00427
00428 return errors ? -1 : 0;
00429 }
00430
00431
00432 struct wpa_config * wpa_config_read(const char *name)
00433 {
00434 TCHAR buf[256];
00435 int errors = 0;
00436 struct wpa_config *config;
00437 HKEY hk;
00438 LONG ret;
00439
00440 config = wpa_config_alloc_empty(NULL, NULL);
00441 if (config == NULL)
00442 return NULL;
00443 wpa_printf(MSG_DEBUG, "Reading configuration profile '%s'", name);
00444
00445 #ifdef UNICODE
00446 _snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
00447 #else
00448 os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
00449 #endif
00450
00451 ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_QUERY_VALUE, &hk);
00452 if (ret != ERROR_SUCCESS) {
00453 wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
00454 "configuration registry HKLM\\" TSTR, buf);
00455 os_free(config);
00456 return NULL;
00457 }
00458
00459 if (wpa_config_read_global(config, hk))
00460 errors++;
00461
00462 if (wpa_config_read_networks(config, hk))
00463 errors++;
00464
00465 if (wpa_config_read_blobs(config, hk))
00466 errors++;
00467
00468 wpa_config_debug_dump_networks(config);
00469
00470 RegCloseKey(hk);
00471
00472 if (errors) {
00473 wpa_config_free(config);
00474 config = NULL;
00475 }
00476
00477 return config;
00478 }
00479
00480
00481 static int wpa_config_write_reg_dword(HKEY hk, const TCHAR *name, int val,
00482 int def)
00483 {
00484 LONG ret;
00485 DWORD _val = val;
00486
00487 if (val == def) {
00488 RegDeleteValue(hk, name);
00489 return 0;
00490 }
00491
00492 ret = RegSetValueEx(hk, name, 0, REG_DWORD, (LPBYTE) &_val,
00493 sizeof(_val));
00494 if (ret != ERROR_SUCCESS) {
00495 wpa_printf(MSG_ERROR, "WINREG: Failed to set %s=%d: error %d",
00496 name, val, (int) GetLastError());
00497 return -1;
00498 }
00499
00500 return 0;
00501 }
00502
00503
00504 static int wpa_config_write_reg_string(HKEY hk, const char *name,
00505 const char *val)
00506 {
00507 LONG ret;
00508 TCHAR *_name, *_val;
00509
00510 _name = wpa_strdup_tchar(name);
00511 if (_name == NULL)
00512 return -1;
00513
00514 if (val == NULL) {
00515 RegDeleteValue(hk, _name);
00516 os_free(_name);
00517 return 0;
00518 }
00519
00520 _val = wpa_strdup_tchar(val);
00521 if (_val == NULL) {
00522 os_free(_name);
00523 return -1;
00524 }
00525 ret = RegSetValueEx(hk, _name, 0, REG_SZ, (BYTE *) _val,
00526 (os_strlen(val) + 1) * sizeof(TCHAR));
00527 if (ret != ERROR_SUCCESS) {
00528 wpa_printf(MSG_ERROR, "WINREG: Failed to set %s='%s': "
00529 "error %d", name, val, (int) GetLastError());
00530 os_free(_name);
00531 os_free(_val);
00532 return -1;
00533 }
00534
00535 os_free(_name);
00536 os_free(_val);
00537 return 0;
00538 }
00539
00540
00541 static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
00542 {
00543 #ifdef CONFIG_CTRL_IFACE
00544 wpa_config_write_reg_string(hk, "ctrl_interface",
00545 config->ctrl_interface);
00546 #endif
00547
00548 wpa_config_write_reg_dword(hk, TEXT("eapol_version"),
00549 config->eapol_version,
00550 DEFAULT_EAPOL_VERSION);
00551 wpa_config_write_reg_dword(hk, TEXT("ap_scan"), config->ap_scan,
00552 DEFAULT_AP_SCAN);
00553 wpa_config_write_reg_dword(hk, TEXT("fast_reauth"),
00554 config->fast_reauth, DEFAULT_FAST_REAUTH);
00555 wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
00556 config->dot11RSNAConfigPMKLifetime, 0);
00557 wpa_config_write_reg_dword(hk,
00558 TEXT("dot11RSNAConfigPMKReauthThreshold"),
00559 config->dot11RSNAConfigPMKReauthThreshold,
00560 0);
00561 wpa_config_write_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
00562 config->dot11RSNAConfigSATimeout, 0);
00563 wpa_config_write_reg_dword(hk, TEXT("update_config"),
00564 config->update_config,
00565 0);
00566 #ifdef CONFIG_WPS
00567 if (!is_nil_uuid(config->uuid)) {
00568 char buf[40];
00569 uuid_bin2str(config->uuid, buf, sizeof(buf));
00570 wpa_config_write_reg_string(hk, "uuid", buf);
00571 }
00572 wpa_config_write_reg_string(hk, "device_name", config->device_name);
00573 wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
00574 wpa_config_write_reg_string(hk, "model_name", config->model_name);
00575 wpa_config_write_reg_string(hk, "model_number", config->model_number);
00576 wpa_config_write_reg_string(hk, "serial_number",
00577 config->serial_number);
00578 wpa_config_write_reg_string(hk, "device_type", config->device_type);
00579 wpa_config_write_reg_string(hk, "config_methods",
00580 config->config_methods);
00581 if (WPA_GET_BE32(config->os_version)) {
00582 char vbuf[10];
00583 os_snprintf(vbuf, sizeof(vbuf), "%08x",
00584 WPA_GET_BE32(config->os_version));
00585 wpa_config_write_reg_string(hk, "os_version", vbuf);
00586 }
00587 wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
00588 config->wps_cred_processing, 0);
00589 #endif
00590
00591 wpa_config_write_reg_dword(hk, TEXT("bss_max_count"),
00592 config->bss_max_count,
00593 DEFAULT_BSS_MAX_COUNT);
00594 wpa_config_write_reg_dword(hk, TEXT("filter_ssids"),
00595 config->filter_ssids, 0);
00596
00597 return 0;
00598 }
00599
00600
00601 static int wpa_config_delete_subkeys(HKEY hk, const TCHAR *key)
00602 {
00603 HKEY nhk;
00604 int i, errors = 0;
00605 LONG ret;
00606
00607 ret = RegOpenKeyEx(hk, key, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &nhk);
00608 if (ret != ERROR_SUCCESS) {
00609 wpa_printf(MSG_DEBUG, "WINREG: Could not open key '" TSTR
00610 "' for subkey deletion: error 0x%x (%d)", key,
00611 (unsigned int) ret, (int) GetLastError());
00612 return 0;
00613 }
00614
00615 for (i = 0; ; i++) {
00616 TCHAR name[255];
00617 DWORD namelen;
00618
00619 namelen = 255;
00620 ret = RegEnumKeyEx(nhk, i, name, &namelen, NULL, NULL, NULL,
00621 NULL);
00622
00623 if (ret == ERROR_NO_MORE_ITEMS)
00624 break;
00625
00626 if (ret != ERROR_SUCCESS) {
00627 wpa_printf(MSG_DEBUG, "RegEnumKeyEx failed: 0x%x (%d)",
00628 (unsigned int) ret, (int) GetLastError());
00629 break;
00630 }
00631
00632 if (namelen >= 255)
00633 namelen = 255 - 1;
00634 name[namelen] = TEXT('\0');
00635
00636 ret = RegDeleteKey(nhk, name);
00637 if (ret != ERROR_SUCCESS) {
00638 wpa_printf(MSG_DEBUG, "RegDeleteKey failed: 0x%x (%d)",
00639 (unsigned int) ret, (int) GetLastError());
00640 errors++;
00641 }
00642 }
00643
00644 RegCloseKey(nhk);
00645
00646 return errors ? -1 : 0;
00647 }
00648
00649
00650 static void write_str(HKEY hk, const char *field, struct wpa_ssid *ssid)
00651 {
00652 char *value = wpa_config_get(ssid, field);
00653 if (value == NULL)
00654 return;
00655 wpa_config_write_reg_string(hk, field, value);
00656 os_free(value);
00657 }
00658
00659
00660 static void write_int(HKEY hk, const char *field, int value, int def)
00661 {
00662 char val[20];
00663 if (value == def)
00664 return;
00665 os_snprintf(val, sizeof(val), "%d", value);
00666 wpa_config_write_reg_string(hk, field, val);
00667 }
00668
00669
00670 static void write_bssid(HKEY hk, struct wpa_ssid *ssid)
00671 {
00672 char *value = wpa_config_get(ssid, "bssid");
00673 if (value == NULL)
00674 return;
00675 wpa_config_write_reg_string(hk, "bssid", value);
00676 os_free(value);
00677 }
00678
00679
00680 static void write_psk(HKEY hk, struct wpa_ssid *ssid)
00681 {
00682 char *value = wpa_config_get(ssid, "psk");
00683 if (value == NULL)
00684 return;
00685 wpa_config_write_reg_string(hk, "psk", value);
00686 os_free(value);
00687 }
00688
00689
00690 static void write_proto(HKEY hk, struct wpa_ssid *ssid)
00691 {
00692 char *value;
00693
00694 if (ssid->proto == DEFAULT_PROTO)
00695 return;
00696
00697 value = wpa_config_get(ssid, "proto");
00698 if (value == NULL)
00699 return;
00700 if (value[0])
00701 wpa_config_write_reg_string(hk, "proto", value);
00702 os_free(value);
00703 }
00704
00705
00706 static void write_key_mgmt(HKEY hk, struct wpa_ssid *ssid)
00707 {
00708 char *value;
00709
00710 if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
00711 return;
00712
00713 value = wpa_config_get(ssid, "key_mgmt");
00714 if (value == NULL)
00715 return;
00716 if (value[0])
00717 wpa_config_write_reg_string(hk, "key_mgmt", value);
00718 os_free(value);
00719 }
00720
00721
00722 static void write_pairwise(HKEY hk, struct wpa_ssid *ssid)
00723 {
00724 char *value;
00725
00726 if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
00727 return;
00728
00729 value = wpa_config_get(ssid, "pairwise");
00730 if (value == NULL)
00731 return;
00732 if (value[0])
00733 wpa_config_write_reg_string(hk, "pairwise", value);
00734 os_free(value);
00735 }
00736
00737
00738 static void write_group(HKEY hk, struct wpa_ssid *ssid)
00739 {
00740 char *value;
00741
00742 if (ssid->group_cipher == DEFAULT_GROUP)
00743 return;
00744
00745 value = wpa_config_get(ssid, "group");
00746 if (value == NULL)
00747 return;
00748 if (value[0])
00749 wpa_config_write_reg_string(hk, "group", value);
00750 os_free(value);
00751 }
00752
00753
00754 static void write_auth_alg(HKEY hk, struct wpa_ssid *ssid)
00755 {
00756 char *value;
00757
00758 if (ssid->auth_alg == 0)
00759 return;
00760
00761 value = wpa_config_get(ssid, "auth_alg");
00762 if (value == NULL)
00763 return;
00764 if (value[0])
00765 wpa_config_write_reg_string(hk, "auth_alg", value);
00766 os_free(value);
00767 }
00768
00769
00770 #ifdef IEEE8021X_EAPOL
00771 static void write_eap(HKEY hk, struct wpa_ssid *ssid)
00772 {
00773 char *value;
00774
00775 value = wpa_config_get(ssid, "eap");
00776 if (value == NULL)
00777 return;
00778
00779 if (value[0])
00780 wpa_config_write_reg_string(hk, "eap", value);
00781 os_free(value);
00782 }
00783 #endif
00784
00785
00786 static void write_wep_key(HKEY hk, int idx, struct wpa_ssid *ssid)
00787 {
00788 char field[20], *value;
00789
00790 os_snprintf(field, sizeof(field), "wep_key%d", idx);
00791 value = wpa_config_get(ssid, field);
00792 if (value) {
00793 wpa_config_write_reg_string(hk, field, value);
00794 os_free(value);
00795 }
00796 }
00797
00798
00799 static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
00800 {
00801 int i, errors = 0;
00802 HKEY nhk, netw;
00803 LONG ret;
00804 TCHAR name[5];
00805
00806 ret = RegOpenKeyEx(hk, TEXT("networks"), 0, KEY_CREATE_SUB_KEY, &nhk);
00807 if (ret != ERROR_SUCCESS) {
00808 wpa_printf(MSG_DEBUG, "WINREG: Could not open networks key "
00809 "for subkey addition: error 0x%x (%d)",
00810 (unsigned int) ret, (int) GetLastError());
00811 return 0;
00812 }
00813
00814 #ifdef UNICODE
00815 wsprintf(name, L"%04d", id);
00816 #else
00817 os_snprintf(name, sizeof(name), "%04d", id);
00818 #endif
00819 ret = RegCreateKeyEx(nhk, name, 0, NULL, 0, KEY_WRITE, NULL, &netw,
00820 NULL);
00821 RegCloseKey(nhk);
00822 if (ret != ERROR_SUCCESS) {
00823 wpa_printf(MSG_DEBUG, "WINREG: Could not add network key '%s':"
00824 " error 0x%x (%d)",
00825 name, (unsigned int) ret, (int) GetLastError());
00826 return -1;
00827 }
00828
00829 #define STR(t) write_str(netw, #t, ssid)
00830 #define INT(t) write_int(netw, #t, ssid->t, 0)
00831 #define INTe(t) write_int(netw, #t, ssid->eap.t, 0)
00832 #define INT_DEF(t, def) write_int(netw, #t, ssid->t, def)
00833 #define INT_DEFe(t, def) write_int(netw, #t, ssid->eap.t, def)
00834
00835 STR(ssid);
00836 INT(scan_ssid);
00837 write_bssid(netw, ssid);
00838 write_psk(netw, ssid);
00839 write_proto(netw, ssid);
00840 write_key_mgmt(netw, ssid);
00841 write_pairwise(netw, ssid);
00842 write_group(netw, ssid);
00843 write_auth_alg(netw, ssid);
00844 #ifdef IEEE8021X_EAPOL
00845 write_eap(netw, ssid);
00846 STR(identity);
00847 STR(anonymous_identity);
00848 STR(password);
00849 STR(ca_cert);
00850 STR(ca_path);
00851 STR(client_cert);
00852 STR(private_key);
00853 STR(private_key_passwd);
00854 STR(dh_file);
00855 STR(subject_match);
00856 STR(altsubject_match);
00857 STR(ca_cert2);
00858 STR(ca_path2);
00859 STR(client_cert2);
00860 STR(private_key2);
00861 STR(private_key2_passwd);
00862 STR(dh_file2);
00863 STR(subject_match2);
00864 STR(altsubject_match2);
00865 STR(phase1);
00866 STR(phase2);
00867 STR(pcsc);
00868 STR(pin);
00869 STR(engine_id);
00870 STR(key_id);
00871 STR(cert_id);
00872 STR(ca_cert_id);
00873 STR(key2_id);
00874 STR(pin2);
00875 STR(engine2_id);
00876 STR(cert2_id);
00877 STR(ca_cert2_id);
00878 INTe(engine);
00879 INTe(engine2);
00880 INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
00881 #endif
00882 for (i = 0; i < 4; i++)
00883 write_wep_key(netw, i, ssid);
00884 INT(wep_tx_keyidx);
00885 INT(priority);
00886 #ifdef IEEE8021X_EAPOL
00887 INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
00888 STR(pac_file);
00889 INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE);
00890 #endif
00891 INT(mode);
00892 INT(proactive_key_caching);
00893 INT(disabled);
00894 INT(peerkey);
00895 #ifdef CONFIG_IEEE80211W
00896 INT(ieee80211w);
00897 #endif
00898 STR(id_str);
00899
00900 #undef STR
00901 #undef INT
00902 #undef INT_DEF
00903
00904 RegCloseKey(netw);
00905
00906 return errors ? -1 : 0;
00907 }
00908
00909
00910 static int wpa_config_write_blob(HKEY hk, struct wpa_config_blob *blob)
00911 {
00912 HKEY bhk;
00913 LONG ret;
00914 TCHAR *name;
00915
00916 ret = RegCreateKeyEx(hk, TEXT("blobs"), 0, NULL, 0, KEY_WRITE, NULL,
00917 &bhk, NULL);
00918 if (ret != ERROR_SUCCESS) {
00919 wpa_printf(MSG_DEBUG, "WINREG: Could not add blobs key: "
00920 "error 0x%x (%d)",
00921 (unsigned int) ret, (int) GetLastError());
00922 return -1;
00923 }
00924
00925 name = wpa_strdup_tchar(blob->name);
00926 ret = RegSetValueEx(bhk, name, 0, REG_BINARY, blob->data,
00927 blob->len);
00928 if (ret != ERROR_SUCCESS) {
00929 wpa_printf(MSG_ERROR, "WINREG: Failed to set blob %s': "
00930 "error 0x%x (%d)", blob->name, (unsigned int) ret,
00931 (int) GetLastError());
00932 RegCloseKey(bhk);
00933 os_free(name);
00934 return -1;
00935 }
00936 os_free(name);
00937
00938 RegCloseKey(bhk);
00939
00940 return 0;
00941 }
00942
00943
00944 int wpa_config_write(const char *name, struct wpa_config *config)
00945 {
00946 TCHAR buf[256];
00947 HKEY hk;
00948 LONG ret;
00949 int errors = 0;
00950 struct wpa_ssid *ssid;
00951 struct wpa_config_blob *blob;
00952 int id;
00953
00954 wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
00955
00956 #ifdef UNICODE
00957 _snwprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%S"), name);
00958 #else
00959 os_snprintf(buf, 256, WPA_KEY_PREFIX TEXT("\\configs\\%s"), name);
00960 #endif
00961
00962 ret = RegOpenKeyEx(WPA_KEY_ROOT, buf, 0, KEY_SET_VALUE | DELETE, &hk);
00963 if (ret != ERROR_SUCCESS) {
00964 wpa_printf(MSG_ERROR, "Could not open wpa_supplicant "
00965 "configuration registry %s: error %d", buf,
00966 (int) GetLastError());
00967 return -1;
00968 }
00969
00970 if (wpa_config_write_global(config, hk)) {
00971 wpa_printf(MSG_ERROR, "Failed to write global configuration "
00972 "data");
00973 errors++;
00974 }
00975
00976 wpa_config_delete_subkeys(hk, TEXT("networks"));
00977 for (ssid = config->ssid, id = 0; ssid; ssid = ssid->next, id++) {
00978 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
00979 continue;
00980 if (wpa_config_write_network(hk, ssid, id))
00981 errors++;
00982 }
00983
00984 RegDeleteKey(hk, TEXT("blobs"));
00985 for (blob = config->blobs; blob; blob = blob->next) {
00986 if (wpa_config_write_blob(hk, blob))
00987 errors++;
00988 }
00989
00990 RegCloseKey(hk);
00991
00992 wpa_printf(MSG_DEBUG, "Configuration '%s' written %ssuccessfully",
00993 name, errors ? "un" : "");
00994 return errors ? -1 : 0;
00995 }