// SPDX-License-Identifier: GPL-2.0-or-later
/* RxRPC key management
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * RxRPC keys should have a description of describing their purpose:
 *	"afs@CAMBRIDGE.REDHAT.COM>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/key-type.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include <keys/user-type.h>
#include "ar-internal.h"

static int rxrpc_vet_description_s(const char *);
static int rxrpc_preparse_s(struct key_preparsed_payload *);
static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
static void rxrpc_destroy_s(struct key *);
static void rxrpc_describe_s(const struct key *, struct seq_file *);

/*
 * rxrpc server keys take "<serviceId>:<securityIndex>[:<sec-specific>]" as the
 * description and the key material as the payload.
 */
struct key_type key_type_rxrpc_s = {
	.name		= "rxrpc_s",
	.flags		= KEY_TYPE_NET_DOMAIN,
	.vet_description = rxrpc_vet_description_s,
	.preparse	= rxrpc_preparse_s,
	.free_preparse	= rxrpc_free_preparse_s,
	.instantiate	= generic_key_instantiate,
	.destroy	= rxrpc_destroy_s,
	.describe	= rxrpc_describe_s,
};

/*
 * Vet the description for an RxRPC server key.
 */
static int rxrpc_vet_description_s(const char *desc)
{
	unsigned long service, sec_class;
	char *p;

	service = simple_strtoul(desc, &p, 10);
	if (*p != ':' || service > 65535)
		return -EINVAL;
	sec_class = simple_strtoul(p + 1, &p, 10);
	if ((*p && *p != ':') || sec_class < 1 || sec_class > 255)
		return -EINVAL;
	return 0;
}

/*
 * Preparse a server secret key.
 */
static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
{
	const struct rxrpc_security *sec;
	unsigned int service, sec_class;
	int n;

	_enter("%zu", prep->datalen);

	if (!prep->orig_description)
		return -EINVAL;

	if (sscanf(prep->orig_description, "%u:%u%n", &service, &sec_class, &n) != 2)
		return -EINVAL;

	sec = rxrpc_security_lookup(sec_class);
	if (!sec)
		return -ENOPKG;

	prep->payload.data[1] = (struct rxrpc_security *)sec;

	if (!sec->preparse_server_key)
		return -EINVAL;

	return sec->preparse_server_key(prep);
}

static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
{
	const struct rxrpc_security *sec = prep->payload.data[1];

	if (sec && sec->free_preparse_server_key)
		sec->free_preparse_server_key(prep);
}

static void rxrpc_destroy_s(struct key *key)
{
	const struct rxrpc_security *sec = key->payload.data[1];

	if (sec && sec->destroy_server_key)
		sec->destroy_server_key(key);
}

static void rxrpc_describe_s(const struct key *key, struct seq_file *m)
{
	const struct rxrpc_security *sec = key->payload.data[1];

	seq_puts(m, key->description);
	if (sec && sec->describe_server_key)
		sec->describe_server_key(key, m);
}

/*
 * grab the security keyring for a server socket
 */
int rxrpc_server_keyring(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
{
	struct key *key;
	char *description;

	_enter("");

	if (rx->securities)
		return -EINVAL;

	if (optlen <= 0 || optlen > PAGE_SIZE - 1)
		return -EINVAL;

	description = memdup_sockptr_nul(optval, optlen);
	if (IS_ERR(description))
		return PTR_ERR(description);

	key = request_key(&key_type_keyring, description, NULL);
	if (IS_ERR(key)) {
		kfree(description);
		_leave(" = %ld", PTR_ERR(key));
		return PTR_ERR(key);
	}

	rx->securities = key;
	kfree(description);
	_leave(" = 0 [key %x]", key->serial);
	return 0;
}

/**
 * rxrpc_sock_set_security_keyring - Set the security keyring for a kernel service
 * @sk: The socket to set the keyring on
 * @keyring: The keyring to set
 *
 * Set the server security keyring on an rxrpc socket.  This is used to provide
 * the encryption keys for a kernel service.
 *
 * Return: %0 if successful and a negative error code otherwise.
 */
int rxrpc_sock_set_security_keyring(struct sock *sk, struct key *keyring)
{
	struct rxrpc_sock *rx = rxrpc_sk(sk);
	int ret = 0;

	lock_sock(sk);
	if (rx->securities)
		ret = -EINVAL;
	else if (rx->sk.sk_state != RXRPC_UNBOUND)
		ret = -EISCONN;
	else
		rx->securities = key_get(keyring);
	release_sock(sk);
	return ret;
}
EXPORT_SYMBOL(rxrpc_sock_set_security_keyring);

/**
 * rxrpc_sock_set_manage_response - Set the manage-response flag for a kernel service
 * @sk: The socket to set the keyring on
 * @set: True to set, false to clear the flag
 *
 * Set the flag on an rxrpc socket to say that the caller wants to manage the
 * RESPONSE packet and the user-defined data it may contain.  Setting this
 * means that recvmsg() will return messages with RXRPC_CHALLENGED in the
 * control message buffer containing information about the challenge.
 *
 * The user should respond to the challenge by passing RXRPC_RESPOND or
 * RXRPC_RESPOND_ABORT control messages with sendmsg() to the same call.
 * Supplementary control messages, such as RXRPC_RESP_RXGK_APPDATA, may be
 * included to indicate the parts the user wants to supply.
 *
 * The server will be passed the response data with a RXRPC_RESPONDED control
 * message when it gets the first data from each call.
 *
 * Note that this is only honoured by security classes that need auxiliary data
 * (e.g. RxGK).  Those that don't offer the facility (e.g. RxKAD) respond
 * without consulting userspace.
 *
 * Return: The previous setting.
 */
int rxrpc_sock_set_manage_response(struct sock *sk, bool set)
{
	struct rxrpc_sock *rx = rxrpc_sk(sk);
	int ret;

	lock_sock(sk);
	ret = !!test_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags);
	if (set)
		set_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags);
	else
		clear_bit(RXRPC_SOCK_MANAGE_RESPONSE, &rx->flags);
	release_sock(sk);
	return ret;
}
EXPORT_SYMBOL(rxrpc_sock_set_manage_response);
