aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-01-18 10:27:12 (GMT)
committerJouni Malinen <j@w1.fi>2009-02-08 09:54:03 (GMT)
commit440180c88e1d006c729f42fccfcc924198808a3e (patch)
tree761460aef867aeefbeb4aa773c63b3e9e85141df /wpa_supplicant
parent6d2139a7155a6e62157ae4c30b238db4dc87a18d (diff)
downloadhostap-06-440180c88e1d006c729f42fccfcc924198808a3e.zip
hostap-06-440180c88e1d006c729f42fccfcc924198808a3e.tar.gz
hostap-06-440180c88e1d006c729f42fccfcc924198808a3e.tar.bz2
WPS: Add configurable option for processing credentials externally
The wps_cred_process option can be used to configure wpa_supplicant to send received Credential attributes for external processing over ctrl_iface and dbus. This allows external programs to update their configuration when WPS is used to provision new networks. (cherry picked from commit 476621644cd3eb94f329bda755f3c639239d321c)
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/config.h11
-rw-r--r--wpa_supplicant/config_file.c4
-rw-r--r--wpa_supplicant/config_winreg.c4
-rw-r--r--wpa_supplicant/ctrl_iface_dbus.c58
-rw-r--r--wpa_supplicant/ctrl_iface_dbus.h10
-rw-r--r--wpa_supplicant/wpa_supplicant.conf7
-rw-r--r--wpa_supplicant/wps_supplicant.c28
7 files changed, 121 insertions, 1 deletions
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 0cea4dc..4484e91 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -312,6 +312,17 @@ struct wpa_config {
* in
*/
char country[2];
+
+ /**
+ * wps_cred_processing - Credential processing
+ *
+ * 0 = process received credentials internally
+ * 1 = do not process received credentials; just pass them over
+ * ctrl_iface to external program(s)
+ * 2 = process received credentials internally and pass them over
+ * ctrl_iface to external program(s)
+ */
+ int wps_cred_processing;
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index f544a56..29e494c 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -456,6 +456,7 @@ static const struct global_parse_data global_fields[] = {
{ STR_RANGE(serial_number, 0, 32) },
{ STR(device_type) },
{ FUNC(os_version) },
+ { INT_RANGE(wps_cred_processing, 0, 2) },
#endif /* CONFIG_WPS */
{ FUNC(country) }
};
@@ -881,6 +882,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (WPA_GET_BE32(config->os_version))
fprintf(f, "os_version=%08x\n",
WPA_GET_BE32(config->os_version));
+ if (config->wps_cred_processing)
+ fprintf(f, "wps_cred_processing=%d\n",
+ config->wps_cred_processing);
#endif /* CONFIG_WPS */
if (config->country[0] && config->country[1]) {
fprintf(f, "country=%c%c\n",
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 0199642..456d417 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -251,6 +251,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
hk, TEXT("device_type"));
if (wpa_config_read_global_os_version(config, hk))
errors++;
+ wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
+ &config->wps_cred_processing);
#endif /* CONFIG_WPS */
return errors ? -1 : 0;
@@ -573,6 +575,8 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
WPA_GET_BE32(config->os_version));
wpa_config_write_reg_string(hk, "os_version", vbuf);
}
+ wpa_config_write_reg_dword(hk, TEXT("wps_cred_processing"),
+ config->wps_cred_processing, 0);
#endif /* CONFIG_WPS */
return 0;
diff --git a/wpa_supplicant/ctrl_iface_dbus.c b/wpa_supplicant/ctrl_iface_dbus.c
index 7f2fba4..b772247 100644
--- a/wpa_supplicant/ctrl_iface_dbus.c
+++ b/wpa_supplicant/ctrl_iface_dbus.c
@@ -18,6 +18,7 @@
#include "eloop.h"
#include "config.h"
#include "wpa_supplicant_i.h"
+#include "wps/wps.h"
#include "ctrl_iface_dbus.h"
#include "ctrl_iface_dbus_handlers.h"
@@ -738,6 +739,63 @@ out:
}
+#ifdef CONFIG_WPS
+void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
+ const struct wps_credential *cred)
+{
+ struct ctrl_iface_dbus_priv *iface;
+ DBusMessage *_signal = NULL;
+ const char *path;
+
+ /* Do nothing if the control interface is not turned on */
+ if (wpa_s->global == NULL)
+ return;
+ iface = wpa_s->global->dbus_ctrl_iface;
+ if (iface == NULL)
+ return;
+
+ path = wpa_supplicant_get_dbus_path(wpa_s);
+ if (path == NULL) {
+ perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "interface didn't have a dbus path");
+ wpa_printf(MSG_ERROR,
+ "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "interface didn't have a dbus path; can't send "
+ "signal.");
+ return;
+ }
+ _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+ "WpsCred");
+ if (_signal == NULL) {
+ perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "couldn't create dbus signal; likely out of memory");
+ wpa_printf(MSG_ERROR,
+ "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "couldn't create dbus signal; likely out of "
+ "memory.");
+ return;
+ }
+
+ if (!dbus_message_append_args(_signal,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &cred->cred_attr, cred->cred_attr_len,
+ DBUS_TYPE_INVALID)) {
+ perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "not enough memory to construct signal.");
+ wpa_printf(MSG_ERROR,
+ "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
+ "not enough memory to construct signal.");
+ goto out;
+ }
+
+ dbus_connection_send(iface->con, _signal, NULL);
+
+out:
+ dbus_message_unref(_signal);
+}
+#endif /* CONFIG_WPS */
+
+
/**
* integrate_with_eloop - Register our mainloop integration with dbus
* @connection: connection to the system message bus
diff --git a/wpa_supplicant/ctrl_iface_dbus.h b/wpa_supplicant/ctrl_iface_dbus.h
index b66c179..68919de 100644
--- a/wpa_supplicant/ctrl_iface_dbus.h
+++ b/wpa_supplicant/ctrl_iface_dbus.h
@@ -15,6 +15,8 @@
#ifndef CTRL_IFACE_DBUS_H
#define CTRL_IFACE_DBUS_H
+struct wps_credential;
+
#ifdef CONFIG_CTRL_IFACE_DBUS
#ifndef SIGPOLL
@@ -84,6 +86,8 @@ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s);
void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
wpa_states new_state,
wpa_states old_state);
+void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
+ const struct wps_credential *cred);
char * wpas_dbus_decompose_object_path(const char *path, char **network,
char **bssid);
@@ -129,6 +133,12 @@ wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
{
}
+static inline void
+wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
+ const struct wps_credential *cred)
+{
+}
+
static inline int
wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index cfcea88..4b1f90b 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -190,6 +190,13 @@ fast_reauth=1
# 4-octet operating system version number (hex string)
#os_version=01020300
+# Credential processing
+# 0 = process received credentials internally (default)
+# 1 = do not process received credentials; just pass them over ctrl_iface to
+# external program(s)
+# 2 = process received credentials internally and pass them over ctrl_iface
+# to external program(s)
+#wps_cred_processing=0
# network block
#
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index fb1d833..14f1f86 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -23,6 +23,7 @@
#include "eloop.h"
#include "uuid.h"
#include "wpa_ctrl.h"
+#include "ctrl_iface_dbus.h"
#include "eap_common/eap_wsc_common.h"
#include "wps_supplicant.h"
@@ -46,6 +47,15 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
return 1;
}
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
+ wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
+ "for external credential processing");
+ wpas_clear_wps(wpa_s);
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_DEAUTH_LEAVING);
+ return 1;
+ }
+
return 0;
}
@@ -56,11 +66,27 @@ static int wpa_supplicant_wps_cred(void *ctx,
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *ssid = wpa_s->current_ssid;
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
+ if ((wpa_s->conf->wps_cred_processing == 1 ||
+ wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
+ size_t blen = cred->cred_attr_len * 2 + 1;
+ char *buf = os_malloc(blen);
+ if (buf) {
+ wpa_snprintf_hex(buf, blen,
+ cred->cred_attr, cred->cred_attr_len);
+ wpa_msg(wpa_s, MSG_INFO, "%s%s",
+ WPS_EVENT_CRED_RECEIVED, buf);
+ os_free(buf);
+ }
+ wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred);
+ } else
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
cred->cred_attr, cred->cred_attr_len);
+ if (wpa_s->conf->wps_cred_processing == 1)
+ return 0;
+
if (cred->auth_type != WPS_AUTH_OPEN &&
cred->auth_type != WPS_AUTH_SHARED &&
cred->auth_type != WPS_AUTH_WPAPSK &&