Date: Sun, 17 May 2020 20:37:15 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r361141 - in projects/nfs-over-tls: sys/rpc sys/rpc/rpcsec_tls usr.sbin/rpctlscd usr.sbin/rpctlssd Message-ID: <202005172037.04HKbF2p087253@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun May 17 20:37:15 2020 New Revision: 361141 URL: https://svnweb.freebsd.org/changeset/base/361141 Log: Separate errors doing the rpctlscd/rpctlssd upcalls from RPC errors. Without this patch, the RPC layer errors were being overloaded and used to indicate failures in the upcalls in the daemons, usually RPC_FAILED. This patch separates the error returns from the upcalls into a separate returned value called "reterr". This cleans up the code, but does not really change any semantics. Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c projects/nfs-over-tls/sys/rpc/clnt_vc.c projects/nfs-over-tls/sys/rpc/rpcsec_tls.h projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlscd.x projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlssd.x projects/nfs-over-tls/sys/rpc/svc_vc.c projects/nfs-over-tls/usr.sbin/rpctlscd/rpctlscd.c projects/nfs-over-tls/usr.sbin/rpctlssd/rpctlssd.c Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_rc.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/clnt_rc.c Sun May 17 20:37:15 2020 (r361141) @@ -132,6 +132,7 @@ clnt_reconnect_connect(CLIENT *cl) struct ucred *oldcred; CLIENT *newclient = NULL; uint64_t ssl[3]; + uint32_t reterr; mtx_lock(&rc->rc_lock); while (rc->rc_connecting) { @@ -198,9 +199,11 @@ clnt_reconnect_connect(CLIENT *cl) rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); if (rc->rc_tls && newclient != NULL) { printf("at rpctls_connect\n"); - stat = rpctls_connect(newclient, so, ssl); + stat = rpctls_connect(newclient, so, ssl, &reterr); printf("aft rpctls_connect=%d ssl=%jd\n", stat, (uintmax_t)ssl[2]); - if (stat != RPC_SUCCESS) { + if (stat != RPC_SUCCESS || reterr != RPCTLSERR_OK) { + if (stat == RPC_SUCCESS) + stat = RPC_FAILED; stat = rpc_createerr.cf_stat = stat; rpc_createerr.cf_error.re_errno = 0; CLNT_CLOSE(newclient); @@ -282,6 +285,7 @@ clnt_reconnect_call( if (!rc->rc_client) { mtx_unlock(&rc->rc_lock); stat = clnt_reconnect_connect(cl); +printf("reconnect_connect=%d\n", stat); if (stat == RPC_SYSTEMERROR) { error = tsleep(&fake_wchan, rc->rc_intr ? PCATCH : 0, "rpccon", hz); @@ -307,6 +311,7 @@ clnt_reconnect_call( mtx_unlock(&rc->rc_lock); stat = CLNT_CALL_MBUF(client, ext, proc, args, resultsp, utimeout); +if (stat != RPC_SUCCESS) printf("clnt_reconnect_call=%d\n", stat); if (stat != RPC_SUCCESS) { if (!ext) Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_vc.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/clnt_vc.c Sun May 17 20:37:15 2020 (r361141) @@ -875,6 +875,7 @@ clnt_vc_destroy(CLIENT *cl) struct socket *so = NULL; SVCXPRT *xprt; enum clnt_stat stat; + uint32_t reterr; clnt_vc_close(cl); @@ -900,10 +901,12 @@ clnt_vc_destroy(CLIENT *cl) mtx_destroy(&ct->ct_lock); if (so) { stat = RPC_FAILED; + reterr = RPCTLSERR_OK; if (ct->ct_sslrefno != 0) stat = rpctls_cl_disconnect(ct->ct_sslsec, - ct->ct_sslusec, ct->ct_sslrefno); - if (stat != RPC_SUCCESS) { + ct->ct_sslusec, ct->ct_sslrefno, + &reterr); + if (stat != RPC_SUCCESS || reterr == RPCTLSERR_NOCLOSE) { soshutdown(so, SHUT_WR); soclose(so); } @@ -1283,15 +1286,16 @@ static void clnt_vc_dotlsupcall(struct ct_data *ct) { enum clnt_stat ret; + uint32_t reterr; mtx_assert(&ct->ct_lock, MA_OWNED); if (ct->ct_rcvstate == UPCALLNEEDED) { ct->ct_rcvstate = UPCALLINPROG; mtx_unlock(&ct->ct_lock); ret = rpctls_cl_handlerecord(ct->ct_sslsec, ct->ct_sslusec, - ct->ct_sslrefno); + ct->ct_sslrefno, &reterr); mtx_lock(&ct->ct_lock); - if (ret == RPC_SUCCESS) + if (ret == RPC_SUCCESS && reterr == RPCTLSERR_OK) ct->ct_rcvstate = RCVNORMAL; else ct->ct_rcvstate = RCVNONAPPDATA; Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls.h ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls.h Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls.h Sun May 17 20:37:15 2020 (r361141) @@ -43,17 +43,24 @@ #define RPCTLS_FLAGS_DISABLED 0x10 #define RPCTLS_FLAGS_CERTUSER 0x20 +/* Error return values for upcall rpcs. */ +#define RPCTLSERR_OK 0 +#define RPCTLSERR_NOCLOSE 1 +#define RPCTLSERR_NOSSL 2 +#define RPCTLSERR_NOSOCKET 3 + #ifdef _KERNEL /* Functions that perform upcalls to the rpctlsd daemon. */ enum clnt_stat rpctls_connect(CLIENT *newclient, struct socket *so, - uint64_t *sslp); + uint64_t *sslp, uint32_t *reterr); enum clnt_stat rpctls_cl_handlerecord(uint64_t sec, uint64_t usec, - uint64_t ssl); + uint64_t ssl, uint32_t *reterr); enum clnt_stat rpctls_srv_handlerecord(uint64_t sec, uint64_t usec, - uint64_t ssl); -enum clnt_stat rpctls_cl_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl); + uint64_t ssl, uint32_t *reterr); +enum clnt_stat rpctls_cl_disconnect(uint64_t sec, uint64_t usec, + uint64_t ssl, uint32_t *reterr); enum clnt_stat rpctls_srv_disconnect(uint64_t sec, uint64_t usec, - uint64_t ssl); + uint64_t ssl, uint32_t *reterr); /* Initialization function for rpcsec_tls. */ int rpctls_init(void); Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctls_impl.c Sun May 17 20:37:15 2020 (r361141) @@ -317,7 +317,8 @@ rpctls_server_client(void) /* Do an upcall for a new socket connect using TLS. */ enum clnt_stat -rpctls_connect(CLIENT *newclient, struct socket *so, uint64_t *sslp) +rpctls_connect(CLIENT *newclient, struct socket *so, uint64_t *sslp, + uint32_t *reterr) { struct rpctlscd_connect_res res; struct rpc_callextra ext; @@ -366,9 +367,12 @@ printf("rpctls_conect so=%p\n", so); stat = rpctlscd_connect_1(NULL, &res, cl); printf("aft connect upcall=%d\n", stat); if (stat == RPC_SUCCESS) { - *sslp++ = res.sec; - *sslp++ = res.usec; - *sslp = res.ssl; + *reterr = res.reterr; + if (res.reterr == 0) { + *sslp++ = res.sec; + *sslp++ = res.usec; + *sslp = res.ssl; + } } CLNT_RELEASE(cl); @@ -389,9 +393,11 @@ printf("aft wakeup\n"); /* Do an upcall to handle an non-application data record using TLS. */ enum clnt_stat -rpctls_cl_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl) +rpctls_cl_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl, + uint32_t *reterr) { struct rpctlscd_handlerecord_arg arg; + struct rpctlscd_handlerecord_res res; enum clnt_stat stat; CLIENT *cl; @@ -399,22 +405,26 @@ printf("In rpctls_cl_handlerecord\n"); cl = rpctls_connect_client(); printf("handlerecord_client=%p\n", cl); if (cl == NULL) - return (RPC_FAILED); + return (RPC_AUTHERROR); /* Do the handlerecord upcall. */ arg.sec = sec; arg.usec = usec; arg.ssl = ssl; - stat = rpctlscd_handlerecord_1(&arg, NULL, cl); + stat = rpctlscd_handlerecord_1(&arg, &res, cl); printf("aft handlerecord upcall=%d\n", stat); CLNT_RELEASE(cl); + if (stat == RPC_SUCCESS) + *reterr = res.reterr; return (stat); } enum clnt_stat -rpctls_srv_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl) +rpctls_srv_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl, + uint32_t *reterr) { struct rpctlssd_handlerecord_arg arg; + struct rpctlssd_handlerecord_res res; enum clnt_stat stat; CLIENT *cl; @@ -422,23 +432,27 @@ printf("In rpctls_srv_handlerecord\n"); cl = rpctls_server_client(); printf("srv handlerecord_client=%p\n", cl); if (cl == NULL) - return (RPC_FAILED); + return (RPC_AUTHERROR); /* Do the handlerecord upcall. */ arg.sec = sec; arg.usec = usec; arg.ssl = ssl; - stat = rpctlssd_handlerecord_1(&arg, NULL, cl); + stat = rpctlssd_handlerecord_1(&arg, &res, cl); printf("aft srv handlerecord upcall=%d\n", stat); CLNT_RELEASE(cl); + if (stat == RPC_SUCCESS) + *reterr = res.reterr; return (stat); } /* Do an upcall to shut down a socket using TLS. */ enum clnt_stat -rpctls_cl_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl) +rpctls_cl_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl, + uint32_t *reterr) { struct rpctlscd_disconnect_arg arg; + struct rpctlscd_disconnect_res res; enum clnt_stat stat; CLIENT *cl; @@ -446,22 +460,26 @@ printf("In rpctls_cl_disconnect\n"); cl = rpctls_connect_client(); printf("disconnect_client=%p\n", cl); if (cl == NULL) - return (RPC_FAILED); + return (RPC_AUTHERROR); /* Do the disconnect upcall. */ arg.sec = sec; arg.usec = usec; arg.ssl = ssl; - stat = rpctlscd_disconnect_1(&arg, NULL, cl); + stat = rpctlscd_disconnect_1(&arg, &res, cl); printf("aft disconnect upcall=%d\n", stat); CLNT_RELEASE(cl); + if (stat == RPC_SUCCESS) + *reterr = res.reterr; return (stat); } enum clnt_stat -rpctls_srv_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl) +rpctls_srv_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl, + uint32_t *reterr) { struct rpctlssd_disconnect_arg arg; + struct rpctlssd_disconnect_res res; enum clnt_stat stat; CLIENT *cl; @@ -469,15 +487,17 @@ printf("In rpctls_srv_disconnect\n"); cl = rpctls_server_client(); printf("srv disconnect_client=%p\n", cl); if (cl == NULL) - return (RPC_FAILED); + return (RPC_AUTHERROR); /* Do the disconnect upcall. */ arg.sec = sec; arg.usec = usec; arg.ssl = ssl; - stat = rpctlssd_disconnect_1(&arg, NULL, cl); + stat = rpctlssd_disconnect_1(&arg, &res, cl); printf("aft srv disconnect upcall=%d\n", stat); CLNT_RELEASE(cl); + if (stat == RPC_SUCCESS) + *reterr = res.reterr; return (stat); } Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlscd.x ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlscd.x Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlscd.x Sun May 17 20:37:15 2020 (r361141) @@ -30,6 +30,7 @@ /* $FreeBSD:$ */ struct rpctlscd_connect_res { + uint32_t reterr; uint64_t sec; uint64_t usec; uint64_t ssl; @@ -41,12 +42,20 @@ struct rpctlscd_handlerecord_arg { uint64_t ssl; }; +struct rpctlscd_handlerecord_res { + uint32_t reterr; +}; + struct rpctlscd_disconnect_arg { uint64_t sec; uint64_t usec; uint64_t ssl; }; +struct rpctlscd_disconnect_res { + uint32_t reterr; +}; + program RPCTLSCD { version RPCTLSCDVERS { void RPCTLSCD_NULL(void) = 0; @@ -54,8 +63,10 @@ program RPCTLSCD { rpctlscd_connect_res RPCTLSCD_CONNECT(void) = 1; - void RPCTLSCD_HANDLERECORD(rpctlscd_handlerecord_arg) = 2; + rpctlscd_handlerecord_res + RPCTLSCD_HANDLERECORD(rpctlscd_handlerecord_arg) = 2; - void RPCTLSCD_DISCONNECT(rpctlscd_disconnect_arg) = 3; + rpctlscd_disconnect_res + RPCTLSCD_DISCONNECT(rpctlscd_disconnect_arg) = 3; } = 1; } = 0x40677374; Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlssd.x ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlssd.x Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls/rpctlssd.x Sun May 17 20:37:15 2020 (r361141) @@ -44,12 +44,20 @@ struct rpctlssd_handlerecord_arg { uint64_t ssl; }; +struct rpctlssd_handlerecord_res { + uint32_t reterr; +}; + struct rpctlssd_disconnect_arg { uint64_t sec; uint64_t usec; uint64_t ssl; }; +struct rpctlssd_disconnect_res { + uint32_t reterr; +}; + program RPCTLSSD { version RPCTLSSDVERS { void RPCTLSSD_NULL(void) = 0; @@ -57,8 +65,10 @@ program RPCTLSSD { rpctlssd_connect_res RPCTLSSD_CONNECT(void) = 1; - void RPCTLSSD_HANDLERECORD(rpctlssd_handlerecord_arg) = 2; + rpctlssd_handlerecord_res + RPCTLSSD_HANDLERECORD(rpctlssd_handlerecord_arg) = 2; - void RPCTLSSD_DISCONNECT(rpctlssd_disconnect_arg) = 3; + rpctlssd_disconnect_res + RPCTLSSD_DISCONNECT(rpctlssd_disconnect_arg) = 3; } = 1; } = 0x40677375; Modified: projects/nfs-over-tls/sys/rpc/svc_vc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/svc_vc.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/sys/rpc/svc_vc.c Sun May 17 20:37:15 2020 (r361141) @@ -452,13 +452,15 @@ static void svc_vc_destroy_common(SVCXPRT *xprt) { enum clnt_stat stat; + uint32_t reterr; if (xprt->xp_socket) { stat = RPC_FAILED; if ((xprt->xp_tls & RPCTLS_FLAGS_HANDSHAKE) != 0) stat = rpctls_srv_disconnect(xprt->xp_sslsec, - xprt->xp_sslusec, xprt->xp_sslrefno); - if (stat != RPC_SUCCESS) + xprt->xp_sslusec, xprt->xp_sslrefno, + &reterr); + if (stat != RPC_SUCCESS || reterr == RPCTLSERR_NOCLOSE) (void)soclose(xprt->xp_socket); } @@ -671,7 +673,7 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_msg *msg, struct socket* so = xprt->xp_socket; XDR xdrs; int error, rcvflag; - uint32_t xid_plus_direction[2]; + uint32_t reterr, xid_plus_direction[2]; struct cmsghdr *cmsg; struct tls_get_record tgr; enum clnt_stat ret; @@ -801,10 +803,11 @@ tryagain: sx_xunlock(&xprt->xp_lock); printf("Call rpctls_srv_handlerecord\n"); ret = rpctls_srv_handlerecord(xprt->xp_sslsec, - xprt->xp_sslusec, xprt->xp_sslrefno); + xprt->xp_sslusec, xprt->xp_sslrefno, + &reterr); sx_xlock(&xprt->xp_lock); xprt->xp_dontrcv = FALSE; - if (ret != RPC_SUCCESS) { + if (ret != RPC_SUCCESS || reterr != RPCTLSERR_OK) { /* * All we can do is soreceive() it and * then toss it. Modified: projects/nfs-over-tls/usr.sbin/rpctlscd/rpctlscd.c ============================================================================== --- projects/nfs-over-tls/usr.sbin/rpctlscd/rpctlscd.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/usr.sbin/rpctlscd/rpctlscd.c Sun May 17 20:37:15 2020 (r361141) @@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$"); static struct pidfh *rpctls_pfh = NULL; static int rpctls_debug_level; static bool rpctls_verbose; -static int testnossl; static SSL_CTX *rpctls_ctx = NULL; static const char *rpctls_verify_cafile = NULL; static const char *rpctls_verify_capath = NULL; @@ -153,9 +152,8 @@ main(int argc, char **argv) rpctls_ssl_usec = tm.tv_usec; rpctls_verbose = false; - testnossl = 0; cert = false; - while ((ch = getopt(argc, argv, "D:dl:mp:r:tv")) != -1) { + while ((ch = getopt(argc, argv, "D:dl:mp:r:v")) != -1) { switch (ch) { case 'D': rpctls_certdir = optarg; @@ -175,9 +173,6 @@ main(int argc, char **argv) case 'r': rpctls_crlfile = optarg; break; - case 't': - testnossl = 1; - break; case 'v': rpctls_verbose = true; break; @@ -325,15 +320,19 @@ rpctlscd_connect_1_svc(void *argp, /* Get the socket fd from the kernel. */ s = gssd_syscall("C"); rpctlscd_verbose_out("rpctlsd_connect s=%d\n", s); - if (s < 0) - return (FALSE); + if (s < 0) { + result->reterr = RPCTLSERR_NOSOCKET; + return (TRUE); + } /* Do a TLS connect handshake. */ ssl = rpctls_connect(rpctls_ctx, s); - if (ssl == NULL) + if (ssl == NULL) { rpctlscd_verbose_out("rpctlsd_connect: can't do TLS " "handshake\n"); - else { + result->reterr = RPCTLSERR_NOSSL; + } else { + result->reterr = RPCTLSERR_OK; result->sec = rpctls_ssl_sec; result->usec = rpctls_ssl_usec; result->ssl = ++rpctls_ssl_refno; @@ -341,15 +340,6 @@ rpctlscd_verbose_out("rpctlsd_connect s=%d\n", s); if (rpctls_ssl_refno == 0) result->ssl = ++rpctls_ssl_refno; } - if (testnossl != 0 && ssl != NULL) { - /* Read the 478 bytes of junk off the socket. */ - siz = 478; - ret = 1; - while (siz > 0 && ret > 0) { - ret = recv(s, &buf[478 - siz], siz, 0); - siz -= ret; - } - } if (ssl == NULL) { /* @@ -358,7 +348,7 @@ rpctlscd_verbose_out("rpctlsd_connect s=%d\n", s); */ shutdown(s, SHUT_WR); close(s); - return (FALSE); + return (TRUE); } /* Maintain list of all current SSL *'s */ @@ -372,7 +362,7 @@ rpctlscd_verbose_out("rpctlsd_connect s=%d\n", s); bool_t rpctlscd_handlerecord_1_svc(struct rpctlscd_handlerecord_arg *argp, - void *result, struct svc_req *rqstp) + struct rpctlscd_handlerecord_res *result, struct svc_req *rqstp) { struct ssl_entry *slp; int ret; @@ -401,14 +391,15 @@ rpctlscd_handlerecord_1_svc(struct rpctlscd_handlereco else fprintf(stderr, "SSL_read returned %d\n", ret); } + result->reterr = RPCTLSERR_OK; } else - return (FALSE); + result->reterr = RPCTLSERR_NOSSL; return (TRUE); } bool_t rpctlscd_disconnect_1_svc(struct rpctlscd_disconnect_arg *argp, - void *result, struct svc_req *rqstp) + struct rpctlscd_disconnect_res *result, struct svc_req *rqstp) { struct ssl_entry *slp; int ret; @@ -441,8 +432,9 @@ rpctlscd_verbose_out("get_shutdown=%d\n", ret); shutdown(slp->s, SHUT_WR); close(slp->s); free(slp); + result->reterr = RPCTLSERR_OK; } else - return (FALSE); + result->reterr = RPCTLSERR_NOCLOSE; return (TRUE); } Modified: projects/nfs-over-tls/usr.sbin/rpctlssd/rpctlssd.c ============================================================================== --- projects/nfs-over-tls/usr.sbin/rpctlssd/rpctlssd.c Sun May 17 20:14:49 2020 (r361140) +++ projects/nfs-over-tls/usr.sbin/rpctlssd/rpctlssd.c Sun May 17 20:37:15 2020 (r361141) @@ -420,7 +420,7 @@ rpctlssd_verbose_out("rpctlsd_connect_svc s=%d\n", s); bool_t rpctlssd_handlerecord_1_svc(struct rpctlssd_handlerecord_arg *argp, - void *result, struct svc_req *rqstp) + struct rpctlssd_handlerecord_res *result, struct svc_req *rqstp) { struct ssl_entry *slp; int ret; @@ -456,14 +456,15 @@ rpctlssd_verbose_out("get_shutdown=%d\n", ret); else fprintf(stderr, "SSL_read returned %d\n", ret); } + result->reterr = RPCTLSERR_OK; } else - return (FALSE); + result->reterr = RPCTLSERR_NOSSL; return (TRUE); } bool_t rpctlssd_disconnect_1_svc(struct rpctlssd_disconnect_arg *argp, - void *result, struct svc_req *rqstp) + struct rpctlssd_disconnect_res *result, struct svc_req *rqstp) { struct ssl_entry *slp; @@ -488,8 +489,9 @@ rpctlssd_disconnect_1_svc(struct rpctlssd_disconnect_a shutdown(slp->s, SHUT_WR); close(slp->s); free(slp); + result->reterr = RPCTLSERR_OK; } else - return (FALSE); + result->reterr = RPCTLSERR_NOCLOSE; return (TRUE); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005172037.04HKbF2p087253>