aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-08-03 18:28:42 (GMT)
committerJouni Malinen <j@w1.fi>2012-08-03 19:15:42 (GMT)
commit306ae22556623f210dfb8dc17130f153dc17eb1e (patch)
treeec937752885d39d0c119607827909d8b7eda6b5d /wpa_supplicant
parent2518aad3e83a842ff8452f9ecf6365edd0527368 (diff)
downloadhostap-306ae22556623f210dfb8dc17130f153dc17eb1e.zip
hostap-306ae22556623f210dfb8dc17130f153dc17eb1e.tar.gz
hostap-306ae22556623f210dfb8dc17130f153dc17eb1e.tar.bz2
EXT PW: Add framework for supporting external password storage
This new mechanism can be used to make wpa_supplicant using external storage (e.g., key store in the operating system) for passwords, passphrases, and PSKs. This commit is only adding the framework part needed to support this, i.e., no actual configuration parameter can yet use this new mechanism. In addition, only a simple test backend is added to allow developer testing of the functionality. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/Android.mk11
-rw-r--r--wpa_supplicant/Makefile11
-rw-r--r--wpa_supplicant/config.c4
-rw-r--r--wpa_supplicant/config.h8
-rw-r--r--wpa_supplicant/config_file.c4
-rw-r--r--wpa_supplicant/config_ssid.h8
-rw-r--r--wpa_supplicant/defconfig8
-rw-r--r--wpa_supplicant/eapol_test.c8
-rw-r--r--wpa_supplicant/wpa_supplicant.c42
-rw-r--r--wpa_supplicant/wpa_supplicant.conf4
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h6
11 files changed, 112 insertions, 2 deletions
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 0666f4d..27dda29 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1321,6 +1321,17 @@ L_CFLAGS += -DCONFIG_AUTOSCAN
OBJS += autoscan.c
endif
+ifdef CONFIG_EXT_PASSWORD_TEST
+OBJS += ../src/utils/ext_password_test.c
+L_CFLAGS += -DCONFIG_EXT_PASSWORD_TEST
+NEED_EXT_PASSWORD=y
+endif
+
+ifdef NEED_EXT_PASSWORD
+OBJS += ../src/utils/ext_password.c
+L_CFLAGS += -DCONFIG_EXT_PASSWORD
+endif
+
ifdef NEED_GAS
OBJS += ../src/common/gas.c
OBJS += gas_query.c
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index e8fe6f2..a7683dd 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -1346,6 +1346,17 @@ CFLAGS += -DCONFIG_AUTOSCAN
OBJS += autoscan.o
endif
+ifdef CONFIG_EXT_PASSWORD_TEST
+OBJS += ../src/utils/ext_password_test.o
+CFLAGS += -DCONFIG_EXT_PASSWORD_TEST
+NEED_EXT_PASSWORD=y
+endif
+
+ifdef NEED_EXT_PASSWORD
+OBJS += ../src/utils/ext_password.o
+CFLAGS += -DCONFIG_EXT_PASSWORD
+endif
+
ifdef NEED_GAS
OBJS += ../src/common/gas.o
OBJS += gas_query.o
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 54a767e..9d7f38e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1866,6 +1866,7 @@ void wpa_config_free(struct wpa_config *config)
wpabuf_free(config->wps_nfc_dh_pubkey);
wpabuf_free(config->wps_nfc_dh_privkey);
wpabuf_free(config->wps_nfc_dev_pw);
+ os_free(config->ext_password_backend);
os_free(config);
}
@@ -2968,7 +2969,8 @@ static const struct global_parse_data global_fields[] = {
{ INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff), 0 },
{ BIN(wps_nfc_dh_pubkey), 0 },
{ BIN(wps_nfc_dh_privkey), 0 },
- { BIN(wps_nfc_dev_pw), 0 }
+ { BIN(wps_nfc_dev_pw), 0 },
+ { STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND }
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 6f4f801..c8c1542 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -206,6 +206,7 @@ struct wpa_cred {
#define CFG_CHANGED_P2P_LISTEN_CHANNEL BIT(11)
#define CFG_CHANGED_P2P_OPER_CHANNEL BIT(12)
#define CFG_CHANGED_P2P_PREF_CHAN BIT(13)
+#define CFG_CHANGED_EXT_PW_BACKEND BIT(14)
/**
* struct wpa_config - wpa_supplicant configuration data
@@ -710,6 +711,13 @@ struct wpa_config {
* wps_nfc_dh_pubkey - NFC Device Password for password token
*/
struct wpabuf *wps_nfc_dev_pw;
+
+ /**
+ * ext_password_backend - External password backend or %NULL if none
+ *
+ * format: <backend name>[:<optional backend parameters>]
+ */
+ char *ext_password_backend;
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index a55a5c9..0520646 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -869,6 +869,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
write_global_bin(f, "wps_nfc_dh_pubkey", config->wps_nfc_dh_pubkey);
write_global_bin(f, "wps_nfc_dh_privkey", config->wps_nfc_dh_privkey);
write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw);
+
+ if (config->ext_password_backend)
+ fprintf(f, "ext_password_backend=%s\n",
+ config->ext_password_backend);
}
#endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index c35f7c3..f4d551d 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -141,6 +141,14 @@ struct wpa_ssid {
char *passphrase;
/**
+ * ext_psk - PSK/passphrase name in external storage
+ *
+ * If this is set, PSK/passphrase will be fetched from external storage
+ * when requesting association with the network.
+ */
+ char *ext_psk;
+
+ /**
* pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
*/
int pairwise_cipher;
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 849f244..e2b6cbe 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -512,3 +512,11 @@ CONFIG_PEERKEY=y
#CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y
+
+# Password (and passphrase, etc.) backend for external storage
+# These optional mechanisms can be used to add support for storing passwords
+# and other secrets in external (to wpa_supplicant) location. This allows, for
+# example, operating system specific key storage to be used
+#
+# External password backend for testing purposes (developer use)
+#CONFIG_EXT_PASSWORD_TEST=y
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index e53e156..825e2b9 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -13,6 +13,7 @@
#include <assert.h>
#include "common.h"
+#include "utils/ext_password.h"
#include "config.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
@@ -506,6 +507,10 @@ static void test_eapol_clean(struct eapol_test_data *e,
wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
wpa_s->ctrl_iface = NULL;
}
+
+ ext_password_deinit(wpa_s->ext_pw);
+ wpa_s->ext_pw = NULL;
+
wpa_config_free(wpa_s->conf);
p = e->extra_attrs;
@@ -1228,6 +1233,9 @@ int main(int argc, char *argv[])
if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
return -1;
+ if (wpas_init_ext_pw(&wpa_s) < 0)
+ return -1;
+
if (wait_for_monitor)
wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 5025410..9247195 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -21,6 +21,7 @@
#include "rsn_supp/wpa.h"
#include "eloop.h"
#include "config.h"
+#include "utils/ext_password.h"
#include "l2_packet/l2_packet.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
@@ -453,6 +454,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
wpa_s->bssid_filter = NULL;
wnm_bss_keep_alive_deinit(wpa_s);
+
+ ext_password_deinit(wpa_s->ext_pw);
+ wpa_s->ext_pw = NULL;
}
@@ -2500,6 +2504,38 @@ static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
}
+int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
+{
+ char *val, *pos;
+
+ ext_password_deinit(wpa_s->ext_pw);
+ wpa_s->ext_pw = NULL;
+ eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
+
+ if (!wpa_s->conf->ext_password_backend)
+ return 0;
+
+ val = os_strdup(wpa_s->conf->ext_password_backend);
+ if (val == NULL)
+ return -1;
+ pos = os_strchr(val, ':');
+ if (pos)
+ *pos++ = '\0';
+
+ wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
+
+ wpa_s->ext_pw = ext_password_init(val, pos);
+ os_free(val);
+ if (wpa_s->ext_pw == NULL) {
+ wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
+ return -1;
+ }
+ eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
+
+ return 0;
+}
+
+
static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
struct wpa_interface *iface)
{
@@ -2725,6 +2761,9 @@ next_driver:
if (pcsc_reader_init(wpa_s) < 0)
return -1;
+ if (wpas_init_ext_pw(wpa_s) < 0)
+ return -1;
+
return 0;
}
@@ -3153,6 +3192,9 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
}
}
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
+ wpas_init_ext_pw(wpa_s);
+
#ifdef CONFIG_WPS
wpas_wps_update_config(wpa_s);
#endif /* CONFIG_WPS */
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index af0da20..05a2d0b 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -255,6 +255,10 @@ fast_reauth=1
# 1 = only include configured SSIDs in scan results/BSS table
#filter_ssids=0
+# Password (and passphrase, etc.) backend for external storage
+# format: <backend name>[:<optional backend parameters>]
+#ext_password_backend=test:pw1=password|pw2=testing
+
# Interworking (IEEE 802.11u)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b608f29..d6d9410 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1,6 +1,6 @@
/*
* wpa_supplicant - Internal definitions
- * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -574,6 +574,8 @@ struct wpa_supplicant {
/* WLAN_REASON_* reason codes. Negative if locally generated. */
int disconnect_reason;
+
+ struct ext_password_data *ext_pw;
};
@@ -697,4 +699,6 @@ static inline int network_is_persistent_group(struct wpa_ssid *ssid)
int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+int wpas_init_ext_pw(struct wpa_supplicant *wpa_s);
+
#endif /* WPA_SUPPLICANT_I_H */