DPP: Automatic network profile creation
wpa_supplicant can now be configured to generate a network profile automatically based on DPP configuration. The following dpp_config_processing values can be used to specify the behavior: 0 = report received configuration to an external program for processing; do not generate any network profile internally (default) 1 = report received configuration to an external program and generate a network profile internally, but do not automatically connect to the created (disabled) profile; the network profile id is reported to external programs 2 = report received configuration to an external program, generate a network profile internally, try to connect to the created profile automatically Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
da143f7fb9
commit
8528994e21
7 changed files with 135 additions and 6 deletions
|
@ -3294,7 +3294,6 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
|
|||
struct json_token *cred)
|
||||
{
|
||||
struct json_token *pass, *psk_hex;
|
||||
u8 psk[32];
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Legacy akm=psk credential");
|
||||
|
||||
|
@ -3302,16 +3301,23 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
|
|||
psk_hex = json_get_member(cred, "psk_hex");
|
||||
|
||||
if (pass && pass->type == JSON_STRING) {
|
||||
size_t len = os_strlen(pass->string);
|
||||
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Legacy passphrase",
|
||||
pass->string, os_strlen(pass->string));
|
||||
pass->string, len);
|
||||
if (len < 8 || len > 63)
|
||||
return -1;
|
||||
os_strlcpy(auth->passphrase, pass->string,
|
||||
sizeof(auth->passphrase));
|
||||
} else if (psk_hex && psk_hex->type == JSON_STRING) {
|
||||
if (os_strlen(psk_hex->string) != sizeof(psk) * 2 ||
|
||||
hexstr2bin(psk_hex->string, psk, sizeof(psk)) < 0) {
|
||||
if (os_strlen(psk_hex->string) != PMK_LEN * 2 ||
|
||||
hexstr2bin(psk_hex->string, auth->psk, PMK_LEN) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding");
|
||||
return -1;
|
||||
}
|
||||
wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK", psk, sizeof(psk));
|
||||
os_memset(psk, 0, sizeof(psk));
|
||||
wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK",
|
||||
auth->psk, PMK_LEN);
|
||||
auth->psk_set = 1;
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "DPP: No pass or psk_hex strings found");
|
||||
return -1;
|
||||
|
|
|
@ -154,6 +154,9 @@ struct dpp_authentication {
|
|||
char *connector; /* received signedConnector */
|
||||
u8 ssid[SSID_MAX_LEN];
|
||||
u8 ssid_len;
|
||||
char passphrase[64];
|
||||
u8 psk[PMK_LEN];
|
||||
int psk_set;
|
||||
struct wpabuf *net_access_key;
|
||||
os_time_t net_access_key_expiry;
|
||||
struct wpabuf *c_sign_key;
|
||||
|
|
|
@ -156,6 +156,7 @@ extern "C" {
|
|||
#define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY "
|
||||
#define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY "
|
||||
#define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR "
|
||||
#define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID "
|
||||
|
||||
/* MESH events */
|
||||
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
|
||||
|
|
|
@ -4577,6 +4577,7 @@ static const struct global_parse_data global_fields[] = {
|
|||
{ INT_RANGE(ftm_initiator, 0, 1), 0 },
|
||||
{ INT(gas_rand_addr_lifetime), 0 },
|
||||
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
|
||||
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
|
||||
};
|
||||
|
||||
#undef FUNC
|
||||
|
|
|
@ -1366,6 +1366,21 @@ struct wpa_config {
|
|||
* 2 = like 1, but maintain OUI (with local admin bit set)
|
||||
*/
|
||||
int gas_rand_mac_addr;
|
||||
|
||||
/**
|
||||
* dpp_config_processing - How to process DPP configuration
|
||||
*
|
||||
* 0 = report received configuration to an external program for
|
||||
* processing; do not generate any network profile internally
|
||||
* 1 = report received configuration to an external program and generate
|
||||
* a network profile internally, but do not automatically connect
|
||||
* to the created (disabled) profile; the network profile id is
|
||||
* reported to external programs
|
||||
* 2 = report received configuration to an external program, generate
|
||||
* a network profile internally, try to connect to the created
|
||||
* profile automatically
|
||||
*/
|
||||
int dpp_config_processing;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1455,6 +1455,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
|||
config->gas_rand_addr_lifetime);
|
||||
if (config->gas_rand_mac_addr)
|
||||
fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr);
|
||||
if (config->dpp_config_processing)
|
||||
fprintf(f, "dpp_config_processing=%d\n",
|
||||
config->dpp_config_processing);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "gas_query.h"
|
||||
#include "bss.h"
|
||||
#include "scan.h"
|
||||
#include "notify.h"
|
||||
#include "dpp_supplicant.h"
|
||||
|
||||
|
||||
|
@ -819,6 +820,102 @@ static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s)
|
|||
}
|
||||
|
||||
|
||||
static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
|
||||
struct dpp_authentication *auth)
|
||||
{
|
||||
struct wpa_ssid *ssid;
|
||||
|
||||
ssid = wpa_config_add_network(wpa_s->conf);
|
||||
if (!ssid)
|
||||
return NULL;
|
||||
wpas_notify_network_added(wpa_s, ssid);
|
||||
wpa_config_set_network_defaults(ssid);
|
||||
ssid->disabled = 1;
|
||||
|
||||
ssid->ssid = os_malloc(auth->ssid_len);
|
||||
if (!ssid->ssid)
|
||||
goto fail;
|
||||
os_memcpy(ssid->ssid, auth->ssid, auth->ssid_len);
|
||||
ssid->ssid_len = auth->ssid_len;
|
||||
|
||||
if (auth->connector) {
|
||||
ssid->key_mgmt = WPA_KEY_MGMT_DPP;
|
||||
ssid->dpp_connector = os_strdup(auth->connector);
|
||||
if (!ssid->dpp_connector)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (auth->c_sign_key) {
|
||||
ssid->dpp_csign = os_malloc(wpabuf_len(auth->c_sign_key));
|
||||
if (!ssid->dpp_csign)
|
||||
goto fail;
|
||||
os_memcpy(ssid->dpp_csign, wpabuf_head(auth->c_sign_key),
|
||||
wpabuf_len(auth->c_sign_key));
|
||||
ssid->dpp_csign_len = wpabuf_len(auth->c_sign_key);
|
||||
ssid->dpp_csign_expiry = auth->c_sign_key_expiry;
|
||||
}
|
||||
|
||||
if (auth->net_access_key) {
|
||||
ssid->dpp_netaccesskey =
|
||||
os_malloc(wpabuf_len(auth->net_access_key));
|
||||
if (!ssid->dpp_netaccesskey)
|
||||
goto fail;
|
||||
os_memcpy(ssid->dpp_netaccesskey,
|
||||
wpabuf_head(auth->net_access_key),
|
||||
wpabuf_len(auth->net_access_key));
|
||||
ssid->dpp_netaccesskey_len = wpabuf_len(auth->net_access_key);
|
||||
ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
|
||||
}
|
||||
|
||||
if (!auth->connector) {
|
||||
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
|
||||
if (auth->passphrase[0]) {
|
||||
if (wpa_config_set_quoted(ssid, "psk",
|
||||
auth->passphrase) < 0)
|
||||
goto fail;
|
||||
wpa_config_update_psk(ssid);
|
||||
ssid->export_keys = 1;
|
||||
} else {
|
||||
ssid->psk_set = auth->psk_set;
|
||||
os_memcpy(ssid->psk, auth->psk, PMK_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
return ssid;
|
||||
fail:
|
||||
wpas_notify_network_removed(wpa_s, ssid);
|
||||
wpa_config_remove_network(wpa_s->conf, ssid->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
|
||||
struct dpp_authentication *auth)
|
||||
{
|
||||
struct wpa_ssid *ssid;
|
||||
|
||||
if (wpa_s->conf->dpp_config_processing < 1)
|
||||
return;
|
||||
|
||||
ssid = wpas_dpp_add_network(wpa_s, auth);
|
||||
if (!ssid)
|
||||
return;
|
||||
|
||||
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
|
||||
if (wpa_s->conf->dpp_config_processing < 2)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
|
||||
ssid->disabled = 0;
|
||||
wpa_s->disconnected = 0;
|
||||
wpa_s->reassociate = 1;
|
||||
wpa_s->scan_runs = 0;
|
||||
wpa_s->normal_scans = 0;
|
||||
wpa_supplicant_cancel_sched_scan(wpa_s);
|
||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
|
||||
enum gas_query_result result,
|
||||
const struct wpabuf *adv_proto,
|
||||
|
@ -916,6 +1013,9 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
|
|||
os_free(hex);
|
||||
}
|
||||
}
|
||||
|
||||
wpas_dpp_process_config(wpa_s, auth);
|
||||
|
||||
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||
wpa_s->dpp_auth = NULL;
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue