aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-08-03 18:47:31 (GMT)
committerJouni Malinen <j@w1.fi>2012-08-03 19:15:42 (GMT)
commit0ebb23e340e625d59923039d0a4eb6379bdad992 (patch)
tree9329f2925c8a522db44433a4427e2514ca9c2839 /src
parent9173b16fd194269878a6a29f4452be22d6cb53c2 (diff)
downloadhostap-0ebb23e340e625d59923039d0a4eb6379bdad992.zip
hostap-0ebb23e340e625d59923039d0a4eb6379bdad992.tar.gz
hostap-0ebb23e340e625d59923039d0a4eb6379bdad992.tar.bz2
EXT PW: Add support for password parameter from external storage
This allows the password parameter for EAP methods to be fetched from an external storage. Following example can be used for developer testing: ext_password_backend=test:pw1=password|pw2=testing network={ key_mgmt=WPA-EAP eap=TTLS identity="user" password=ext:pw1 ca_cert="ca.pem" phase2="auth=PAP" } Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src')
-rw-r--r--src/eap_peer/eap.c49
-rw-r--r--src/eap_peer/eap.h3
-rw-r--r--src/eap_peer/eap_config.h3
-rw-r--r--src/eap_peer/eap_i.h3
-rw-r--r--src/eap_peer/eap_mschapv2.c4
-rw-r--r--src/eapol_supp/eapol_supp_sm.c10
-rw-r--r--src/eapol_supp/eapol_supp_sm.h9
7 files changed, 78 insertions, 3 deletions
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 8b43be4..b672494 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -20,6 +20,7 @@
#include "common.h"
#include "pcsc_funcs.h"
#include "state_machine.h"
+#include "ext_password.h"
#include "crypto/crypto.h"
#include "crypto/tls.h"
#include "common/wpa_ctrl.h"
@@ -93,6 +94,9 @@ static void eap_notify_status(struct eap_sm *sm, const char *status,
static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
{
+ ext_password_free(sm->ext_pw_buf);
+ sm->ext_pw_buf = NULL;
+
if (sm->m == NULL || sm->eap_method_priv == NULL)
return;
@@ -1915,6 +1919,27 @@ const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
}
+static int eap_get_ext_password(struct eap_sm *sm,
+ struct eap_peer_config *config)
+{
+ char *name;
+
+ if (config->password == NULL)
+ return -1;
+
+ name = os_zalloc(config->password_len + 1);
+ if (name == NULL)
+ return -1;
+ os_memcpy(name, config->password, config->password_len);
+
+ ext_password_free(sm->ext_pw_buf);
+ sm->ext_pw_buf = ext_password_get(sm->ext_pw, name);
+ os_free(name);
+
+ return sm->ext_pw_buf == NULL ? -1 : 0;
+}
+
+
/**
* eap_get_config_password - Get password from the network configuration
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
@@ -1926,6 +1951,14 @@ const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
struct eap_peer_config *config = eap_get_config(sm);
if (config == NULL)
return NULL;
+
+ if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
+ if (eap_get_ext_password(sm, config) < 0)
+ return NULL;
+ *len = wpabuf_len(sm->ext_pw_buf);
+ return wpabuf_head(sm->ext_pw_buf);
+ }
+
*len = config->password_len;
return config->password;
}
@@ -1945,6 +1978,14 @@ const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
struct eap_peer_config *config = eap_get_config(sm);
if (config == NULL)
return NULL;
+
+ if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
+ if (eap_get_ext_password(sm, config) < 0)
+ return NULL;
+ *len = wpabuf_len(sm->ext_pw_buf);
+ return wpabuf_head(sm->ext_pw_buf);
+ }
+
*len = config->password_len;
if (hash)
*hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH);
@@ -2256,3 +2297,11 @@ int eap_is_wps_pin_enrollee(struct eap_peer_config *conf)
return 1;
}
+
+
+void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext)
+{
+ ext_password_free(sm->ext_pw_buf);
+ sm->ext_pw_buf = NULL;
+ sm->ext_pw = ext;
+}
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index 6e87475..cf58608 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -306,6 +306,9 @@ void eap_invalidate_cached_session(struct eap_sm *sm);
int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf);
int eap_is_wps_pin_enrollee(struct eap_peer_config *conf);
+struct ext_password_data;
+void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext);
+
#endif /* IEEE8021X_EAPOL */
#endif /* EAP_H */
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index a6f6f4c..a08543e 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -619,6 +619,7 @@ struct eap_peer_config {
int fragment_size;
#define EAP_CONFIG_FLAGS_PASSWORD_NTHASH BIT(0)
+#define EAP_CONFIG_FLAGS_EXT_PASSWORD BIT(1)
/**
* flags - Network configuration flags (bitfield)
*
@@ -626,6 +627,8 @@ struct eap_peer_config {
* for the network parameters.
* bit 0 = password is represented as a 16-byte NtPasswordHash value
* instead of plaintext password
+ * bit 1 = password is stored in external storage; the value in the
+ * password field is the name of that external entry
*/
u32 flags;
};
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 3318b81..dd94317 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -330,6 +330,9 @@ struct eap_sm {
struct wps_context *wps;
int prev_failure;
+
+ struct ext_password_data *ext_pw;
+ struct wpabuf *ext_pw_buf;
};
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index 3b0a116..fb6c282 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -304,7 +304,9 @@ static void eap_mschapv2_password_changed(struct eap_sm *sm,
"EAP-MSCHAPV2: Password changed successfully");
data->prev_error = 0;
os_free(config->password);
- if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) {
+ if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
+ /* TODO: update external storage */
+ } else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) {
config->password = os_malloc(16);
config->password_len = 16;
if (config->password) {
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index f0cae70..2a8ef1a 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -1,6 +1,6 @@
/*
* EAPOL supplicant state machines
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -1946,3 +1946,11 @@ void eapol_sm_deinit(struct eapol_sm *sm)
os_free(sm->ctx);
os_free(sm);
}
+
+
+void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
+ struct ext_password_data *ext)
+{
+ if (sm && sm->eap)
+ eap_sm_set_ext_pw_ctx(sm->eap, ext);
+}
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index 1a20e4b..b69dd97 100644
--- a/src/eapol_supp/eapol_supp_sm.h
+++ b/src/eapol_supp/eapol_supp_sm.h
@@ -1,6 +1,6 @@
/*
* EAPOL supplicant state machines
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -243,6 +243,7 @@ struct eapol_ctx {
struct eap_peer_config;
+struct ext_password_data;
#ifdef IEEE8021X_EAPOL
struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx);
@@ -275,6 +276,8 @@ void eapol_sm_request_reauth(struct eapol_sm *sm);
void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm);
void eapol_sm_invalidate_cached_session(struct eapol_sm *sm);
const char * eapol_sm_get_method_name(struct eapol_sm *sm);
+void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
+ struct ext_password_data *ext);
#else /* IEEE8021X_EAPOL */
static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
{
@@ -366,6 +369,10 @@ static inline const char * eapol_sm_get_method_name(struct eapol_sm *sm)
{
return NULL;
}
+static inline void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
+ struct ext_password_data *ext)
+{
+}
#endif /* IEEE8021X_EAPOL */
#endif /* EAPOL_SUPP_SM_H */