@ -23,7 +23,6 @@
# include "nl80211.h"
# include "reg.h"
static bool nl80211_valid_auth_type ( enum nl80211_auth_type auth_type ) ;
static int nl80211_crypto_settings ( struct cfg80211_registered_device * rdev ,
struct genl_info * info ,
struct cfg80211_crypto_settings * settings ,
@ -355,6 +354,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[ NL80211_ATTR_BG_SCAN_PERIOD ] = { . type = NLA_U16 } ,
[ NL80211_ATTR_WDEV ] = { . type = NLA_U64 } ,
[ NL80211_ATTR_USER_REG_HINT_TYPE ] = { . type = NLA_U32 } ,
[ NL80211_ATTR_SAE_DATA ] = { . type = NLA_BINARY , } ,
} ;
/* policy for the key attributes */
@ -2490,6 +2490,30 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
return ret ;
}
static bool nl80211_valid_auth_type ( struct cfg80211_registered_device * rdev ,
enum nl80211_auth_type auth_type ,
enum nl80211_commands cmd )
{
if ( auth_type > NL80211_AUTHTYPE_MAX )
return false ;
switch ( cmd ) {
case NL80211_CMD_AUTHENTICATE :
if ( ! ( rdev - > wiphy . features & NL80211_FEATURE_SAE ) & &
auth_type = = NL80211_AUTHTYPE_SAE )
return false ;
return true ;
case NL80211_CMD_CONNECT :
case NL80211_CMD_START_AP :
/* SAE not supported yet */
if ( auth_type = = NL80211_AUTHTYPE_SAE )
return false ;
return true ;
default :
return false ;
}
}
static int nl80211_start_ap ( struct sk_buff * skb , struct genl_info * info )
{
struct cfg80211_registered_device * rdev = info - > user_ptr [ 0 ] ;
@ -2559,7 +2583,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
if ( info - > attrs [ NL80211_ATTR_AUTH_TYPE ] ) {
params . auth_type = nla_get_u32 (
info - > attrs [ NL80211_ATTR_AUTH_TYPE ] ) ;
if ( ! nl80211_valid_auth_type ( params . auth_type ) )
if ( ! nl80211_valid_auth_type ( rdev , params . auth_type ,
NL80211_CMD_START_AP ) )
return - EINVAL ;
} else
params . auth_type = NL80211_AUTHTYPE_AUTOMATIC ;
@ -4852,11 +4877,6 @@ static int nl80211_dump_survey(struct sk_buff *skb,
return res ;
}
static bool nl80211_valid_auth_type ( enum nl80211_auth_type auth_type )
{
return auth_type < = NL80211_AUTHTYPE_MAX ;
}
static bool nl80211_valid_wpa_versions ( u32 wpa_versions )
{
return ! ( wpa_versions & ~ ( NL80211_WPA_VERSION_1 |
@ -4868,8 +4888,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device * rdev = info - > user_ptr [ 0 ] ;
struct net_device * dev = info - > user_ptr [ 1 ] ;
struct ieee80211_channel * chan ;
const u8 * bssid , * ssid , * ie = NULL ;
int err , ssid_len , ie_len = 0 ;
const u8 * bssid , * ssid , * ie = NULL , * sae_data = NULL ;
int err , ssid_len , ie_len = 0 , sae_data_len = 0 ;
enum nl80211_auth_type auth_type ;
struct key_parse key ;
bool local_state_change ;
@ -4945,9 +4965,23 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
}
auth_type = nla_get_u32 ( info - > attrs [ NL80211_ATTR_AUTH_TYPE ] ) ;
if ( ! nl80211_valid_auth_type ( auth_type ) )
if ( ! nl80211_valid_auth_type ( rdev , auth_type , NL80211_CMD_AUTHENTICATE ) )
return - EINVAL ;
if ( auth_type = = NL80211_AUTHTYPE_SAE & &
! info - > attrs [ NL80211_ATTR_SAE_DATA ] )
return - EINVAL ;
if ( info - > attrs [ NL80211_ATTR_SAE_DATA ] ) {
if ( auth_type ! = NL80211_AUTHTYPE_SAE )
return - EINVAL ;
sae_data = nla_data ( info - > attrs [ NL80211_ATTR_SAE_DATA ] ) ;
sae_data_len = nla_len ( info - > attrs [ NL80211_ATTR_SAE_DATA ] ) ;
/* need to include at least Auth Transaction and Status Code */
if ( sae_data_len < 4 )
return - EINVAL ;
}
local_state_change = ! ! info - > attrs [ NL80211_ATTR_LOCAL_STATE_CHANGE ] ;
/*
@ -4959,7 +4993,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
return cfg80211_mlme_auth ( rdev , dev , chan , auth_type , bssid ,
ssid , ssid_len , ie , ie_len ,
key . p . key , key . p . key_len , key . idx ) ;
key . p . key , key . p . key_len , key . idx ,
sae_data , sae_data_len ) ;
}
static int nl80211_crypto_settings ( struct cfg80211_registered_device * rdev ,
@ -5596,7 +5631,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
if ( info - > attrs [ NL80211_ATTR_AUTH_TYPE ] ) {
connect . auth_type =
nla_get_u32 ( info - > attrs [ NL80211_ATTR_AUTH_TYPE ] ) ;
if ( ! nl80211_valid_auth_type ( connect . auth_type ) )
if ( ! nl80211_valid_auth_type ( rdev , connect . auth_type ,
NL80211_CMD_CONNECT ) )
return - EINVAL ;
} else
connect . auth_type = NL80211_AUTHTYPE_AUTOMATIC ;