aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2015-09-05 10:21:17 (GMT)
committerJouni Malinen <j@w1.fi>2015-09-05 10:21:17 (GMT)
commit6ebe816be00702904332744547180bdb27b126f3 (patch)
tree27b6356a4e4b240c90a0101430cbcc746974744a /src
parent06f52b12f9942917f0e86a62a19167002f425025 (diff)
downloadhostap-6ebe816be00702904332744547180bdb27b126f3.zip
hostap-6ebe816be00702904332744547180bdb27b126f3.tar.gz
hostap-6ebe816be00702904332744547180bdb27b126f3.tar.bz2
wpa_priv: Add authentication command and event
These are needed to work with nl80211 driver interface. Signed-off-by: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src')
-rw-r--r--src/common/privsep_commands.h30
-rw-r--r--src/drivers/driver_privsep.c80
2 files changed, 110 insertions, 0 deletions
diff --git a/src/common/privsep_commands.h b/src/common/privsep_commands.h
index 6562140..8dff303 100644
--- a/src/common/privsep_commands.h
+++ b/src/common/privsep_commands.h
@@ -26,6 +26,25 @@ enum privsep_cmd {
PRIVSEP_CMD_L2_NOTIFY_AUTH_START,
PRIVSEP_CMD_L2_SEND,
PRIVSEP_CMD_SET_COUNTRY,
+ PRIVSEP_CMD_AUTHENTICATE,
+};
+
+struct privsep_cmd_authenticate
+{
+ int freq;
+ u8 bssid[ETH_ALEN];
+ u8 ssid[SSID_MAX_LEN];
+ size_t ssid_len;
+ int auth_alg;
+ size_t ie_len;
+ u8 wep_key[4][16];
+ size_t wep_key_len[4];
+ int wep_tx_keyidx;
+ int local_state_change;
+ int p2p;
+ size_t sae_data_len;
+ /* followed by ie_len bytes of ie */
+ /* followed by sae_data_len bytes of sae_data */
};
struct privsep_cmd_associate
@@ -69,6 +88,17 @@ enum privsep_event {
PRIVSEP_EVENT_FT_RESPONSE,
PRIVSEP_EVENT_RX_EAPOL,
PRIVSEP_EVENT_SCAN_STARTED,
+ PRIVSEP_EVENT_AUTH,
+};
+
+struct privsep_event_auth {
+ u8 peer[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ u16 auth_type;
+ u16 auth_transaction;
+ u16 status_code;
+ size_t ies_len;
+ /* followed by ies_len bytes of ies */
};
#endif /* PRIVSEP_COMMANDS_H */
diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c
index c2d70fc..1f1676a 100644
--- a/src/drivers/driver_privsep.c
+++ b/src/drivers/driver_privsep.c
@@ -220,6 +220,56 @@ static int wpa_driver_privsep_set_key(const char *ifname, void *priv,
}
+static int wpa_driver_privsep_authenticate(
+ void *priv, struct wpa_driver_auth_params *params)
+{
+ struct wpa_driver_privsep_data *drv = priv;
+ struct privsep_cmd_authenticate *data;
+ int i, res;
+ size_t buflen;
+ u8 *pos;
+
+ wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d bssid=" MACSTR
+ " auth_alg=%d local_state_change=%d p2p=%d",
+ __func__, priv, params->freq, MAC2STR(params->bssid),
+ params->auth_alg, params->local_state_change, params->p2p);
+
+ buflen = sizeof(*data) + params->ie_len + params->sae_data_len;
+ data = os_zalloc(buflen);
+ if (data == NULL)
+ return -1;
+
+ data->freq = params->freq;
+ os_memcpy(data->bssid, params->bssid, ETH_ALEN);
+ os_memcpy(data->ssid, params->ssid, params->ssid_len);
+ data->ssid_len = params->ssid_len;
+ data->auth_alg = params->auth_alg;
+ data->ie_len = params->ie_len;
+ for (i = 0; i < 4; i++) {
+ if (params->wep_key[i])
+ os_memcpy(data->wep_key[i], params->wep_key[i],
+ params->wep_key_len[i]);
+ data->wep_key_len[i] = params->wep_key_len[i];
+ }
+ data->wep_tx_keyidx = params->wep_tx_keyidx;
+ data->local_state_change = params->local_state_change;
+ data->p2p = params->p2p;
+ pos = (u8 *) (data + 1);
+ if (params->ie_len) {
+ os_memcpy(pos, params->ie, params->ie_len);
+ pos += params->ie_len;
+ }
+ if (params->sae_data_len)
+ os_memcpy(pos, params->sae_data, params->sae_data_len);
+
+ res = wpa_priv_cmd(drv, PRIVSEP_CMD_AUTHENTICATE, data, buflen,
+ NULL, NULL);
+ os_free(data);
+
+ return res;
+}
+
+
static int wpa_driver_privsep_associate(
void *priv, struct wpa_driver_associate_params *params)
{
@@ -309,6 +359,32 @@ static int wpa_driver_privsep_deauthenticate(void *priv, const u8 *addr,
}
+static void wpa_driver_privsep_event_auth(void *ctx, u8 *buf, size_t len)
+{
+ union wpa_event_data data;
+ struct privsep_event_auth *auth;
+
+ os_memset(&data, 0, sizeof(data));
+ if (len < sizeof(*auth))
+ return;
+ auth = (struct privsep_event_auth *) buf;
+ if (len < sizeof(*auth) + auth->ies_len)
+ return;
+
+ os_memcpy(data.auth.peer, auth->peer, ETH_ALEN);
+ os_memcpy(data.auth.bssid, auth->bssid, ETH_ALEN);
+ data.auth.auth_type = auth->auth_type;
+ data.auth.auth_transaction = auth->auth_transaction;
+ data.auth.status_code = auth->status_code;
+ if (auth->ies_len) {
+ data.auth.ies = (u8 *) (auth + 1);
+ data.auth.ies_len = auth->ies_len;
+ }
+
+ wpa_supplicant_event(ctx, EVENT_AUTH, &data);
+}
+
+
static void wpa_driver_privsep_event_assoc(void *ctx,
enum wpa_event_type event,
u8 *buf, size_t len)
@@ -506,6 +582,9 @@ static void wpa_driver_privsep_receive(int sock, void *eloop_ctx,
wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf,
event_len);
break;
+ case PRIVSEP_EVENT_AUTH:
+ wpa_driver_privsep_event_auth(drv->ctx, event_buf, event_len);
+ break;
}
os_free(buf);
@@ -742,6 +821,7 @@ struct wpa_driver_ops wpa_driver_privsep_ops = {
.set_param = wpa_driver_privsep_set_param,
.scan2 = wpa_driver_privsep_scan,
.deauthenticate = wpa_driver_privsep_deauthenticate,
+ .authenticate = wpa_driver_privsep_authenticate,
.associate = wpa_driver_privsep_associate,
.get_capa = wpa_driver_privsep_get_capa,
.get_mac_addr = wpa_driver_privsep_get_mac_addr,