Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 179d3dea authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "nl80211: Allow SAE Authentication for NL80211_CMD_CONNECT"

parents 3f574e52 bc3bb8a2
Loading
Loading
Loading
Loading
+51 −3
Original line number Diff line number Diff line
@@ -1900,11 +1900,16 @@ struct cfg80211_auth_request {
 * @ASSOC_REQ_DISABLE_HT:  Disable HT (802.11n)
 * @ASSOC_REQ_DISABLE_VHT:  Disable VHT
 * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
 * @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
 *	authentication capability. Drivers can offload authentication to
 *	userspace if this flag is set. Only applicable for cfg80211_connect()
 *	request (connect callback).
 */
enum cfg80211_assoc_req_flags {
	ASSOC_REQ_DISABLE_HT			= BIT(0),
	ASSOC_REQ_DISABLE_VHT			= BIT(1),
	ASSOC_REQ_USE_RRM			= BIT(2),
	CONNECT_REQ_EXTERNAL_AUTH_SUPPORT	= BIT(3),
};

/**
@@ -2590,6 +2595,33 @@ struct cfg80211_pmk_conf {
	const u8 *pmk_r0_name;
};

/**
 * struct cfg80211_external_auth_params - Trigger External authentication.
 *
 * Commonly used across the external auth request and event interfaces.
 *
 * @action: action type / trigger for external authentication. Only significant
 *	for the authentication request event interface (driver to user space).
 * @bssid: BSSID of the peer with which the authentication has
 *	to happen. Used by both the authentication request event and
 *	authentication response command interface.
 * @ssid: SSID of the AP.  Used by both the authentication request event and
 *	authentication response command interface.
 * @key_mgmt_suite: AKM suite of the respective authentication. Used by the
 *	authentication request event interface.
 * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
 *	use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
 *	the real status code for failures. Used only for the authentication
 *	response command interface (user space to driver).
 */
struct cfg80211_external_auth_params {
	enum nl80211_external_auth_action action;
	u8 bssid[ETH_ALEN] __aligned(2);
	struct cfg80211_ssid ssid;
	unsigned int key_mgmt_suite;
	u16 status;
};

/**
 * struct cfg80211_ops - backend description for wireless configuration
 *
@@ -2913,6 +2945,9 @@ struct cfg80211_pmk_conf {
 *	(invoked with the wireless_dev mutex held)
 * @del_pmk: delete the previously configured PMK for the given authenticator.
 *	(invoked with the wireless_dev mutex held)
 *
 * @external_auth: indicates result of offloaded authentication processing from
 *     user space
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3206,6 +3241,8 @@ struct cfg80211_ops {
			   const struct cfg80211_pmk_conf *conf);
	int	(*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
			   const u8 *aa);
	int     (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
				 struct cfg80211_external_auth_params *params);
};

/*
@@ -6236,6 +6273,17 @@ void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 */
bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb);

/**
 * cfg80211_external_auth_request - userspace request for authentication
 * @netdev: network device
 * @params: External authentication parameters
 * @gfp: allocation flags
 * Returns: 0 on success, < 0 on error
 */
int cfg80211_external_auth_request(struct net_device *netdev,
				   struct cfg80211_external_auth_params *params,
				   gfp_t gfp);

/* Logging, debugging and troubleshooting/diagnostic helpers. */

/* wiphy_printk helpers, similar to dev_printk */
+47 −0
Original line number Diff line number Diff line
@@ -992,6 +992,27 @@
 * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
 *
 *
 * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
 *	drivers that do not define separate commands for authentication and
 *	association, but rely on user space for the authentication to happen.
 *	This interface acts both as the event request (driver to user space)
 *	to trigger the authentication and command response (userspace to
 *	driver) to indicate the authentication status.
 *
 *	User space uses the %NL80211_CMD_CONNECT command to the host driver to
 *	trigger a connection. The host driver selects a BSS and further uses
 *	this interface to offload only the authentication part to the user
 *	space. Authentication frames are passed between the driver and user
 *	space through the %NL80211_CMD_FRAME interface. Host driver proceeds
 *	further with the association after getting successful authentication
 *	status. User space indicates the authentication status through
 *	%NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
 *	command interface.
 *
 *	Host driver reports this status on an authentication failure to the
 *	user space through the connect result as the user space would have
 *	initiated the connection through the connect request.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -1198,6 +1219,8 @@ enum nl80211_commands {

	NL80211_CMD_RELOAD_REGDB,

	NL80211_CMD_EXTERNAL_AUTH,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
@@ -2156,6 +2179,16 @@ enum nl80211_commands {
 *	the driver or is not needed (because roaming used the Fast Transition
 *	protocol).
 *
 * @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
 *     authentication operation (u32 attribute with an
 *     &enum nl80211_external_auth_action value). This is used with the
 *     &NL80211_CMD_EXTERNAL_AUTH request event.
 * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
 *     space supports external authentication. This attribute shall be used
 *     only with %NL80211_CMD_CONNECT request. The driver may offload
 *     authentication processing to user space if this capability is indicated
 *     in NL80211_CMD_CONNECT requests from the user space.
 *
 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2582,6 +2615,9 @@ enum nl80211_attrs {
	NL80211_ATTR_PMKR0_NAME,
	NL80211_ATTR_PORT_AUTHORIZED,

	NL80211_ATTR_EXTERNAL_AUTH_ACTION,
	NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,

	/* add attributes here, update the policy in nl80211.c */

	__NL80211_ATTR_AFTER_LAST,
@@ -5503,4 +5539,15 @@ enum nl80211_nan_match_attributes {
	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
};

/**
 * nl80211_external_auth_action - Action to perform with external
 *     authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
 * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
 * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
 */
enum nl80211_external_auth_action {
	NL80211_EXTERNAL_AUTH_START,
	NL80211_EXTERNAL_AUTH_ABORT,
};

#endif /* __LINUX_NL80211_H */
+95 −2
Original line number Diff line number Diff line
@@ -421,6 +421,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
	[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
	[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
	[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
	[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
};

/* policy for the key attributes */
@@ -3863,9 +3864,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
			return false;
		return true;
	case NL80211_CMD_CONNECT:
		/* SAE not supported yet */
		if (auth_type == NL80211_AUTHTYPE_SAE)
		if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
		    auth_type == NL80211_AUTHTYPE_SAE)
			return false;

		/* FILS with SK PFS or PK not supported yet */
		if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
		    auth_type == NL80211_AUTHTYPE_FILS_PK)
@@ -9101,6 +9103,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
		return -EINVAL;
	}

	if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
		if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
			return -EINVAL;
		}
		connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
	}

	wdev_lock(dev->ieee80211_ptr);

	err = cfg80211_connect(rdev, dev, &connect, connkeys,
@@ -12409,6 +12418,41 @@ static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
	return ret;
}

static int nl80211_external_auth(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 cfg80211_external_auth_params params;

	if (rdev->ops->external_auth)
		return -EOPNOTSUPP;

	if (!info->attrs[NL80211_ATTR_SSID])
		return -EINVAL;

	if (!info->attrs[NL80211_ATTR_BSSID])
		return -EINVAL;

	if (!info->attrs[NL80211_ATTR_STATUS_CODE])
		return -EINVAL;

	memset(&params, 0, sizeof(params));

	params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
	if (params.ssid.ssid_len == 0 ||
	    params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;
	memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
	       params.ssid.ssid_len);

	memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
	       ETH_ALEN);

	params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);

	return rdev_external_auth(rdev, dev, &params);
}

#define NL80211_FLAG_NEED_WIPHY		0x01
#define NL80211_FLAG_NEED_NETDEV	0x02
#define NL80211_FLAG_NEED_RTNL		0x04
@@ -13298,6 +13342,14 @@ static const struct genl_ops nl80211_ops[] = {
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_EXTERNAL_AUTH,
		.doit = nl80211_external_auth,
		.policy = nl80211_policy,
		.flags = GENL_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},

};

@@ -15292,6 +15344,47 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev)
	nlmsg_free(msg);
}

int cfg80211_external_auth_request(struct net_device *dev,
				   struct cfg80211_external_auth_params *params,
				   gfp_t gfp)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct sk_buff *msg;
	void *hdr;

	if (!wdev->conn_owner_nlportid)
		return -EINVAL;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
	if (!msg)
		return -ENOMEM;

	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
	if (!hdr)
		goto nla_put_failure;

	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
	    nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
	    nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
			params->action) ||
	    nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
	    nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
		    params->ssid.ssid))
		goto nla_put_failure;

	genlmsg_end(msg, hdr);
	genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
			wdev->conn_owner_nlportid);
	return 0;

 nla_put_failure:
	nlmsg_free(msg);
	return -ENOBUFS;
}
EXPORT_SYMBOL(cfg80211_external_auth_request);

/* initialisation/exit functions */

int __init nl80211_init(void)
+15 −0
Original line number Diff line number Diff line
@@ -1190,4 +1190,19 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
	trace_rdev_return_int(&rdev->wiphy, ret);
	return ret;
}

static inline int
rdev_external_auth(struct cfg80211_registered_device *rdev,
		   struct net_device *dev,
		   struct cfg80211_external_auth_params *params)
{
	int ret = -EOPNOTSUPP;

	trace_rdev_external_auth(&rdev->wiphy, dev, params);
	if (rdev->ops->external_auth)
		ret = rdev->ops->external_auth(&rdev->wiphy, dev, params);
	trace_rdev_return_int(&rdev->wiphy, ret);
	return ret;
}

#endif /* __CFG80211_RDEV_OPS */
+23 −0
Original line number Diff line number Diff line
@@ -2319,6 +2319,29 @@ TRACE_EVENT(rdev_del_pmk,
		  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
);

TRACE_EVENT(rdev_external_auth,
	    TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
		     struct cfg80211_external_auth_params *params),
	    TP_ARGS(wiphy, netdev, params),
	    TP_STRUCT__entry(WIPHY_ENTRY
			     NETDEV_ENTRY
			     MAC_ENTRY(bssid)
			     __array(u8, ssid, IEEE80211_MAX_SSID_LEN + 1)
			     __field(u16, status)
	    ),
	    TP_fast_assign(WIPHY_ASSIGN;
			   NETDEV_ASSIGN;
			   MAC_ASSIGN(bssid, params->bssid);
			   memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
			   memcpy(__entry->ssid, params->ssid.ssid,
				  params->ssid.ssid_len);
			   __entry->status = params->status;
	    ),
	    TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
		      ", ssid: %s, status: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
		      __entry->bssid, __entry->ssid, __entry->status)
);

/*************************************************************
 *	     cfg80211 exported functions traces		     *
 *************************************************************/