/* RxRPC security handling
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/crypto.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include "ar-internal.h"

static LIST_HEAD(rxrpc_security_methods);
static DECLARE_RWSEM(rxrpc_security_sem);

/*
 * get an RxRPC security module
 */
static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec)
{
	return try_module_get(sec->owner) ? sec : NULL;
}

/*
 * release an RxRPC security module
 */
static void rxrpc_security_put(struct rxrpc_security *sec)
{
	module_put(sec->owner);
}

/*
 * look up an rxrpc security module
 */
static struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
{
	struct rxrpc_security *sec = NULL;

	_enter("");

	down_read(&rxrpc_security_sem);

	list_for_each_entry(sec, &rxrpc_security_methods, link) {
		if (sec->security_index == security_index) {
			if (unlikely(!rxrpc_security_get(sec)))
				break;
			goto out;
		}
	}

	sec = NULL;
out:
	up_read(&rxrpc_security_sem);
	_leave(" = %p [%s]", sec, sec ? sec->name : "");
	return sec;
}

/**
 * rxrpc_register_security - register an RxRPC security handler
 * @sec: security module
 *
 * register an RxRPC security handler for use by RxRPC
 */
int rxrpc_register_security(struct rxrpc_security *sec)
{
	struct rxrpc_security *psec;
	int ret;

	_enter("");
	down_write(&rxrpc_security_sem);

	ret = -EEXIST;
	list_for_each_entry(psec, &rxrpc_security_methods, link) {
		if (psec->security_index == sec->security_index)
			goto out;
	}

	list_add(&sec->link, &rxrpc_security_methods);

	printk(KERN_NOTICE "RxRPC: Registered security type %d '%s'\n",
	       sec->security_index, sec->name);
	ret = 0;

out:
	up_write(&rxrpc_security_sem);
	_leave(" = %d", ret);
	return ret;
}

EXPORT_SYMBOL_GPL(rxrpc_register_security);

/**
 * rxrpc_unregister_security - unregister an RxRPC security handler
 * @sec: security module
 *
 * unregister an RxRPC security handler
 */
void rxrpc_unregister_security(struct rxrpc_security *sec)
{

	_enter("");
	down_write(&rxrpc_security_sem);
	list_del_init(&sec->link);
	up_write(&rxrpc_security_sem);

	printk(KERN_NOTICE "RxRPC: Unregistered security type %d '%s'\n",
	       sec->security_index, sec->name);
}

EXPORT_SYMBOL_GPL(rxrpc_unregister_security);

/*
 * initialise the security on a client connection
 */
int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
{
	struct rxrpc_key_token *token;
	struct rxrpc_security *sec;
	struct key *key = conn->key;
	int ret;

	_enter("{%d},{%x}", conn->debug_id, key_serial(key));

	if (!key)
		return 0;

	ret = key_validate(key);
	if (ret < 0)
		return ret;

	if (!key->payload.data)
		return -EKEYREJECTED;
	token = key->payload.data;

	sec = rxrpc_security_lookup(token->security_index);
	if (!sec)
		return -EKEYREJECTED;
	conn->security = sec;

	ret = conn->security->init_connection_security(conn);
	if (ret < 0) {
		rxrpc_security_put(conn->security);
		conn->security = NULL;
		return ret;
	}

	_leave(" = 0");
	return 0;
}

/*
 * initialise the security on a server connection
 */
int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
{
	struct rxrpc_security *sec;
	struct rxrpc_local *local = conn->trans->local;
	struct rxrpc_sock *rx;
	struct key *key;
	key_ref_t kref;
	char kdesc[5+1+3+1];

	_enter("");

	sprintf(kdesc, "%u:%u", ntohs(conn->service_id), conn->security_ix);

	sec = rxrpc_security_lookup(conn->security_ix);
	if (!sec) {
		_leave(" = -ENOKEY [lookup]");
		return -ENOKEY;
	}

	/* find the service */
	read_lock_bh(&local->services_lock);
	list_for_each_entry(rx, &local->services, listen_link) {
		if (rx->service_id == conn->service_id)
			goto found_service;
	}

	/* the service appears to have died */
	read_unlock_bh(&local->services_lock);
	rxrpc_security_put(sec);
	_leave(" = -ENOENT");
	return -ENOENT;

found_service:
	if (!rx->securities) {
		read_unlock_bh(&local->services_lock);
		rxrpc_security_put(sec);
		_leave(" = -ENOKEY");
		return -ENOKEY;
	}

	/* look through the service's keyring */
	kref = keyring_search(make_key_ref(rx->securities, 1UL),
			      &key_type_rxrpc_s, kdesc);
	if (IS_ERR(kref)) {
		read_unlock_bh(&local->services_lock);
		rxrpc_security_put(sec);
		_leave(" = %ld [search]", PTR_ERR(kref));
		return PTR_ERR(kref);
	}

	key = key_ref_to_ptr(kref);
	read_unlock_bh(&local->services_lock);

	conn->server_key = key;
	conn->security = sec;

	_leave(" = 0");
	return 0;
}

/*
 * secure a packet prior to transmission
 */
int rxrpc_secure_packet(const struct rxrpc_call *call,
			struct sk_buff *skb,
			size_t data_size,
			void *sechdr)
{
	if (call->conn->security)
		return call->conn->security->secure_packet(
			call, skb, data_size, sechdr);
	return 0;
}

/*
 * secure a packet prior to transmission
 */
int rxrpc_verify_packet(const struct rxrpc_call *call, struct sk_buff *skb,
			u32 *_abort_code)
{
	if (call->conn->security)
		return call->conn->security->verify_packet(
			call, skb, _abort_code);
	return 0;
}

/*
 * clear connection security
 */
void rxrpc_clear_conn_security(struct rxrpc_connection *conn)
{
	_enter("{%d}", conn->debug_id);

	if (conn->security) {
		conn->security->clear(conn);
		rxrpc_security_put(conn->security);
		conn->security = NULL;
	}

	key_put(conn->key);
	key_put(conn->server_key);
}
