svn commit: r357152 - projects/nfs-over-tls/sys/rpc
Rick Macklem
rmacklem at FreeBSD.org
Sun Jan 26 18:43:33 UTC 2020
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
More information about the svn-src-projects
mailing list