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
|
* in
|
||||||
*/
|
*/
|
||||||
char country[2];
|
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_RANGE(serial_number, 0, 32) },
|
||||||
{ STR(device_type) },
|
{ STR(device_type) },
|
||||||
{ FUNC(os_version) },
|
{ FUNC(os_version) },
|
||||||
|
{ INT_RANGE(wps_cred_processing, 0, 2) },
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
{ FUNC(country) }
|
{ 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))
|
if (WPA_GET_BE32(config->os_version))
|
||||||
fprintf(f, "os_version=%08x\n",
|
fprintf(f, "os_version=%08x\n",
|
||||||
WPA_GET_BE32(config->os_version));
|
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 */
|
#endif /* CONFIG_WPS */
|
||||||
if (config->country[0] && config->country[1]) {
|
if (config->country[0] && config->country[1]) {
|
||||||
fprintf(f, "country=%c%c\n",
|
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"));
|
hk, TEXT("device_type"));
|
||||||
if (wpa_config_read_global_os_version(config, hk))
|
if (wpa_config_read_global_os_version(config, hk))
|
||||||
errors++;
|
errors++;
|
||||||
|
wpa_config_read_reg_dword(hk, TEXT("wps_cred_processing"),
|
||||||
|
&config->wps_cred_processing);
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
return errors ? -1 : 0;
|
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_GET_BE32(config->os_version));
|
||||||
wpa_config_write_reg_string(hk, "os_version", vbuf);
|
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 */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "eloop.h"
|
#include "eloop.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
|
#include "wps/wps.h"
|
||||||
#include "ctrl_iface_dbus.h"
|
#include "ctrl_iface_dbus.h"
|
||||||
#include "ctrl_iface_dbus_handlers.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
|
* integrate_with_eloop - Register our mainloop integration with dbus
|
||||||
* @connection: connection to the system message bus
|
* @connection: connection to the system message bus
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef CTRL_IFACE_DBUS_H
|
#ifndef CTRL_IFACE_DBUS_H
|
||||||
#define CTRL_IFACE_DBUS_H
|
#define CTRL_IFACE_DBUS_H
|
||||||
|
|
||||||
|
struct wps_credential;
|
||||||
|
|
||||||
#ifdef CONFIG_CTRL_IFACE_DBUS
|
#ifdef CONFIG_CTRL_IFACE_DBUS
|
||||||
|
|
||||||
#ifndef SIGPOLL
|
#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,
|
void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
|
||||||
wpa_states new_state,
|
wpa_states new_state,
|
||||||
wpa_states old_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 * wpas_dbus_decompose_object_path(const char *path, char **network,
|
||||||
char **bssid);
|
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
|
static inline int
|
||||||
wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
|
wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,6 +190,13 @@ fast_reauth=1
|
||||||
# 4-octet operating system version number (hex string)
|
# 4-octet operating system version number (hex string)
|
||||||
#os_version=01020300
|
#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
|
# network block
|
||||||
#
|
#
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "eloop.h"
|
#include "eloop.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "wpa_ctrl.h"
|
#include "wpa_ctrl.h"
|
||||||
|
#include "ctrl_iface_dbus.h"
|
||||||
#include "eap_common/eap_wsc_common.h"
|
#include "eap_common/eap_wsc_common.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
|
|
||||||
|
@ -46,6 +47,15 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,11 +66,27 @@ static int wpa_supplicant_wps_cred(void *ctx,
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
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",
|
wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
|
||||||
cred->cred_attr, cred->cred_attr_len);
|
cred->cred_attr, cred->cred_attr_len);
|
||||||
|
|
||||||
|
if (wpa_s->conf->wps_cred_processing == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (cred->auth_type != WPS_AUTH_OPEN &&
|
if (cred->auth_type != WPS_AUTH_OPEN &&
|
||||||
cred->auth_type != WPS_AUTH_SHARED &&
|
cred->auth_type != WPS_AUTH_SHARED &&
|
||||||
cred->auth_type != WPS_AUTH_WPAPSK &&
|
cred->auth_type != WPS_AUTH_WPAPSK &&
|
||||||
|
|
Loading…
Reference in a new issue