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.
This commit is contained in:
parent
eca6e0a9a5
commit
476621644c
7 changed files with 121 additions and 1 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in a new issue