mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-12-01 11:48:23 -05:00
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
@ -3294,7 +3294,6 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
|
|||||||
struct json_token *cred)
|
struct json_token *cred)
|
||||||
{
|
{
|
||||||
struct json_token *pass, *psk_hex;
|
struct json_token *pass, *psk_hex;
|
||||||
u8 psk[32];
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Legacy akm=psk credential");
|
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");
|
psk_hex = json_get_member(cred, "psk_hex");
|
||||||
|
|
||||||
if (pass && pass->type == JSON_STRING) {
|
if (pass && pass->type == JSON_STRING) {
|
||||||
|
size_t len = os_strlen(pass->string);
|
||||||
|
|
||||||
wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Legacy passphrase",
|
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) {
|
} else if (psk_hex && psk_hex->type == JSON_STRING) {
|
||||||
if (os_strlen(psk_hex->string) != sizeof(psk) * 2 ||
|
if (os_strlen(psk_hex->string) != PMK_LEN * 2 ||
|
||||||
hexstr2bin(psk_hex->string, psk, sizeof(psk)) < 0) {
|
hexstr2bin(psk_hex->string, auth->psk, PMK_LEN) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding");
|
wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK", psk, sizeof(psk));
|
wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK",
|
||||||
os_memset(psk, 0, sizeof(psk));
|
auth->psk, PMK_LEN);
|
||||||
|
auth->psk_set = 1;
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: No pass or psk_hex strings found");
|
wpa_printf(MSG_DEBUG, "DPP: No pass or psk_hex strings found");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -154,6 +154,9 @@ struct dpp_authentication {
|
|||||||
char *connector; /* received signedConnector */
|
char *connector; /* received signedConnector */
|
||||||
u8 ssid[SSID_MAX_LEN];
|
u8 ssid[SSID_MAX_LEN];
|
||||||
u8 ssid_len;
|
u8 ssid_len;
|
||||||
|
char passphrase[64];
|
||||||
|
u8 psk[PMK_LEN];
|
||||||
|
int psk_set;
|
||||||
struct wpabuf *net_access_key;
|
struct wpabuf *net_access_key;
|
||||||
os_time_t net_access_key_expiry;
|
os_time_t net_access_key_expiry;
|
||||||
struct wpabuf *c_sign_key;
|
struct wpabuf *c_sign_key;
|
||||||
|
@ -156,6 +156,7 @@ extern "C" {
|
|||||||
#define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY "
|
#define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY "
|
||||||
#define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY "
|
#define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY "
|
||||||
#define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR "
|
#define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR "
|
||||||
|
#define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID "
|
||||||
|
|
||||||
/* MESH events */
|
/* MESH events */
|
||||||
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
|
#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_RANGE(ftm_initiator, 0, 1), 0 },
|
||||||
{ INT(gas_rand_addr_lifetime), 0 },
|
{ INT(gas_rand_addr_lifetime), 0 },
|
||||||
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
|
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
|
||||||
|
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef FUNC
|
#undef FUNC
|
||||||
|
@ -1366,6 +1366,21 @@ struct wpa_config {
|
|||||||
* 2 = like 1, but maintain OUI (with local admin bit set)
|
* 2 = like 1, but maintain OUI (with local admin bit set)
|
||||||
*/
|
*/
|
||||||
int gas_rand_mac_addr;
|
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);
|
config->gas_rand_addr_lifetime);
|
||||||
if (config->gas_rand_mac_addr)
|
if (config->gas_rand_mac_addr)
|
||||||
fprintf(f, "gas_rand_mac_addr=%d\n", 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 "gas_query.h"
|
||||||
#include "bss.h"
|
#include "bss.h"
|
||||||
#include "scan.h"
|
#include "scan.h"
|
||||||
|
#include "notify.h"
|
||||||
#include "dpp_supplicant.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,
|
static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
|
||||||
enum gas_query_result result,
|
enum gas_query_result result,
|
||||||
const struct wpabuf *adv_proto,
|
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);
|
os_free(hex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpas_dpp_process_config(wpa_s, auth);
|
||||||
|
|
||||||
dpp_auth_deinit(wpa_s->dpp_auth);
|
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||||
wpa_s->dpp_auth = NULL;
|
wpa_s->dpp_auth = NULL;
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user