Skip to content

Commit 74aaf96

Browse files
committed
SUNRPC: Teach server to recognize RPC_AUTH_TLS
Initial support for the RPC_AUTH_TLS authentication flavor enables NFSD to eventually accept an RPC_AUTH_TLS probe from clients. This patch simply prevents NFSD from rejecting these probes completely. In the meantime, graft this support in now so that RPC_AUTH_TLS support keeps up with generic code and API changes in the RPC server. Down the road, server-side transport implementations will populate xpo_start_tls when they can support RPC-with-TLS. For example, TCP will eventually populate it, but RDMA won't. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 37902c6 commit 74aaf96

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

include/linux/sunrpc/svc_xprt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct svc_xprt_ops {
2828
void (*xpo_free)(struct svc_xprt *);
2929
void (*xpo_secure_port)(struct svc_rqst *rqstp);
3030
void (*xpo_kill_temp_xprt)(struct svc_xprt *);
31+
void (*xpo_start_tls)(struct svc_xprt *);
3132
};
3233

3334
struct svc_xprt_class {

net/sunrpc/svcauth.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
*/
3232
extern struct auth_ops svcauth_null;
3333
extern struct auth_ops svcauth_unix;
34+
extern struct auth_ops svcauth_tls;
3435

3536
static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
3637
[RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
3738
[RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
39+
[RPC_AUTH_TLS] = (struct auth_ops __force __rcu *)&svcauth_tls,
3840
};
3941

4042
static struct auth_ops *

net/sunrpc/svcauth_unix.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct unix_domain {
3737

3838
extern struct auth_ops svcauth_null;
3939
extern struct auth_ops svcauth_unix;
40+
extern struct auth_ops svcauth_tls;
4041

4142
static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
4243
{
@@ -788,6 +789,65 @@ struct auth_ops svcauth_null = {
788789
};
789790

790791

792+
static int
793+
svcauth_tls_accept(struct svc_rqst *rqstp)
794+
{
795+
struct svc_cred *cred = &rqstp->rq_cred;
796+
struct kvec *argv = rqstp->rq_arg.head;
797+
struct kvec *resv = rqstp->rq_res.head;
798+
799+
if (argv->iov_len < XDR_UNIT * 3)
800+
return SVC_GARBAGE;
801+
802+
/* Call's cred length */
803+
if (svc_getu32(argv) != xdr_zero) {
804+
rqstp->rq_auth_stat = rpc_autherr_badcred;
805+
return SVC_DENIED;
806+
}
807+
808+
/* Call's verifier flavor and its length */
809+
if (svc_getu32(argv) != rpc_auth_null ||
810+
svc_getu32(argv) != xdr_zero) {
811+
rqstp->rq_auth_stat = rpc_autherr_badverf;
812+
return SVC_DENIED;
813+
}
814+
815+
/* AUTH_TLS is not valid on non-NULL procedures */
816+
if (rqstp->rq_proc != 0) {
817+
rqstp->rq_auth_stat = rpc_autherr_badcred;
818+
return SVC_DENIED;
819+
}
820+
821+
/* Mapping to nobody uid/gid is required */
822+
cred->cr_uid = INVALID_UID;
823+
cred->cr_gid = INVALID_GID;
824+
cred->cr_group_info = groups_alloc(0);
825+
if (cred->cr_group_info == NULL)
826+
return SVC_CLOSE; /* kmalloc failure - client must retry */
827+
828+
/* Reply's verifier */
829+
svc_putnl(resv, RPC_AUTH_NULL);
830+
if (rqstp->rq_xprt->xpt_ops->xpo_start_tls) {
831+
svc_putnl(resv, 8);
832+
memcpy(resv->iov_base + resv->iov_len, "STARTTLS", 8);
833+
resv->iov_len += 8;
834+
} else
835+
svc_putnl(resv, 0);
836+
837+
rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
838+
return SVC_OK;
839+
}
840+
841+
struct auth_ops svcauth_tls = {
842+
.name = "tls",
843+
.owner = THIS_MODULE,
844+
.flavour = RPC_AUTH_TLS,
845+
.accept = svcauth_tls_accept,
846+
.release = svcauth_null_release,
847+
.set_client = svcauth_unix_set_client,
848+
};
849+
850+
791851
static int
792852
svcauth_unix_accept(struct svc_rqst *rqstp)
793853
{

0 commit comments

Comments
 (0)