DPP2: Connection status result (Configurator)

A new argument to the DPP_AUTH_INIT command (conn_status=1) can now be
used to set Configurator to request a station Enrollee to report
connection result after a successfully completed provisioning step. If
the peer supports this, the DPP-CONF-SENT event indicates this with a
new argument (wait_conn_status=1) and the Configurator remains waiting
for the connection result for up to 16 seconds.

Once the Enrollee reports the result, a new DPP-CONN-STATUS-RESULT event
is generated with arguments result, ssid, and channel_list indicating
what the Enrollee reported. result=0 means success while non-zero codes
are for various error cases as specified in the DPP tech spec. If no
report is received from the Enrollee, the event with "timeout" argument
is generated locally.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-09-15 16:19:45 +03:00 committed by Jouni Malinen
parent e501a2eb59
commit b10e01a795
5 changed files with 369 additions and 1 deletions

View file

@ -922,6 +922,24 @@ static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
} }
static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
void *timeout_ctx)
{
struct hostapd_data *hapd = eloop_ctx;
struct dpp_authentication *auth = hapd->dpp_auth;
if (!auth || !auth->waiting_conf_result)
return;
wpa_printf(MSG_DEBUG,
"DPP: Timeout while waiting for Connection Status Result");
wpa_msg(hapd->msg_ctx, MSG_INFO,
DPP_EVENT_CONN_STATUS_RESULT "timeout");
dpp_auth_deinit(auth);
hapd->dpp_auth = NULL;
}
static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src, static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
const u8 *hdr, const u8 *buf, size_t len) const u8 *hdr, const u8 *buf, size_t len)
{ {
@ -945,6 +963,20 @@ static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
status = dpp_conf_result_rx(auth, hdr, buf, len); status = dpp_conf_result_rx(auth, hdr, buf, len);
if (status == DPP_STATUS_OK && auth->send_conn_status) {
wpa_msg(hapd->msg_ctx, MSG_INFO,
DPP_EVENT_CONF_SENT "wait_conn_status=1");
wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
hapd, NULL);
eloop_cancel_timeout(
hostapd_dpp_conn_status_result_wait_timeout,
hapd, NULL);
eloop_register_timeout(
16, 0, hostapd_dpp_conn_status_result_wait_timeout,
hapd, NULL);
return;
}
hostapd_drv_send_action_cancel_wait(hapd); hostapd_drv_send_action_cancel_wait(hapd);
hostapd_dpp_listen_stop(hapd); hostapd_dpp_listen_stop(hapd);
if (status == DPP_STATUS_OK) if (status == DPP_STATUS_OK)
@ -957,6 +989,41 @@ static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
NULL); NULL);
} }
static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
const u8 *src, const u8 *hdr,
const u8 *buf, size_t len)
{
struct dpp_authentication *auth = hapd->dpp_auth;
enum dpp_status_error status;
u8 ssid[SSID_MAX_LEN];
size_t ssid_len = 0;
char *channel_list = NULL;
wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
if (!auth || !auth->waiting_conn_status_result) {
wpa_printf(MSG_DEBUG,
"DPP: No DPP Configuration waiting for connection status result - drop");
return;
}
status = dpp_conn_status_result_rx(auth, hdr, buf, len,
ssid, &ssid_len, &channel_list);
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
"result=%d ssid=%s channel_list=%s",
status, wpa_ssid_txt(ssid, ssid_len),
channel_list ? channel_list : "N/A");
os_free(channel_list);
hostapd_drv_send_action_cancel_wait(hapd);
hostapd_dpp_listen_stop(hapd);
dpp_auth_deinit(auth);
hapd->dpp_auth = NULL;
eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
hapd, NULL);
}
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
@ -1403,6 +1470,9 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
case DPP_PA_CONFIGURATION_RESULT: case DPP_PA_CONFIGURATION_RESULT:
hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len); hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
break; break;
case DPP_PA_CONNECTION_STATUS_RESULT:
hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
break;
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
default: default:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
@ -1715,6 +1785,8 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
#ifdef CONFIG_DPP2 #ifdef CONFIG_DPP2
eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd, eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
NULL); NULL);
eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
NULL);
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
dpp_auth_deinit(hapd->dpp_auth); dpp_auth_deinit(hapd->dpp_auth);
hapd->dpp_auth = NULL; hapd->dpp_auth = NULL;

View file

@ -4446,6 +4446,12 @@ int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
} }
} }
pos = os_strstr(cmd, " conn_status=");
if (pos) {
pos += 13;
auth->send_conn_status = atoi(pos);
}
if (dpp_configuration_parse(auth, cmd) < 0) { if (dpp_configuration_parse(auth, cmd) < 0) {
wpa_msg(msg_ctx, MSG_INFO, wpa_msg(msg_ctx, MSG_INFO,
"DPP: Failed to set configurator parameters"); "DPP: Failed to set configurator parameters");
@ -4861,10 +4867,12 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE; status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE;
auth->conf_resp_status = status; auth->conf_resp_status = status;
/* { E-nonce, configurationObject}ke */ /* { E-nonce, configurationObject[, sendConnStatus]}ke */
clear_len = 4 + e_nonce_len; clear_len = 4 + e_nonce_len;
if (conf) if (conf)
clear_len += 4 + wpabuf_len(conf); clear_len += 4 + wpabuf_len(conf);
if (auth->peer_version >= 2 && auth->send_conn_status && !ap)
clear_len += 4;
clear = wpabuf_alloc(clear_len); clear = wpabuf_alloc(clear_len);
attr_len = 4 + 1 + 4 + clear_len + AES_BLOCK_SIZE; attr_len = 4 + 1 + 4 + clear_len + AES_BLOCK_SIZE;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
@ -4913,6 +4921,12 @@ skip_e_nonce:
wpabuf_put_buf(clear, conf); wpabuf_put_buf(clear, conf);
} }
if (auth->peer_version >= 2 && auth->send_conn_status && !ap) {
wpa_printf(MSG_DEBUG, "DPP: sendConnStatus");
wpabuf_put_le16(clear, DPP_ATTR_SEND_CONN_STATUS);
wpabuf_put_le16(clear, 0);
}
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
skip_config_obj: skip_config_obj:
if (dpp_test == DPP_TEST_NO_STATUS_CONF_RESP) { if (dpp_test == DPP_TEST_NO_STATUS_CONF_RESP) {
@ -6148,6 +6162,135 @@ fail:
return NULL; return NULL;
} }
static int valid_channel_list(const char *val)
{
while (*val) {
if (!((*val >= '0' && *val <= '9') ||
*val == '/' || *val == ','))
return 0;
val++;
}
return 1;
}
enum dpp_status_error dpp_conn_status_result_rx(struct dpp_authentication *auth,
const u8 *hdr,
const u8 *attr_start,
size_t attr_len,
u8 *ssid, size_t *ssid_len,
char **channel_list)
{
const u8 *wrapped_data, *status, *e_nonce;
u16 wrapped_data_len, status_len, e_nonce_len;
const u8 *addr[2];
size_t len[2];
u8 *unwrapped = NULL;
size_t unwrapped_len = 0;
enum dpp_status_error ret = 256;
struct json_token *root = NULL, *token;
*ssid_len = 0;
*channel_list = NULL;
wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA,
&wrapped_data_len);
if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) {
dpp_auth_fail(auth,
"Missing or invalid required Wrapped Data attribute");
goto fail;
}
wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data",
wrapped_data, wrapped_data_len);
attr_len = wrapped_data - 4 - attr_start;
addr[0] = hdr;
len[0] = DPP_HDR_LEN;
addr[1] = attr_start;
len[1] = attr_len;
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
wrapped_data, wrapped_data_len);
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
unwrapped = os_malloc(unwrapped_len);
if (!unwrapped)
goto fail;
if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
wrapped_data, wrapped_data_len,
2, addr, len, unwrapped) < 0) {
dpp_auth_fail(auth, "AES-SIV decryption failed");
goto fail;
}
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext",
unwrapped, unwrapped_len);
if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) {
dpp_auth_fail(auth, "Invalid attribute in unwrapped data");
goto fail;
}
e_nonce = dpp_get_attr(unwrapped, unwrapped_len,
DPP_ATTR_ENROLLEE_NONCE,
&e_nonce_len);
if (!e_nonce || e_nonce_len != auth->curve->nonce_len) {
dpp_auth_fail(auth,
"Missing or invalid Enrollee Nonce attribute");
goto fail;
}
wpa_hexdump(MSG_DEBUG, "DPP: Enrollee Nonce", e_nonce, e_nonce_len);
if (os_memcmp(e_nonce, auth->e_nonce, e_nonce_len) != 0) {
dpp_auth_fail(auth, "Enrollee Nonce mismatch");
wpa_hexdump(MSG_DEBUG, "DPP: Expected Enrollee Nonce",
auth->e_nonce, e_nonce_len);
goto fail;
}
status = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_CONN_STATUS,
&status_len);
if (!status) {
dpp_auth_fail(auth,
"Missing required DPP Connection Status attribute");
goto fail;
}
wpa_hexdump_ascii(MSG_DEBUG, "DPP: connStatus JSON",
status, status_len);
root = json_parse((const char *) status, status_len);
if (!root) {
dpp_auth_fail(auth, "Could not parse connStatus");
goto fail;
}
token = json_get_member(root, "ssid");
if (token && token->type == JSON_STRING &&
os_strlen(token->string) <= SSID_MAX_LEN) {
*ssid_len = os_strlen(token->string);
os_memcpy(ssid, token->string, *ssid_len);
}
token = json_get_member(root, "channelList");
if (token && token->type == JSON_STRING &&
valid_channel_list(token->string))
*channel_list = os_strdup(token->string);
token = json_get_member(root, "result");
if (!token || token->type != JSON_NUMBER) {
dpp_auth_fail(auth, "No connStatus - result");
goto fail;
}
wpa_printf(MSG_DEBUG, "DPP: result %d", token->number);
ret = token->number;
fail:
json_free(root);
bin_clear_free(unwrapped, unwrapped_len);
return ret;
}
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
@ -8721,6 +8864,10 @@ int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
#ifdef CONFIG_DPP2 #ifdef CONFIG_DPP2
static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx,
void *timeout_ctx);
static void dpp_connection_free(struct dpp_connection *conn) static void dpp_connection_free(struct dpp_connection *conn)
{ {
if (conn->sock >= 0) { if (conn->sock >= 0) {
@ -8730,6 +8877,8 @@ static void dpp_connection_free(struct dpp_connection *conn)
eloop_unregister_sock(conn->sock, EVENT_TYPE_WRITE); eloop_unregister_sock(conn->sock, EVENT_TYPE_WRITE);
close(conn->sock); close(conn->sock);
} }
eloop_cancel_timeout(dpp_controller_conn_status_result_wait_timeout,
conn, NULL);
wpabuf_free(conn->msg); wpabuf_free(conn->msg);
wpabuf_free(conn->msg_out); wpabuf_free(conn->msg_out);
dpp_auth_deinit(conn->auth); dpp_auth_deinit(conn->auth);
@ -9454,6 +9603,22 @@ static int dpp_controller_rx_auth_conf(struct dpp_connection *conn,
} }
static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx,
void *timeout_ctx)
{
struct dpp_connection *conn = eloop_ctx;
if (!conn->auth->waiting_conf_result)
return;
wpa_printf(MSG_DEBUG,
"DPP: Timeout while waiting for Connection Status Result");
wpa_msg(conn->ctrl->global->msg_ctx, MSG_INFO,
DPP_EVENT_CONN_STATUS_RESULT "timeout");
dpp_connection_remove(conn);
}
static int dpp_controller_rx_conf_result(struct dpp_connection *conn, static int dpp_controller_rx_conf_result(struct dpp_connection *conn,
const u8 *hdr, const u8 *buf, const u8 *hdr, const u8 *buf,
size_t len) size_t len)
@ -9473,6 +9638,18 @@ static int dpp_controller_rx_conf_result(struct dpp_connection *conn,
} }
status = dpp_conf_result_rx(auth, hdr, buf, len); status = dpp_conf_result_rx(auth, hdr, buf, len);
if (status == DPP_STATUS_OK && auth->send_conn_status) {
wpa_msg(conn->ctrl->global->msg_ctx, MSG_INFO,
DPP_EVENT_CONF_SENT "wait_conn_status=1");
wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
eloop_cancel_timeout(
dpp_controller_conn_status_result_wait_timeout,
conn, NULL);
eloop_register_timeout(
16, 0, dpp_controller_conn_status_result_wait_timeout,
conn, NULL);
return 0;
}
if (status == DPP_STATUS_OK) if (status == DPP_STATUS_OK)
wpa_msg(conn->ctrl->global->msg_ctx, MSG_INFO, wpa_msg(conn->ctrl->global->msg_ctx, MSG_INFO,
DPP_EVENT_CONF_SENT); DPP_EVENT_CONF_SENT);
@ -9483,6 +9660,39 @@ static int dpp_controller_rx_conf_result(struct dpp_connection *conn,
} }
static int dpp_controller_rx_conn_status_result(struct dpp_connection *conn,
const u8 *hdr, const u8 *buf,
size_t len)
{
struct dpp_authentication *auth = conn->auth;
enum dpp_status_error status;
u8 ssid[SSID_MAX_LEN];
size_t ssid_len = 0;
char *channel_list = NULL;
if (!conn->ctrl)
return 0;
wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
if (!auth || !auth->waiting_conn_status_result) {
wpa_printf(MSG_DEBUG,
"DPP: No DPP Configuration waiting for connection status result - drop");
return -1;
}
status = dpp_conn_status_result_rx(auth, hdr, buf, len,
ssid, &ssid_len, &channel_list);
wpa_msg(conn->ctrl->global->msg_ctx, MSG_INFO,
DPP_EVENT_CONN_STATUS_RESULT
"result=%d ssid=%s channel_list=%s",
status, wpa_ssid_txt(ssid, ssid_len),
channel_list ? channel_list : "N/A");
os_free(channel_list);
return -1; /* to remove the completed connection */
}
static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg, static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
size_t len) size_t len)
{ {
@ -9530,6 +9740,9 @@ static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
return dpp_controller_rx_auth_conf(conn, msg, pos, end - pos); return dpp_controller_rx_auth_conf(conn, msg, pos, end - pos);
case DPP_PA_CONFIGURATION_RESULT: case DPP_PA_CONFIGURATION_RESULT:
return dpp_controller_rx_conf_result(conn, msg, pos, end - pos); return dpp_controller_rx_conf_result(conn, msg, pos, end - pos);
case DPP_PA_CONNECTION_STATUS_RESULT:
return dpp_controller_rx_conn_status_result(conn, msg, pos,
end - pos);
default: default:
/* TODO: missing messages types */ /* TODO: missing messages types */
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,

View file

@ -226,6 +226,7 @@ struct dpp_authentication {
int remove_on_tx_status; int remove_on_tx_status;
int connect_on_tx_status; int connect_on_tx_status;
int waiting_conf_result; int waiting_conf_result;
int waiting_conn_status_result;
int auth_success; int auth_success;
struct wpabuf *conf_req; struct wpabuf *conf_req;
const struct wpabuf *conf_resp; /* owned by GAS server */ const struct wpabuf *conf_resp; /* owned by GAS server */
@ -242,6 +243,7 @@ struct dpp_authentication {
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;
int send_conn_status;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
char *config_obj_override; char *config_obj_override;
char *discovery_override; char *discovery_override;
@ -443,6 +445,12 @@ enum dpp_status_error dpp_conf_result_rx(struct dpp_authentication *auth,
const u8 *attr_start, size_t attr_len); const u8 *attr_start, size_t attr_len);
struct wpabuf * dpp_build_conf_result(struct dpp_authentication *auth, struct wpabuf * dpp_build_conf_result(struct dpp_authentication *auth,
enum dpp_status_error status); enum dpp_status_error status);
enum dpp_status_error dpp_conn_status_result_rx(struct dpp_authentication *auth,
const u8 *hdr,
const u8 *attr_start,
size_t attr_len,
u8 *ssid, size_t *ssid_len,
char **channel_list);
struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type, struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,
size_t len); size_t len);
const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len); const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len);

View file

@ -168,6 +168,7 @@ extern "C" {
#define DPP_EVENT_CONF_RECEIVED "DPP-CONF-RECEIVED " #define DPP_EVENT_CONF_RECEIVED "DPP-CONF-RECEIVED "
#define DPP_EVENT_CONF_SENT "DPP-CONF-SENT " #define DPP_EVENT_CONF_SENT "DPP-CONF-SENT "
#define DPP_EVENT_CONF_FAILED "DPP-CONF-FAILED " #define DPP_EVENT_CONF_FAILED "DPP-CONF-FAILED "
#define DPP_EVENT_CONN_STATUS_RESULT "DPP-CONN-STATUS-RESULT "
#define DPP_EVENT_CONFOBJ_AKM "DPP-CONFOBJ-AKM " #define DPP_EVENT_CONFOBJ_AKM "DPP-CONFOBJ-AKM "
#define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID " #define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID "
#define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS " #define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS "

View file

@ -1270,6 +1270,24 @@ static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx,
} }
static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct dpp_authentication *auth = wpa_s->dpp_auth;
if (!auth || !auth->waiting_conn_status_result)
return;
wpa_printf(MSG_DEBUG,
"DPP: Timeout while waiting for Connection Status Result");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT "timeout");
wpas_dpp_listen_stop(wpa_s);
dpp_auth_deinit(auth);
wpa_s->dpp_auth = NULL;
}
static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src, static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *hdr, const u8 *buf, size_t len) const u8 *hdr, const u8 *buf, size_t len)
{ {
@ -1293,6 +1311,23 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
status = dpp_conf_result_rx(auth, hdr, buf, len); status = dpp_conf_result_rx(auth, hdr, buf, len);
if (status == DPP_STATUS_OK && auth->send_conn_status) {
wpa_msg(wpa_s, MSG_INFO,
DPP_EVENT_CONF_SENT "wait_conn_status=1");
wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout,
wpa_s, NULL);
auth->waiting_conn_status_result = 1;
eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
wpa_s, NULL);
eloop_register_timeout(16, 0,
wpas_dpp_conn_status_result_wait_timeout,
wpa_s, NULL);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_start(wpa_s, auth->neg_freq ? auth->neg_freq :
auth->curr_freq);
return;
}
offchannel_send_action_done(wpa_s); offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s); wpas_dpp_listen_stop(wpa_s);
if (status == DPP_STATUS_OK) if (status == DPP_STATUS_OK)
@ -1305,6 +1340,40 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
} }
static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant *wpa_s,
const u8 *src, const u8 *hdr,
const u8 *buf, size_t len)
{
struct dpp_authentication *auth = wpa_s->dpp_auth;
enum dpp_status_error status;
u8 ssid[SSID_MAX_LEN];
size_t ssid_len = 0;
char *channel_list = NULL;
wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
if (!auth || !auth->waiting_conn_status_result) {
wpa_printf(MSG_DEBUG,
"DPP: No DPP Configuration waiting for connection status result - drop");
return;
}
status = dpp_conn_status_result_rx(auth, hdr, buf, len,
ssid, &ssid_len, &channel_list);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
"result=%d ssid=%s channel_list=%s",
status, wpa_ssid_txt(ssid, ssid_len),
channel_list ? channel_list : "N/A");
os_free(channel_list);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
dpp_auth_deinit(auth);
wpa_s->dpp_auth = NULL;
eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
wpa_s, NULL);
}
static int wpas_dpp_process_conf_obj(void *ctx, static int wpas_dpp_process_conf_obj(void *ctx,
struct dpp_authentication *auth) struct dpp_authentication *auth)
{ {
@ -1848,6 +1917,9 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
case DPP_PA_CONFIGURATION_RESULT: case DPP_PA_CONFIGURATION_RESULT:
wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len); wpas_dpp_rx_conf_result(wpa_s, src, hdr, buf, len);
break; break;
case DPP_PA_CONNECTION_STATUS_RESULT:
wpas_dpp_rx_conn_status_result(wpa_s, src, hdr, buf, len);
break;
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
default: default:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
@ -2294,6 +2366,8 @@ void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
#ifdef CONFIG_DPP2 #ifdef CONFIG_DPP2
eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
wpa_s, NULL);
dpp_pfs_free(wpa_s->dpp_pfs); dpp_pfs_free(wpa_s->dpp_pfs);
wpa_s->dpp_pfs = NULL; wpa_s->dpp_pfs = NULL;
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */