// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, 2022 Oracle.  All rights reserved.
 *
 * The AUTH_TLS credential is used only to probe a remote peer
 * for RPC-over-TLS support.
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/sunrpc/clnt.h>

static const char *starttls_token = "STARTTLS";
static const size_t starttls_len = 8;

static struct rpc_auth tls_auth;
static struct rpc_cred tls_cred;

static void tls_encode_probe(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
			     const void *obj)
{
}

static int tls_decode_probe(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
			    void *obj)
{
	return 0;
}

static const struct rpc_procinfo rpcproc_tls_probe = {
	.p_encode	= tls_encode_probe,
	.p_decode	= tls_decode_probe,
};

static void rpc_tls_probe_call_prepare(struct rpc_task *task, void *data)
{
	task->tk_flags &= ~RPC_TASK_NO_RETRANS_TIMEOUT;
	rpc_call_start(task);
}

static void rpc_tls_probe_call_done(struct rpc_task *task, void *data)
{
}

static const struct rpc_call_ops rpc_tls_probe_ops = {
	.rpc_call_prepare	= rpc_tls_probe_call_prepare,
	.rpc_call_done		= rpc_tls_probe_call_done,
};

static int tls_probe(struct rpc_clnt *clnt)
{
	struct rpc_message msg = {
		.rpc_proc	= &rpcproc_tls_probe,
	};
	struct rpc_task_setup task_setup_data = {
		.rpc_client	= clnt,
		.rpc_message	= &msg,
		.rpc_op_cred	= &tls_cred,
		.callback_ops	= &rpc_tls_probe_ops,
		.flags		= RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
	};
	struct rpc_task	*task;
	int status;

	task = rpc_run_task(&task_setup_data);
	if (IS_ERR(task))
		return PTR_ERR(task);
	status = task->tk_status;
	rpc_put_task(task);
	return status;
}

static struct rpc_auth *tls_create(const struct rpc_auth_create_args *args,
				   struct rpc_clnt *clnt)
{
	refcount_inc(&tls_auth.au_count);
	return &tls_auth;
}

static void tls_destroy(struct rpc_auth *auth)
{
}

static struct rpc_cred *tls_lookup_cred(struct rpc_auth *auth,
					struct auth_cred *acred, int flags)
{
	return get_rpccred(&tls_cred);
}

static void tls_destroy_cred(struct rpc_cred *cred)
{
}

static int tls_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
{
	return 1;
}

static int tls_marshal(struct rpc_task *task, struct xdr_stream *xdr)
{
	__be32 *p;

	p = xdr_reserve_space(xdr, 4 * XDR_UNIT);
	if (!p)
		return -EMSGSIZE;
	/* Credential */
	*p++ = rpc_auth_tls;
	*p++ = xdr_zero;
	/* Verifier */
	*p++ = rpc_auth_null;
	*p   = xdr_zero;
	return 0;
}

static int tls_refresh(struct rpc_task *task)
{
	set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
	return 0;
}

static int tls_validate(struct rpc_task *task, struct xdr_stream *xdr)
{
	__be32 *p;
	void *str;

	p = xdr_inline_decode(xdr, XDR_UNIT);
	if (!p)
		return -EIO;
	if (*p != rpc_auth_null)
		return -EIO;
	if (xdr_stream_decode_opaque_inline(xdr, &str, starttls_len) != starttls_len)
		return -EPROTONOSUPPORT;
	if (memcmp(str, starttls_token, starttls_len))
		return -EPROTONOSUPPORT;
	return 0;
}

const struct rpc_authops authtls_ops = {
	.owner		= THIS_MODULE,
	.au_flavor	= RPC_AUTH_TLS,
	.au_name	= "NULL",
	.create		= tls_create,
	.destroy	= tls_destroy,
	.lookup_cred	= tls_lookup_cred,
	.ping		= tls_probe,
};

static struct rpc_auth tls_auth = {
	.au_cslack	= NUL_CALLSLACK,
	.au_rslack	= NUL_REPLYSLACK,
	.au_verfsize	= NUL_REPLYSLACK,
	.au_ralign	= NUL_REPLYSLACK,
	.au_ops		= &authtls_ops,
	.au_flavor	= RPC_AUTH_TLS,
	.au_count	= REFCOUNT_INIT(1),
};

static const struct rpc_credops tls_credops = {
	.cr_name	= "AUTH_TLS",
	.crdestroy	= tls_destroy_cred,
	.crmatch	= tls_match,
	.crmarshal	= tls_marshal,
	.crwrap_req	= rpcauth_wrap_req_encode,
	.crrefresh	= tls_refresh,
	.crvalidate	= tls_validate,
	.crunwrap_resp	= rpcauth_unwrap_resp_decode,
};

static struct rpc_cred tls_cred = {
	.cr_lru		= LIST_HEAD_INIT(tls_cred.cr_lru),
	.cr_auth	= &tls_auth,
	.cr_ops		= &tls_credops,
	.cr_count	= REFCOUNT_INIT(2),
	.cr_flags	= 1UL << RPCAUTH_CRED_UPTODATE,
};
