[PATCH 1 5/5] SUNRPC: Consider qop when looking up pseudoflavors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A list of GSS tuples are returned in response to a SECINFO request.
The client is supposed to pick a pseudoflavor it supports that
corresponds to one of the tuples returned by the server.

Currently we ignore a GSS tuple's "qop" value.  A pseudoflavor is
chosen based on the OID and service.  NFSv4 appears to support
only one qop value: zero.  So this omission has not had much effect.

However, if a server returns something other than zero in that
field, we won't catch it, and may behave in incorrect or unexpected
ways.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---

 include/linux/sunrpc/gss_api.h        |    2 ++
 net/sunrpc/auth_gss/gss_krb5_mech.c   |    3 +++
 net/sunrpc/auth_gss/gss_mech_switch.c |   22 +++++++++++++++++++++-
 3 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index a7bbe96..7daacea 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -26,6 +26,7 @@ struct gss_ctx {
 #define GSS_C_NO_BUFFER		((struct xdr_netobj) 0)
 #define GSS_C_NO_CONTEXT	((struct gss_ctx *) 0)
 #define GSS_C_NULL_OID		((struct xdr_netobj) 0)
+#define GSS_C_QOP_DEFAULT	(0)
 
 /* RPCSEC_GSS services, from RFC 2203, section 5 */
 enum rpc_gss_svc {
@@ -82,6 +83,7 @@ char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
 
 struct pf_desc {
 	u32	pseudoflavor;
+	u32	qop;
 	u32	service;
 	char	*name;
 	char	*auth_domain_name;
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 8b1005d..9d99f3a 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -729,16 +729,19 @@ static const struct gss_api_ops gss_kerberos_ops = {
 static struct pf_desc gss_kerberos_pfs[] = {
 	[0] = {
 		.pseudoflavor = RPC_AUTH_GSS_KRB5,
+		.qop = GSS_C_QOP_DEFAULT,
 		.service = RPC_GSS_SVC_NONE,
 		.name = "krb5",
 	},
 	[1] = {
 		.pseudoflavor = RPC_AUTH_GSS_KRB5I,
+		.qop = GSS_C_QOP_DEFAULT,
 		.service = RPC_GSS_SVC_INTEGRITY,
 		.name = "krb5i",
 	},
 	[2] = {
 		.pseudoflavor = RPC_AUTH_GSS_KRB5P,
+		.qop = GSS_C_QOP_DEFAULT,
 		.service = RPC_GSS_SVC_PRIVACY,
 		.name = "krb5p",
 	},
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 64dbf07a..731e298 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -285,6 +285,25 @@ gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service)
 }
 EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor);
 
+/*
+ * Same as gss_svc_to_pseudoflavor, but includes a search on the qop
+ * as well.
+ */
+static rpc_authflavor_t gss_qop_svc_to_pseudoflavor(struct gss_api_mech *gm,
+	u32 qop, u32 service)
+{
+	int i;
+
+	for (i = 0; i < gm->gm_pf_num; i++) {
+		if (gm->gm_pfs[i].qop == qop &&
+		    gm->gm_pfs[i].service == service) {
+			return gm->gm_pfs[i].pseudoflavor;
+		}
+	}
+
+	return RPC_AUTH_MAXFLAVOR;
+}
+
 /**
  * gss_mech_lookup_pseudoflavor - look up a pseudoflavor given a GSS tuple
  * @info: a GSS mech OID, quality of protection, and service value
@@ -301,7 +320,8 @@ rpc_authflavor_t gss_mech_lookup_pseudoflavor(struct rpcsec_gss_info *info)
 	if (mech == NULL)
 		return RPC_AUTH_MAXFLAVOR;
 
-	pseudoflavor = gss_svc_to_pseudoflavor(mech, info->service);
+	pseudoflavor = gss_qop_svc_to_pseudoflavor(mech,
+					info->qop, info->service);
 
 	gss_mech_put(mech);
 	return pseudoflavor;

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux