Compare commits
3 commits
vlan_per_p
...
vlan_per_p
Author | SHA1 | Date | |
---|---|---|---|
9fa8a0c991 | |||
c34c234aec | |||
b82877d603 |
14 changed files with 163 additions and 81 deletions
|
@ -1096,13 +1096,14 @@ const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
|
||||||
|
|
||||||
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||||
const u8 *addr, const u8 *p2p_dev_addr,
|
const u8 *addr, const u8 *p2p_dev_addr,
|
||||||
const u8 *prev_psk, int *vlan_id)
|
const u8 *prev_psk,
|
||||||
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
struct hostapd_wpa_psk *psk;
|
struct hostapd_wpa_psk *psk;
|
||||||
int next_ok = prev_psk == NULL;
|
int next_ok = prev_psk == NULL;
|
||||||
|
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
|
|
||||||
if (p2p_dev_addr && !is_zero_ether_addr(p2p_dev_addr)) {
|
if (p2p_dev_addr && !is_zero_ether_addr(p2p_dev_addr)) {
|
||||||
wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
|
wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
|
||||||
|
@ -1122,8 +1123,8 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||||
(!addr && p2p_dev_addr &&
|
(!addr && p2p_dev_addr &&
|
||||||
os_memcmp(psk->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
|
os_memcmp(psk->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
|
||||||
0))) {
|
0))) {
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = psk->vlan_id;
|
*vlan_desc = vlan_desc_from_id(psk->vlan_id);
|
||||||
return psk->psk;
|
return psk->psk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,8 @@ struct hostapd_sta_wpa_psk_short {
|
||||||
u8 psk[PMK_LEN];
|
u8 psk[PMK_LEN];
|
||||||
char passphrase[MAX_PASSPHRASE_LEN + 1];
|
char passphrase[MAX_PASSPHRASE_LEN + 1];
|
||||||
int ref; /* (number of references held) - 1 */
|
int ref; /* (number of references held) - 1 */
|
||||||
|
struct vlan_description vlan;
|
||||||
|
u8 tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hostapd_wpa_psk {
|
struct hostapd_wpa_psk {
|
||||||
|
@ -1174,7 +1176,8 @@ int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
|
||||||
int hostapd_rate_found(int *list, int rate);
|
int hostapd_rate_found(int *list, int rate);
|
||||||
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||||
const u8 *addr, const u8 *p2p_dev_addr,
|
const u8 *addr, const u8 *p2p_dev_addr,
|
||||||
const u8 *prev_psk, int *vlan_id);
|
const u8 *prev_psk,
|
||||||
|
struct vlan_description *vlan_desc);
|
||||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
||||||
int hostapd_vlan_valid(struct hostapd_vlan *vlan,
|
int hostapd_vlan_valid(struct hostapd_vlan *vlan,
|
||||||
struct vlan_description *vlan_desc);
|
struct vlan_description *vlan_desc);
|
||||||
|
|
|
@ -380,6 +380,7 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd,
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
size_t i;
|
size_t i;
|
||||||
struct hostapd_sta_wpa_psk_short *psk;
|
struct hostapd_sta_wpa_psk_short *psk;
|
||||||
|
u8 tag = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode all tunnel passwords as PSK and save them into a linked list.
|
* Decode all tunnel passwords as PSK and save them into a linked list.
|
||||||
|
@ -387,7 +388,7 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd,
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
passphrase = radius_msg_get_tunnel_password(
|
passphrase = radius_msg_get_tunnel_password(
|
||||||
msg, &passphraselen, shared_secret, shared_secret_len,
|
msg, &passphraselen, shared_secret, shared_secret_len,
|
||||||
req, i);
|
req, i, &tag);
|
||||||
/*
|
/*
|
||||||
* Passphrase is NULL iff there is no i-th Tunnel-Password
|
* Passphrase is NULL iff there is no i-th Tunnel-Password
|
||||||
* attribute in msg.
|
* attribute in msg.
|
||||||
|
@ -424,6 +425,7 @@ static void decode_tunnel_passwords(struct hostapd_data *hapd,
|
||||||
psk->is_passphrase = 1;
|
psk->is_passphrase = 1;
|
||||||
}
|
}
|
||||||
psk->next = cache->info.psk;
|
psk->next = cache->info.psk;
|
||||||
|
psk->tag = tag;
|
||||||
cache->info.psk = psk;
|
cache->info.psk = psk;
|
||||||
psk = NULL;
|
psk = NULL;
|
||||||
}
|
}
|
||||||
|
@ -455,6 +457,8 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||||
struct hostapd_cached_radius_acl *cache;
|
struct hostapd_cached_radius_acl *cache;
|
||||||
struct radius_sta *info;
|
struct radius_sta *info;
|
||||||
struct radius_hdr *hdr = radius_msg_get_hdr(msg);
|
struct radius_hdr *hdr = radius_msg_get_hdr(msg);
|
||||||
|
struct hostapd_sta_wpa_psk_short *psk;
|
||||||
|
int vlan_psk_empty = 1;
|
||||||
|
|
||||||
query = hapd->acl_queries;
|
query = hapd->acl_queries;
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
|
@ -513,14 +517,26 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||||
info->acct_interim_interval = 0;
|
info->acct_interim_interval = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED)
|
|
||||||
info->vlan_id.notempty = !!radius_msg_get_vlanid(
|
|
||||||
msg, &info->vlan_id.untagged,
|
|
||||||
MAX_NUM_TAGGED_VLAN, info->vlan_id.tagged);
|
|
||||||
|
|
||||||
decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
|
decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
|
||||||
msg, req, cache);
|
msg, req, cache);
|
||||||
|
|
||||||
|
if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) {
|
||||||
|
/*
|
||||||
|
* Fill in the "default" VLAN (in case there is no
|
||||||
|
* tagged Tunnel* attribute associated with the PSK)
|
||||||
|
*/
|
||||||
|
info->vlan_id.notempty = !!radius_msg_get_vlanid(
|
||||||
|
msg, &info->vlan_id.untagged,
|
||||||
|
MAX_NUM_TAGGED_VLAN, info->vlan_id.tagged, 0);
|
||||||
|
/* Fill in per-PSK VLAN descriptions */
|
||||||
|
for (psk = info->psk; psk; psk = psk->next) {
|
||||||
|
psk->vlan.notempty = !!radius_msg_get_vlanid(
|
||||||
|
msg, &psk->vlan.untagged,
|
||||||
|
MAX_NUM_TAGGED_VLAN, psk->vlan.tagged,
|
||||||
|
psk->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
|
if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
|
||||||
&buf, &len, NULL) == 0) {
|
&buf, &len, NULL) == 0) {
|
||||||
info->identity = os_zalloc(len + 1);
|
info->identity = os_zalloc(len + 1);
|
||||||
|
@ -549,9 +565,23 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
|
||||||
info->vlan_id.tagged[0] ? "+" : "");
|
info->vlan_id.tagged[0] ? "+" : "");
|
||||||
os_memset(&info->vlan_id, 0, sizeof(info->vlan_id));
|
os_memset(&info->vlan_id, 0, sizeof(info->vlan_id));
|
||||||
}
|
}
|
||||||
|
for (psk = info->psk; psk; psk = psk->next) {
|
||||||
|
if (psk->vlan.notempty &&
|
||||||
|
!hostapd_vlan_valid(hapd->conf->vlan, &psk->vlan)) {
|
||||||
|
hostapd_logger(hapd, query->addr,
|
||||||
|
HOSTAPD_MODULE_RADIUS,
|
||||||
|
HOSTAPD_LEVEL_INFO,
|
||||||
|
"Invalid VLAN %d%s received from RADIUS server",
|
||||||
|
psk->vlan.untagged,
|
||||||
|
psk->vlan.tagged[0] ? "+" : "");
|
||||||
|
os_memset(&psk->vlan, 0, sizeof(psk->vlan));
|
||||||
|
}
|
||||||
|
vlan_psk_empty &= !psk->vlan.notempty;
|
||||||
|
}
|
||||||
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED &&
|
if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED &&
|
||||||
!info->vlan_id.notempty)
|
!info->vlan_id.notempty && vlan_psk_empty) {
|
||||||
cache->accepted = HOSTAPD_ACL_REJECT;
|
cache->accepted = HOSTAPD_ACL_REJECT;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
cache->accepted = HOSTAPD_ACL_REJECT;
|
cache->accepted = HOSTAPD_ACL_REJECT;
|
||||||
cache->next = hapd->acl_cache;
|
cache->next = hapd->acl_cache;
|
||||||
|
|
|
@ -1876,7 +1876,7 @@ static int ieee802_1x_update_vlan(struct radius_msg *msg,
|
||||||
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
||||||
vlan_desc.notempty = !!radius_msg_get_vlanid(msg, &vlan_desc.untagged,
|
vlan_desc.notempty = !!radius_msg_get_vlanid(msg, &vlan_desc.untagged,
|
||||||
MAX_NUM_TAGGED_VLAN,
|
MAX_NUM_TAGGED_VLAN,
|
||||||
vlan_desc.tagged);
|
vlan_desc.tagged, 0);
|
||||||
|
|
||||||
if (vlan_desc.notempty &&
|
if (vlan_desc.notempty &&
|
||||||
!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
|
!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
|
||||||
|
|
|
@ -32,3 +32,16 @@ int vlan_compare(struct vlan_description *a, struct vlan_description *b)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vlan_description
|
||||||
|
vlan_desc_from_id(int vlan_id)
|
||||||
|
{
|
||||||
|
struct vlan_description vlan_desc;
|
||||||
|
|
||||||
|
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
||||||
|
|
||||||
|
vlan_desc.notempty = 1;
|
||||||
|
vlan_desc.untagged = vlan_id;
|
||||||
|
|
||||||
|
return vlan_desc;
|
||||||
|
}
|
||||||
|
|
|
@ -19,12 +19,23 @@ struct vlan_description {
|
||||||
|
|
||||||
#ifndef CONFIG_NO_VLAN
|
#ifndef CONFIG_NO_VLAN
|
||||||
int vlan_compare(struct vlan_description *a, struct vlan_description *b);
|
int vlan_compare(struct vlan_description *a, struct vlan_description *b);
|
||||||
|
struct vlan_description vlan_desc_from_id(int vlan_id);
|
||||||
#else /* CONFIG_NO_VLAN */
|
#else /* CONFIG_NO_VLAN */
|
||||||
static inline int
|
static inline int
|
||||||
vlan_compare(struct vlan_description *a, struct vlan_description *b)
|
vlan_compare(struct vlan_description *a, struct vlan_description *b)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct vlan_description
|
||||||
|
vlan_desc_from_id(int vlan_id)
|
||||||
|
{
|
||||||
|
struct vlan_description vlan_desc;
|
||||||
|
|
||||||
|
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
||||||
|
|
||||||
|
return vlan_desc;
|
||||||
|
}
|
||||||
#endif /* CONFIG_NO_VLAN */
|
#endif /* CONFIG_NO_VLAN */
|
||||||
|
|
||||||
#endif /* VLAN_H */
|
#endif /* VLAN_H */
|
||||||
|
|
|
@ -118,12 +118,12 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
|
||||||
const u8 *addr,
|
const u8 *addr,
|
||||||
const u8 *p2p_dev_addr,
|
const u8 *p2p_dev_addr,
|
||||||
const u8 *prev_psk, size_t *psk_len,
|
const u8 *prev_psk, size_t *psk_len,
|
||||||
int *vlan_id)
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
if (!wpa_auth->cb->get_psk)
|
if (!wpa_auth->cb->get_psk)
|
||||||
return NULL;
|
return NULL;
|
||||||
return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
|
return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
|
||||||
prev_psk, psk_len, vlan_id);
|
prev_psk, psk_len, vlan_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -298,11 +298,12 @@ static int wpa_channel_info(struct wpa_authenticator *wpa_auth,
|
||||||
|
|
||||||
|
|
||||||
static int wpa_auth_update_vlan(struct wpa_authenticator *wpa_auth,
|
static int wpa_auth_update_vlan(struct wpa_authenticator *wpa_auth,
|
||||||
const u8 *addr, int vlan_id)
|
const u8 *addr,
|
||||||
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
if (!wpa_auth->cb->update_vlan)
|
if (!wpa_auth->cb->update_vlan)
|
||||||
return -1;
|
return -1;
|
||||||
return wpa_auth->cb->update_vlan(wpa_auth->cb_ctx, addr, vlan_id);
|
return wpa_auth->cb->update_vlan(wpa_auth->cb_ctx, addr, vlan_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -937,15 +938,16 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
const u8 *pmk = NULL;
|
const u8 *pmk = NULL;
|
||||||
size_t pmk_len;
|
size_t pmk_len;
|
||||||
int vlan_id = 0;
|
struct vlan_description vlan_desc;
|
||||||
|
|
||||||
os_memset(&PTK, 0, sizeof(PTK));
|
os_memset(&PTK, 0, sizeof(PTK));
|
||||||
|
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
||||||
!wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
|
!wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
|
||||||
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
|
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
|
||||||
sm->p2p_dev_addr, pmk, &pmk_len,
|
sm->p2p_dev_addr, pmk, &pmk_len,
|
||||||
&vlan_id);
|
&vlan_desc);
|
||||||
if (!pmk)
|
if (!pmk)
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
|
@ -988,8 +990,9 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
|
||||||
"WPA: Earlier SNonce resulted in matching MIC");
|
"WPA: Earlier SNonce resulted in matching MIC");
|
||||||
sm->alt_snonce_valid = 0;
|
sm->alt_snonce_valid = 0;
|
||||||
|
|
||||||
if (vlan_id && wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
if (vlan_desc.notempty && vlan_desc.untagged
|
||||||
wpa_auth_update_vlan(sm->wpa_auth, sm->addr, vlan_id) < 0)
|
&& wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
||||||
|
wpa_auth_update_vlan(sm->wpa_auth, sm->addr, &vlan_desc) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN);
|
os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN);
|
||||||
|
@ -2938,7 +2941,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||||
struct ieee802_1x_hdr *hdr;
|
struct ieee802_1x_hdr *hdr;
|
||||||
struct wpa_eapol_key *key;
|
struct wpa_eapol_key *key;
|
||||||
struct wpa_eapol_ie_parse kde;
|
struct wpa_eapol_ie_parse kde;
|
||||||
int vlan_id = 0;
|
struct vlan_description vlan_desc;
|
||||||
int owe_ptk_workaround = !!wpa_auth->conf.owe_ptk_workaround;
|
int owe_ptk_workaround = !!wpa_auth->conf.owe_ptk_workaround;
|
||||||
|
|
||||||
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
|
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
|
||||||
|
@ -2946,6 +2949,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||||
sm->update_snonce = false;
|
sm->update_snonce = false;
|
||||||
os_memset(&PTK, 0, sizeof(PTK));
|
os_memset(&PTK, 0, sizeof(PTK));
|
||||||
|
|
||||||
|
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
||||||
|
|
||||||
mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
|
mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
|
||||||
|
|
||||||
/* WPA with IEEE 802.1X: use the derived PMK from EAP
|
/* WPA with IEEE 802.1X: use the derived PMK from EAP
|
||||||
|
@ -2956,7 +2961,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||||
!wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
|
!wpa_key_mgmt_sae(sm->wpa_key_mgmt)) {
|
||||||
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
|
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
|
||||||
sm->p2p_dev_addr, pmk, &pmk_len,
|
sm->p2p_dev_addr, pmk, &pmk_len,
|
||||||
&vlan_id);
|
&vlan_desc);
|
||||||
if (!pmk)
|
if (!pmk)
|
||||||
break;
|
break;
|
||||||
psk_found = 1;
|
psk_found = 1;
|
||||||
|
@ -3189,8 +3194,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211R_AP */
|
#endif /* CONFIG_IEEE80211R_AP */
|
||||||
|
|
||||||
if (vlan_id && wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
if (vlan_desc.notempty && vlan_desc.untagged &&
|
||||||
wpa_auth_update_vlan(wpa_auth, sm->addr, vlan_id) < 0) {
|
wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
|
||||||
|
wpa_auth_update_vlan(wpa_auth, sm->addr, &vlan_desc) < 0) {
|
||||||
wpa_sta_disconnect(wpa_auth, sm->addr,
|
wpa_sta_disconnect(wpa_auth, sm->addr,
|
||||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -296,7 +296,7 @@ struct wpa_auth_callbacks {
|
||||||
int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var);
|
int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var);
|
||||||
const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *p2p_dev_addr,
|
const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *p2p_dev_addr,
|
||||||
const u8 *prev_psk, size_t *psk_len,
|
const u8 *prev_psk, size_t *psk_len,
|
||||||
int *vlan_id);
|
struct vlan_description *vlan_desc);
|
||||||
int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len);
|
int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len);
|
||||||
int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg,
|
int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg,
|
||||||
const u8 *addr, int idx, u8 *key, size_t key_len,
|
const u8 *addr, int idx, u8 *key, size_t key_len,
|
||||||
|
@ -313,7 +313,8 @@ struct wpa_auth_callbacks {
|
||||||
int (*send_oui)(void *ctx, const u8 *dst, u8 oui_suffix, const u8 *data,
|
int (*send_oui)(void *ctx, const u8 *dst, u8 oui_suffix, const u8 *data,
|
||||||
size_t data_len);
|
size_t data_len);
|
||||||
int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
|
int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
|
||||||
int (*update_vlan)(void *ctx, const u8 *addr, int vlan_id);
|
int (*update_vlan)(void *ctx, const u8 *addr,
|
||||||
|
struct vlan_description *vlan_desc);
|
||||||
int (*get_sta_tx_params)(void *ctx, const u8 *addr,
|
int (*get_sta_tx_params)(void *ctx, const u8 *addr,
|
||||||
int ap_max_chanwidth, int ap_seg1_idx,
|
int ap_max_chanwidth, int ap_seg1_idx,
|
||||||
int *bandwidth, int *seg1_idx);
|
int *bandwidth, int *seg1_idx);
|
||||||
|
|
|
@ -330,14 +330,15 @@ static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,
|
||||||
static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
|
static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
|
||||||
const u8 *p2p_dev_addr,
|
const u8 *p2p_dev_addr,
|
||||||
const u8 *prev_psk, size_t *psk_len,
|
const u8 *prev_psk, size_t *psk_len,
|
||||||
int *vlan_id)
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
struct hostapd_data *hapd = ctx;
|
struct hostapd_data *hapd = ctx;
|
||||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||||
|
struct vlan_description *vlan = NULL;
|
||||||
const u8 *psk;
|
const u8 *psk;
|
||||||
|
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
if (psk_len)
|
if (psk_len)
|
||||||
*psk_len = PMK_LEN;
|
*psk_len = PMK_LEN;
|
||||||
|
|
||||||
|
@ -374,7 +375,7 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
|
||||||
#endif /* CONFIG_OWE */
|
#endif /* CONFIG_OWE */
|
||||||
|
|
||||||
psk = hostapd_get_psk(hapd->conf, addr, p2p_dev_addr, prev_psk,
|
psk = hostapd_get_psk(hapd->conf, addr, p2p_dev_addr, prev_psk,
|
||||||
vlan_id);
|
vlan_desc);
|
||||||
/*
|
/*
|
||||||
* This is about to iterate over all psks, prev_psk gives the last
|
* This is about to iterate over all psks, prev_psk gives the last
|
||||||
* returned psk which should not be returned again.
|
* returned psk which should not be returned again.
|
||||||
|
@ -383,9 +384,10 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
|
||||||
if (sta && sta->psk && !psk) {
|
if (sta && sta->psk && !psk) {
|
||||||
struct hostapd_sta_wpa_psk_short *pos;
|
struct hostapd_sta_wpa_psk_short *pos;
|
||||||
|
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
psk = sta->psk->psk;
|
psk = sta->psk->psk;
|
||||||
|
vlan = &sta->psk->vlan;
|
||||||
for (pos = sta->psk; pos; pos = pos->next) {
|
for (pos = sta->psk; pos; pos = pos->next) {
|
||||||
if (pos->is_passphrase) {
|
if (pos->is_passphrase) {
|
||||||
pbkdf2_sha1(pos->passphrase,
|
pbkdf2_sha1(pos->passphrase,
|
||||||
|
@ -396,10 +398,13 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
|
||||||
}
|
}
|
||||||
if (pos->psk == prev_psk) {
|
if (pos->psk == prev_psk) {
|
||||||
psk = pos->next ? pos->next->psk : NULL;
|
psk = pos->next ? pos->next->psk : NULL;
|
||||||
|
vlan = pos->next ? &pos->next->vlan : NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (vlan_desc && vlan)
|
||||||
|
*vlan_desc = *vlan;
|
||||||
return psk;
|
return psk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,42 +944,40 @@ static void hostapd_clear_ptksa(void *ctx, const u8 *addr, int cipher)
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr, int vlan_id)
|
static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr,
|
||||||
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_NO_VLAN
|
#ifndef CONFIG_NO_VLAN
|
||||||
struct hostapd_data *hapd = ctx;
|
struct hostapd_data *hapd = ctx;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
if (!hostapd_vlan_valid(hapd->conf->vlan, vlan_desc)) {
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"Invalid VLAN ID %d",
|
||||||
|
vlan_desc->untagged);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, addr);
|
sta = ap_get_sta(hapd, addr);
|
||||||
if (!sta)
|
if (!sta)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
|
if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
|
||||||
struct vlan_description vlan_desc;
|
if (ap_sta_set_vlan(hapd, sta, vlan_desc) < 0) {
|
||||||
|
|
||||||
os_memset(&vlan_desc, 0, sizeof(vlan_desc));
|
|
||||||
vlan_desc.notempty = 1;
|
|
||||||
vlan_desc.untagged = vlan_id;
|
|
||||||
if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
|
|
||||||
wpa_printf(MSG_INFO,
|
wpa_printf(MSG_INFO,
|
||||||
"Invalid VLAN ID %d in wpa_psk_file",
|
"Failed to assign VLAN ID %d to "
|
||||||
vlan_id);
|
MACSTR, vlan_desc->untagged,
|
||||||
return -1;
|
MAC2STR(sta->addr));
|
||||||
}
|
|
||||||
|
|
||||||
if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) {
|
|
||||||
wpa_printf(MSG_INFO,
|
|
||||||
"Failed to assign VLAN ID %d from wpa_psk_file to "
|
|
||||||
MACSTR, vlan_id, MAC2STR(sta->addr));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sta->vlan_id = vlan_id;
|
/* TODO: tagged? */
|
||||||
|
sta->vlan_id = vlan_desc->untagged;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_INFO,
|
wpa_printf(MSG_INFO,
|
||||||
"Assigned VLAN ID %d from wpa_psk_file to " MACSTR,
|
"Assigned VLAN ID %d to " MACSTR,
|
||||||
vlan_id, MAC2STR(sta->addr));
|
vlan_desc->untagged, MAC2STR(sta->addr));
|
||||||
if ((sta->flags & WLAN_STA_ASSOC) &&
|
if ((sta->flags & WLAN_STA_ASSOC) &&
|
||||||
ap_sta_bind_vlan(hapd, sta) < 0)
|
ap_sta_bind_vlan(hapd, sta) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1437,6 +1437,11 @@ static int cmp_int(const void *a, const void *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int tag_is_valid(u8 tag) {
|
||||||
|
return 0x1 <= tag && tag <= 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* radius_msg_get_vlanid - Parse RADIUS attributes for VLAN tunnel information
|
* radius_msg_get_vlanid - Parse RADIUS attributes for VLAN tunnel information
|
||||||
* The k tagged vlans found are sorted by vlan_id and stored in the first k
|
* The k tagged vlans found are sorted by vlan_id and stored in the first k
|
||||||
|
@ -1450,7 +1455,7 @@ static int cmp_int(const void *a, const void *b)
|
||||||
* Returns: 0 if neither tagged nor untagged configuration is found, 1 otherwise
|
* Returns: 0 if neither tagged nor untagged configuration is found, 1 otherwise
|
||||||
*/
|
*/
|
||||||
int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
int *tagged)
|
int *tagged, u8 tag)
|
||||||
{
|
{
|
||||||
struct radius_tunnel_attrs tunnel[RADIUS_TUNNEL_TAGS], *tun;
|
struct radius_tunnel_attrs tunnel[RADIUS_TUNNEL_TAGS], *tun;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -1465,6 +1470,11 @@ int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
tagged[j] = 0;
|
tagged[j] = 0;
|
||||||
*untagged = 0;
|
*untagged = 0;
|
||||||
|
|
||||||
|
if (tag_is_valid(tag))
|
||||||
|
tun = &tunnel[tag];
|
||||||
|
else
|
||||||
|
tun = &tunnel[0];
|
||||||
|
|
||||||
for (i = 0; i < msg->attr_used; i++) {
|
for (i = 0; i < msg->attr_used; i++) {
|
||||||
attr = radius_get_attr_hdr(msg, i);
|
attr = radius_get_attr_hdr(msg, i);
|
||||||
if (attr->length < sizeof(*attr))
|
if (attr->length < sizeof(*attr))
|
||||||
|
@ -1473,10 +1483,8 @@ int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
dlen = attr->length - sizeof(*attr);
|
dlen = attr->length - sizeof(*attr);
|
||||||
if (attr->length < 3)
|
if (attr->length < 3)
|
||||||
continue;
|
continue;
|
||||||
if (data[0] >= RADIUS_TUNNEL_TAGS)
|
if (data[0] != tag)
|
||||||
tun = &tunnel[0];
|
continue;
|
||||||
else
|
|
||||||
tun = &tunnel[data[0]];
|
|
||||||
|
|
||||||
switch (attr->type) {
|
switch (attr->type) {
|
||||||
case RADIUS_ATTR_TUNNEL_TYPE:
|
case RADIUS_ATTR_TUNNEL_TYPE:
|
||||||
|
@ -1521,17 +1529,11 @@ int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use tunnel with the lowest tag for untagged VLAN id */
|
if (tun->tag_used &&
|
||||||
for (i = 0; i < RADIUS_TUNNEL_TAGS; i++) {
|
tun->type == RADIUS_TUNNEL_TYPE_VLAN &&
|
||||||
tun = &tunnel[i];
|
tun->medium_type == RADIUS_TUNNEL_MEDIUM_TYPE_802 &&
|
||||||
if (tun->tag_used &&
|
tun->vlanid > 0)
|
||||||
tun->type == RADIUS_TUNNEL_TYPE_VLAN &&
|
*untagged = tun->vlanid;
|
||||||
tun->medium_type == RADIUS_TUNNEL_MEDIUM_TYPE_802 &&
|
|
||||||
tun->vlanid > 0) {
|
|
||||||
*untagged = tun->vlanid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (taggedidx)
|
if (taggedidx)
|
||||||
qsort(tagged, taggedidx, sizeof(int), cmp_int);
|
qsort(tagged, taggedidx, sizeof(int), cmp_int);
|
||||||
|
@ -1554,7 +1556,8 @@ int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
*/
|
*/
|
||||||
char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
||||||
const u8 *secret, size_t secret_len,
|
const u8 *secret, size_t secret_len,
|
||||||
struct radius_msg *sent_msg, size_t n)
|
struct radius_msg *sent_msg, size_t n,
|
||||||
|
u8 *tag)
|
||||||
{
|
{
|
||||||
u8 *buf = NULL;
|
u8 *buf = NULL;
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
|
@ -1572,6 +1575,9 @@ char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
||||||
size_t fdlen = -1;
|
size_t fdlen = -1;
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
|
|
||||||
|
if (tag)
|
||||||
|
*tag = 0;
|
||||||
|
|
||||||
/* find n-th valid Tunnel-Password attribute */
|
/* find n-th valid Tunnel-Password attribute */
|
||||||
for (i = 0; i < msg->attr_used; i++) {
|
for (i = 0; i < msg->attr_used; i++) {
|
||||||
attr = radius_get_attr_hdr(msg, i);
|
attr = radius_get_attr_hdr(msg, i);
|
||||||
|
@ -1589,6 +1595,9 @@ char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
||||||
if (j <= n)
|
if (j <= n)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (tag && tag_is_valid(data[0]))
|
||||||
|
*tag = data[0];
|
||||||
|
|
||||||
fdata = data;
|
fdata = data;
|
||||||
fdlen = dlen;
|
fdlen = dlen;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -294,10 +294,11 @@ radius_msg_add_attr_user_password(struct radius_msg *msg,
|
||||||
const u8 *secret, size_t secret_len);
|
const u8 *secret, size_t secret_len);
|
||||||
int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
|
int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
|
||||||
int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged,
|
||||||
int *tagged);
|
int *tagged, u8 tag);
|
||||||
char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
|
||||||
const u8 *secret, size_t secret_len,
|
const u8 *secret, size_t secret_len,
|
||||||
struct radius_msg *sent_msg, size_t n);
|
struct radius_msg *sent_msg, size_t n,
|
||||||
|
u8 *tag);
|
||||||
|
|
||||||
static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
|
static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
|
||||||
u32 value)
|
u32 value)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "utils/eloop.h"
|
#include "utils/eloop.h"
|
||||||
#include "ap/wpa_auth.h"
|
#include "ap/wpa_auth.h"
|
||||||
|
#include "ap/vlan.h"
|
||||||
#include "../fuzzer-common.h"
|
#include "../fuzzer-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,14 +142,14 @@ static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
|
||||||
|
|
||||||
static const u8 * auth_get_psk(void *ctx, const u8 *addr,
|
static const u8 * auth_get_psk(void *ctx, const u8 *addr,
|
||||||
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
||||||
size_t *psk_len, int *vlan_id)
|
size_t *psk_len, struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
struct wpa *wpa = ctx;
|
struct wpa *wpa = ctx;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
||||||
__func__, MAC2STR(addr), prev_psk);
|
__func__, MAC2STR(addr), prev_psk);
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
if (psk_len)
|
if (psk_len)
|
||||||
*psk_len = PMK_LEN;
|
*psk_len = PMK_LEN;
|
||||||
if (prev_psk)
|
if (prev_psk)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "common/ieee802_11_defs.h"
|
#include "common/ieee802_11_defs.h"
|
||||||
|
#include "ap/vlan.h"
|
||||||
#include "ibss_rsn.h"
|
#include "ibss_rsn.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,14 +275,15 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
|
||||||
|
|
||||||
static const u8 * auth_get_psk(void *ctx, const u8 *addr,
|
static const u8 * auth_get_psk(void *ctx, const u8 *addr,
|
||||||
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
||||||
size_t *psk_len, int *vlan_id)
|
size_t *psk_len,
|
||||||
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
struct ibss_rsn *ibss_rsn = ctx;
|
struct ibss_rsn *ibss_rsn = ctx;
|
||||||
|
|
||||||
if (psk_len)
|
if (psk_len)
|
||||||
*psk_len = PMK_LEN;
|
*psk_len = PMK_LEN;
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
||||||
__func__, MAC2STR(addr), prev_psk);
|
__func__, MAC2STR(addr), prev_psk);
|
||||||
if (prev_psk)
|
if (prev_psk)
|
||||||
|
|
|
@ -76,7 +76,8 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
|
||||||
|
|
||||||
static const u8 *auth_get_psk(void *ctx, const u8 *addr,
|
static const u8 *auth_get_psk(void *ctx, const u8 *addr,
|
||||||
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
const u8 *p2p_dev_addr, const u8 *prev_psk,
|
||||||
size_t *psk_len, int *vlan_id)
|
size_t *psk_len,
|
||||||
|
struct vlan_description *vlan_desc)
|
||||||
{
|
{
|
||||||
struct mesh_rsn *mesh_rsn = ctx;
|
struct mesh_rsn *mesh_rsn = ctx;
|
||||||
struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
|
struct hostapd_data *hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
|
||||||
|
@ -84,8 +85,8 @@ static const u8 *auth_get_psk(void *ctx, const u8 *addr,
|
||||||
|
|
||||||
if (psk_len)
|
if (psk_len)
|
||||||
*psk_len = PMK_LEN;
|
*psk_len = PMK_LEN;
|
||||||
if (vlan_id)
|
if (vlan_desc)
|
||||||
*vlan_id = 0;
|
os_memset(vlan_desc, 0, sizeof(*vlan_desc));
|
||||||
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
||||||
__func__, MAC2STR(addr), prev_psk);
|
__func__, MAC2STR(addr), prev_psk);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue