Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jan 2020 18:43:31 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r357152 - projects/nfs-over-tls/sys/rpc
Message-ID:  <202001261843.00QIhV4l061824@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sun Jan 26 18:43:31 2020
New Revision: 357152
URL: https://svnweb.freebsd.org/changeset/base/357152

Log:
  Patch the kernel RPC files for handling RPC-over-TLS.

Modified:
  projects/nfs-over-tls/sys/rpc/auth.h
  projects/nfs-over-tls/sys/rpc/clnt.h
  projects/nfs-over-tls/sys/rpc/clnt_rc.c
  projects/nfs-over-tls/sys/rpc/clnt_stat.h
  projects/nfs-over-tls/sys/rpc/clnt_vc.c
  projects/nfs-over-tls/sys/rpc/krpc.h
  projects/nfs-over-tls/sys/rpc/svc.h
  projects/nfs-over-tls/sys/rpc/svc_auth.c
  projects/nfs-over-tls/sys/rpc/svc_vc.c

Modified: projects/nfs-over-tls/sys/rpc/auth.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/auth.h	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/auth.h	Sun Jan 26 18:43:31 2020	(r357152)
@@ -150,6 +150,7 @@ enum auth_stat {
 	 */
 	RPCSEC_GSS_CREDPROBLEM = 13,
 	RPCSEC_GSS_CTXPROBLEM = 14,
+	/* Also used by RPCSEC_TLS for the same purpose */
 	RPCSEC_GSS_NODISPATCH = 0x8000000
 };
 
@@ -249,6 +250,7 @@ extern AUTH *authunix_create(char *, u_int, u_int, int
 extern AUTH *authunix_create_default(void);	/* takes no parameters */
 #endif
 extern AUTH *authnone_create(void);		/* takes no parameters */
+extern AUTH *authtls_create(void);		/* takes no parameters */
 __END_DECLS
 /*
  * DES style authentication
@@ -344,6 +346,7 @@ struct rpc_msg;
 enum auth_stat _svcauth_null (struct svc_req *, struct rpc_msg *);
 enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *);
 enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *);
+enum auth_stat _svcauth_rpcsec_tls (struct svc_req *, struct rpc_msg *);
 __END_DECLS
 
 #define AUTH_NONE	0		/* no authentication */
@@ -355,6 +358,7 @@ __END_DECLS
 #define AUTH_DES	AUTH_DH		/* for backward compatibility */
 #define AUTH_KERB	4		/* kerberos style */
 #define RPCSEC_GSS	6		/* RPCSEC_GSS */
+#define	AUTH_TLS	7		/* Initiate RPC-over-TLS */
 
 /*
  * Pseudo auth flavors for RPCSEC_GSS.

Modified: projects/nfs-over-tls/sys/rpc/clnt.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt.h	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/clnt.h	Sun Jan 26 18:43:31 2020	(r357152)
@@ -357,6 +357,8 @@ enum clnt_stat clnt_call_private(CLIENT *, struct rpc_
 #define CLSET_PRIVPORT		27	/* set privileged source port flag */
 #define CLGET_PRIVPORT		28	/* get privileged source port flag */
 #define CLSET_BACKCHANNEL	29	/* set backchannel for socket */
+#define	CLSET_TLS		30	/* set TLS for socket */
+#define	CLSET_BLOCKRCV		31	/* Temporarily block reception */
 #endif
 
 

Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_rc.c	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/clnt_rc.c	Sun Jan 26 18:43:31 2020	(r357152)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <rpc/rpc.h>
 #include <rpc/rpc_com.h>
 #include <rpc/krpc.h>
+#include <rpc/rpcsec_tls.h>
 
 static enum clnt_stat clnt_reconnect_call(CLIENT *, struct rpc_callextra *,
     rpcproc_t, struct mbuf *, struct mbuf **, struct timeval);
@@ -193,6 +194,24 @@ clnt_reconnect_connect(CLIENT *cl)
 		newclient = clnt_vc_create(so,
 		    (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers,
 		    rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr);
+		if (rc->rc_tls != 0 && newclient != NULL) {
+printf("at rpctls_connect\n");
+			stat = rpctls_connect(newclient, so);
+printf("aft rpctls_connect=%d\n", stat);
+			if (stat != RPC_SUCCESS) {
+				if (stat != RPC_SYSTEMERROR)
+					stat = rpc_createerr.cf_stat =
+					    RPC_TLSCONNECT;
+				else
+					stat = rpc_createerr.cf_stat = stat;
+				rpc_createerr.cf_error.re_errno = 0;
+				CLNT_CLOSE(newclient);
+				CLNT_RELEASE(newclient);
+				newclient = NULL;
+				td->td_ucred = oldcred;
+				goto out;
+			}
+		}
 	}
 	td->td_ucred = oldcred;
 
@@ -470,6 +489,10 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void
 		xprt = (SVCXPRT *)info;
 		xprt_register(xprt);
 		rc->rc_backchannel = info;
+		break;
+
+	case CLSET_TLS:
+		rc->rc_tls = 1;
 		break;
 
 	default:

Modified: projects/nfs-over-tls/sys/rpc/clnt_stat.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_stat.h	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/clnt_stat.h	Sun Jan 26 18:43:31 2020	(r357152)
@@ -73,7 +73,11 @@ enum clnt_stat {
 	RPC_STALERACHANDLE = 25,
 	RPC_CANTCONNECT = 26,		/* couldn't make connection (cots) */
 	RPC_XPRTFAILED = 27,		/* received discon from remote (cots) */
-	RPC_CANTCREATESTREAM = 28	/* can't push rpc module (cots) */
+	RPC_CANTCREATESTREAM = 28,	/* can't push rpc module (cots) */
+	/*
+	 * TLS errors
+	 */
+	RPC_TLSCONNECT = 29		/* can't do TLS handshake */
 };
 
 #ifdef __cplusplus

Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/clnt_vc.c	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/clnt_vc.c	Sun Jan 26 18:43:31 2020	(r357152)
@@ -733,6 +733,13 @@ clnt_vc_control(CLIENT *cl, u_int request, void *info)
 		}
 		break;
 
+	case CLSET_BLOCKRCV:
+		if (*(int *) info)
+			ct->ct_dontrcv = TRUE;
+		else
+			ct->ct_dontrcv = FALSE;
+		break;
+
 	default:
 		mtx_unlock(&ct->ct_lock);
 		return (FALSE);
@@ -859,6 +866,15 @@ clnt_vc_soupcall(struct socket *so, void *arg, int wai
 	struct cf_conn *cd;
 
 	CTASSERT(sizeof(xid_plus_direction) == 2 * sizeof(uint32_t));
+
+	/* RPC-over-TLS needs to block reception during handshake upcall. */
+	mtx_lock(&ct->ct_lock);
+	if (ct->ct_dontrcv) {
+		mtx_unlock(&ct->ct_lock);
+		return (SU_OK);
+	}
+	mtx_unlock(&ct->ct_lock);
+
 	ct->ct_upcallrefs++;
 	uio.uio_td = curthread;
 	do {

Modified: projects/nfs-over-tls/sys/rpc/krpc.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/krpc.h	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/krpc.h	Sun Jan 26 18:43:31 2020	(r357152)
@@ -78,6 +78,7 @@ struct rc_data {
 	CLIENT*			rc_client; /* underlying RPC client */
 	struct rpc_err		rc_err;
 	void			*rc_backchannel;
+	int			rc_tls;	/* Enable TLS on connection */
 };
 
 struct ct_data {
@@ -101,6 +102,7 @@ struct ct_data {
 	struct ct_request_list ct_pending;
 	int		ct_upcallrefs;	/* Ref cnt of upcalls in prog. */
 	SVCXPRT		*ct_backchannelxprt; /* xprt for backchannel */
+	bool_t		ct_dontrcv;	/* TRUE to block receiving */
 };
 
 struct cf_conn {  /* kept in xprt->xp_p1 for actual connection */

Modified: projects/nfs-over-tls/sys/rpc/svc.h
==============================================================================
--- projects/nfs-over-tls/sys/rpc/svc.h	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/svc.h	Sun Jan 26 18:43:31 2020	(r357152)
@@ -175,6 +175,7 @@ typedef struct __rpc_svcxprt {
 	int		xp_upcallset;	/* socket upcall is set up */
 	uint32_t	xp_snd_cnt;	/* # of bytes to send to socket */
 	uint32_t	xp_snt_cnt;	/* # of bytes sent to socket */
+	bool_t		xp_dontrcv;	/* Do not receive on the socket */
 #else
 	int		xp_fd;
 	u_short		xp_port;	 /* associated port number */

Modified: projects/nfs-over-tls/sys/rpc/svc_auth.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/svc_auth.c	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/svc_auth.c	Sun Jan 26 18:43:31 2020	(r357152)
@@ -104,6 +104,9 @@ _authenticate(struct svc_req *rqst, struct rpc_msg *ms
 			return (AUTH_REJECTEDCRED);
 		dummy = _svcauth_rpcsec_gss(rqst, msg);
 		return (dummy);
+	case AUTH_TLS:
+		dummy = _svcauth_rpcsec_tls(rqst, msg);
+		return (dummy);
 	default:
 		break;
 	}

Modified: projects/nfs-over-tls/sys/rpc/svc_vc.c
==============================================================================
--- projects/nfs-over-tls/sys/rpc/svc_vc.c	Sun Jan 26 18:05:46 2020	(r357151)
+++ projects/nfs-over-tls/sys/rpc/svc_vc.c	Sun Jan 26 18:43:31 2020	(r357152)
@@ -732,6 +732,15 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg,
 		}
 
 		/*
+		 * If receiving is disabled so that a TLS handshake can be
+		 * done by the rpctlssd daemon, return FALSE here.
+		 */
+		if (xprt->xp_dontrcv) {
+			sx_xunlock(&xprt->xp_lock);
+			return (FALSE);
+		}
+
+		/*
 		 * The socket upcall calls xprt_active() which will eventually
 		 * cause the server to call us here. We attempt to
 		 * read as much as possible from the socket and put



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001261843.00QIhV4l061824>