nl80211: Introduce the interface for external authentication
This command/event interface can be used by host drivers that do not define separate commands for authentication and association but rely on wpa_supplicant for the authentication (SAE) processing. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
8678b14faa
commit
ba71cb821a
4 changed files with 143 additions and 1 deletions
|
@ -2051,6 +2051,36 @@ enum wpa_drv_update_connect_params_mask {
|
||||||
WPA_DRV_UPDATE_AUTH_TYPE = BIT(2),
|
WPA_DRV_UPDATE_AUTH_TYPE = BIT(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct external_auth - External authentication trigger parameters
|
||||||
|
*
|
||||||
|
* These are used across the external authentication request and event
|
||||||
|
* interfaces.
|
||||||
|
* @action: Action type / trigger for external authentication. Only significant
|
||||||
|
* for the event interface.
|
||||||
|
* @bssid: BSSID of the peer with which the authentication has to happen. Used
|
||||||
|
* by both the request and event interface.
|
||||||
|
* @ssid: SSID of the AP. Used by both the request and event interface.
|
||||||
|
* @ssid_len: SSID length in octets.
|
||||||
|
* @key_mgmt_suite: AKM suite of the respective authentication. Optional for
|
||||||
|
* the request interface.
|
||||||
|
* @status: Status code, %WLAN_STATUS_SUCCESS for successful authentication,
|
||||||
|
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if wpa_supplicant cannot give
|
||||||
|
* the real status code for failures. Used only for the request interface
|
||||||
|
* from user space to the driver.
|
||||||
|
*/
|
||||||
|
struct external_auth {
|
||||||
|
enum {
|
||||||
|
EXT_AUTH_START,
|
||||||
|
EXT_AUTH_ABORT,
|
||||||
|
} action;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
u8 ssid[SSID_MAX_LEN];
|
||||||
|
size_t ssid_len;
|
||||||
|
unsigned int key_mgmt_suite;
|
||||||
|
u16 status;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_ops - Driver interface API definition
|
* struct wpa_driver_ops - Driver interface API definition
|
||||||
*
|
*
|
||||||
|
@ -4012,6 +4042,16 @@ struct wpa_driver_ops {
|
||||||
int (*update_connect_params)(
|
int (*update_connect_params)(
|
||||||
void *priv, struct wpa_driver_associate_params *params,
|
void *priv, struct wpa_driver_associate_params *params,
|
||||||
enum wpa_drv_update_connect_params_mask mask);
|
enum wpa_drv_update_connect_params_mask mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send_external_auth_status - Indicate the status of external
|
||||||
|
* authentication processing to the host driver.
|
||||||
|
* @priv: Private driver interface data
|
||||||
|
* @params: Status of authentication processing.
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int (*send_external_auth_status)(void *priv,
|
||||||
|
struct external_auth *params);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4507,6 +4547,16 @@ enum wpa_event_type {
|
||||||
* performed before start operating on this channel.
|
* performed before start operating on this channel.
|
||||||
*/
|
*/
|
||||||
EVENT_DFS_PRE_CAC_EXPIRED,
|
EVENT_DFS_PRE_CAC_EXPIRED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVENT_EXTERNAL_AUTH - This event interface is used by host drivers
|
||||||
|
* that do not define separate commands for authentication and
|
||||||
|
* association (~WPA_DRIVER_FLAGS_SME) but offload the 802.11
|
||||||
|
* authentication to wpa_supplicant. This event carries all the
|
||||||
|
* necessary information from the host driver for the authentication to
|
||||||
|
* happen.
|
||||||
|
*/
|
||||||
|
EVENT_EXTERNAL_AUTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -5309,6 +5359,9 @@ union wpa_event_data {
|
||||||
P2P_LO_STOPPED_REASON_NOT_SUPPORTED,
|
P2P_LO_STOPPED_REASON_NOT_SUPPORTED,
|
||||||
} reason_code;
|
} reason_code;
|
||||||
} p2p_lo_stop;
|
} p2p_lo_stop;
|
||||||
|
|
||||||
|
/* For EVENT_EXTERNAL_AUTH */
|
||||||
|
struct external_auth external_auth;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -82,6 +82,7 @@ const char * event_to_string(enum wpa_event_type event)
|
||||||
E2S(P2P_LO_STOP);
|
E2S(P2P_LO_STOP);
|
||||||
E2S(BEACON_LOSS);
|
E2S(BEACON_LOSS);
|
||||||
E2S(DFS_PRE_CAC_EXPIRED);
|
E2S(DFS_PRE_CAC_EXPIRED);
|
||||||
|
E2S(EXTERNAL_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
|
|
|
@ -2020,7 +2020,9 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
|
wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
|
||||||
"handle %p", bss->nl_mgmt);
|
"handle %p", bss->nl_mgmt);
|
||||||
|
|
||||||
if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
|
if (drv->nlmode == NL80211_IFTYPE_ADHOC ||
|
||||||
|
((drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
|
||||||
|
!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))) {
|
||||||
u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
|
u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
|
||||||
|
|
||||||
/* register for any AUTH message */
|
/* register for any AUTH message */
|
||||||
|
@ -5368,6 +5370,11 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
|
||||||
nl80211_put_fils_connect_params(drv, params, msg) != 0)
|
nl80211_put_fils_connect_params(drv, params, msg) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if ((params->auth_alg & WPA_AUTH_ALG_SAE) &&
|
||||||
|
(!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) &&
|
||||||
|
nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10377,6 +10384,38 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int nl80211_send_external_auth_status(void *priv,
|
||||||
|
struct external_auth *params)
|
||||||
|
{
|
||||||
|
struct i802_bss *bss = priv;
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
struct nl_msg *msg = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
wpa_dbg(drv->ctx, MSG_DEBUG,
|
||||||
|
"nl80211: External auth status: %u", params->status);
|
||||||
|
|
||||||
|
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_EXTERNAL_AUTH);
|
||||||
|
if (!msg ||
|
||||||
|
nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, params->status) ||
|
||||||
|
nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
|
||||||
|
params->ssid) ||
|
||||||
|
nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid))
|
||||||
|
goto fail;
|
||||||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
|
msg = NULL;
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: External Auth status update failed: ret=%d (%s)",
|
||||||
|
ret, strerror(-ret));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
fail:
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.name = "nl80211",
|
.name = "nl80211",
|
||||||
.desc = "Linux nl80211/cfg80211",
|
.desc = "Linux nl80211/cfg80211",
|
||||||
|
@ -10504,4 +10543,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
|
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
|
||||||
.get_ext_capab = nl80211_get_ext_capab,
|
.get_ext_capab = nl80211_get_ext_capab,
|
||||||
.update_connect_params = nl80211_update_connection_params,
|
.update_connect_params = nl80211_update_connection_params,
|
||||||
|
.send_external_auth_status = nl80211_send_external_auth_status,
|
||||||
};
|
};
|
||||||
|
|
|
@ -131,6 +131,7 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd)
|
||||||
C2S(NL80211_CMD_SET_QOS_MAP)
|
C2S(NL80211_CMD_SET_QOS_MAP)
|
||||||
C2S(NL80211_CMD_ADD_TX_TS)
|
C2S(NL80211_CMD_ADD_TX_TS)
|
||||||
C2S(NL80211_CMD_DEL_TX_TS)
|
C2S(NL80211_CMD_DEL_TX_TS)
|
||||||
|
C2S(NL80211_CMD_EXTERNAL_AUTH)
|
||||||
default:
|
default:
|
||||||
return "NL80211_CMD_UNKNOWN";
|
return "NL80211_CMD_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
@ -2175,6 +2176,50 @@ static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
|
||||||
|
struct nlattr **tb)
|
||||||
|
{
|
||||||
|
union wpa_event_data event;
|
||||||
|
enum nl80211_external_auth_action act;
|
||||||
|
|
||||||
|
if (!tb[NL80211_ATTR_AKM_SUITES] ||
|
||||||
|
!tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] ||
|
||||||
|
!tb[NL80211_ATTR_BSSID] ||
|
||||||
|
!tb[NL80211_ATTR_SSID])
|
||||||
|
return;
|
||||||
|
|
||||||
|
os_memset(&event, 0, sizeof(event));
|
||||||
|
act = nla_get_u32(tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION]);
|
||||||
|
switch (act) {
|
||||||
|
case NL80211_EXTERNAL_AUTH_START:
|
||||||
|
event.external_auth.action = EXT_AUTH_START;
|
||||||
|
break;
|
||||||
|
case NL80211_EXTERNAL_AUTH_ABORT:
|
||||||
|
event.external_auth.action = EXT_AUTH_ABORT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.external_auth.key_mgmt_suite =
|
||||||
|
nla_get_u32(tb[NL80211_ATTR_AKM_SUITES]);
|
||||||
|
|
||||||
|
event.external_auth.ssid_len = nla_len(tb[NL80211_ATTR_SSID]);
|
||||||
|
if (event.external_auth.ssid_len > SSID_MAX_LEN)
|
||||||
|
return;
|
||||||
|
os_memcpy(event.external_auth.ssid, nla_data(tb[NL80211_ATTR_SSID]),
|
||||||
|
event.external_auth.ssid_len);
|
||||||
|
|
||||||
|
os_memcpy(event.external_auth.bssid, nla_data(tb[NL80211_ATTR_BSSID]),
|
||||||
|
ETH_ALEN);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: External auth action: %u, AKM: 0x%x",
|
||||||
|
event.external_auth.action,
|
||||||
|
event.external_auth.key_mgmt_suite);
|
||||||
|
wpa_supplicant_event(drv->ctx, EVENT_EXTERNAL_AUTH, &event);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
||||||
struct nlattr **tb)
|
struct nlattr **tb)
|
||||||
{
|
{
|
||||||
|
@ -2373,6 +2418,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
||||||
case NL80211_CMD_NEW_PEER_CANDIDATE:
|
case NL80211_CMD_NEW_PEER_CANDIDATE:
|
||||||
nl80211_new_peer_candidate(drv, tb);
|
nl80211_new_peer_candidate(drv, tb);
|
||||||
break;
|
break;
|
||||||
|
case NL80211_CMD_EXTERNAL_AUTH:
|
||||||
|
nl80211_external_auth(drv, tb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||||
"(cmd=%d)", cmd);
|
"(cmd=%d)", cmd);
|
||||||
|
|
Loading…
Reference in a new issue