diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2020-12-21 23:14:53 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2020-12-23 21:42:55 +0000 |
commit | 665b1365fe8e24d618d63b0d57b0b4ad39e97824 (patch) | |
tree | 44fecd432dcd0b10c880a0fe045f5ba27d5a3a67 /sys/rpc/clnt_rc.c | |
parent | e523262107865130e40fb19f7c3c571c8dd0b252 (diff) | |
download | src-665b1365fe8e24d618d63b0d57b0b4ad39e97824.tar.gz src-665b1365fe8e24d618d63b0d57b0b4ad39e97824.zip |
Add a new "tlscertname" NFS mount option.
When using NFS-over-TLS, an NFS client can optionally provide an X.509
certificate to the server during the TLS handshake. For some situations,
such as different NFS servers or different certificates being mapped
to different user credentials on the NFS server, there may be a need
for different mounts to provide different certificates.
This new mount option called "tlscertname" may be used to specify a
non-default certificate be provided. This alernate certificate will
be stored in /etc/rpc.tlsclntd in a file with a name based on what is
provided by this mount option.
Diffstat (limited to 'sys/rpc/clnt_rc.c')
-rw-r--r-- | sys/rpc/clnt_rc.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c index 730001723e94..8c204989d0ea 100644 --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -110,6 +110,7 @@ clnt_reconnect_create( rc->rc_ucred = crdup(curthread->td_ucred); rc->rc_client = NULL; rc->rc_tls = false; + rc->rc_tlscertname = NULL; cl->cl_refs = 1; cl->cl_ops = &clnt_reconnect_ops; @@ -198,7 +199,8 @@ clnt_reconnect_connect(CLIENT *cl) (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); if (rc->rc_tls && newclient != NULL) { - stat = rpctls_connect(newclient, so, ssl, &reterr); + stat = rpctls_connect(newclient, rc->rc_tlscertname, so, + ssl, &reterr); if (stat != RPC_SUCCESS || reterr != RPCTLSERR_OK) { if (stat == RPC_SUCCESS) stat = RPC_FAILED; @@ -405,6 +407,7 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void *info) { struct rc_data *rc = (struct rc_data *)cl->cl_private; SVCXPRT *xprt; + size_t slen; if (info == NULL) { return (FALSE); @@ -496,6 +499,20 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void *info) rc->rc_tls = true; break; + case CLSET_TLSCERTNAME: + slen = strlen(info) + 1; + /* + * tlscertname with "key.pem" appended to it forms a file + * name. As such, the maximum allowable strlen(info) is + * NAME_MAX - 7. However, "slen" includes the nul termination + * byte so it can be up to NAME_MAX - 6. + */ + if (slen <= 1 || slen > NAME_MAX - 6) + return (FALSE); + rc->rc_tlscertname = mem_alloc(slen); + strlcpy(rc->rc_tlscertname, info, slen); + break; + default: return (FALSE); } @@ -543,6 +560,7 @@ clnt_reconnect_destroy(CLIENT *cl) } crfree(rc->rc_ucred); mtx_destroy(&rc->rc_lock); + mem_free(rc->rc_tlscertname, 0); /* 0 ok, since arg. ignored. */ mem_free(rc, sizeof(*rc)); mem_free(cl, sizeof (CLIENT)); } |