/**
 * eCryptfs: Linux filesystem encryption layer
 *
 * Copyright (C) 2004-2006 International Business Machines Corp.
 *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
 *		Tyler Hicks <tyhicks@ou.edu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <net/sock.h>
#include <linux/hash.h>
#include <linux/random.h>
#include "ecryptfs_kernel.h"

static struct sock *ecryptfs_nl_sock;

/**
 * ecryptfs_send_netlink
 * @data: The data to include as the payload
 * @data_len: The byte count of the data
 * @msg_ctx: The netlink context that will be used to handle the
 *          response message
 * @msg_type: The type of netlink message to send
 * @msg_flags: The flags to include in the netlink header
 * @daemon_pid: The process id of the daemon to send the message to
 *
 * Sends the data to the specified daemon pid and uses the netlink
 * context element to store the data needed for validation upon
 * receiving the response.  The data and the netlink context can be
 * null if just sending a netlink header is sufficient.  Returns zero
 * upon sending the message; non-zero upon error.
 */
int ecryptfs_send_netlink(char *data, int data_len,
			  struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type,
			  u16 msg_flags, pid_t daemon_pid)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	struct ecryptfs_message *msg;
	size_t payload_len;
	int rc;

	payload_len = ((data && data_len) ? (sizeof(*msg) + data_len) : 0);
	skb = alloc_skb(NLMSG_SPACE(payload_len), GFP_KERNEL);
	if (!skb) {
		rc = -ENOMEM;
		ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n");
		goto out;
	}
	nlh = NLMSG_PUT(skb, daemon_pid, msg_ctx ? msg_ctx->counter : 0,
			msg_type, payload_len);
	nlh->nlmsg_flags = msg_flags;
	if (msg_ctx && payload_len) {
		msg = (struct ecryptfs_message *)NLMSG_DATA(nlh);
		msg->index = msg_ctx->index;
		msg->data_len = data_len;
		memcpy(msg->data, data, data_len);
	}
	rc = netlink_unicast(ecryptfs_nl_sock, skb, daemon_pid, 0);
	if (rc < 0) {
		ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink "
				"message; rc = [%d]\n", rc);
		goto out;
	}
	rc = 0;
	goto out;
nlmsg_failure:
	rc = -EMSGSIZE;
	kfree_skb(skb);
out:
	return rc;
}

/**
 * ecryptfs_process_nl_reponse
 * @skb: The socket buffer containing the netlink message of state
 *       RESPONSE
 *
 * Processes a response message after sending a operation request to
 * userspace.  Attempts to assign the msg to a netlink context element
 * at the index specified in the msg.  The sk_buff and nlmsghdr must
 * be validated before this function. Returns zero upon delivery to
 * desired context element; non-zero upon delivery failure or error.
 */
static int ecryptfs_process_nl_response(struct sk_buff *skb)
{
	struct nlmsghdr *nlh = nlmsg_hdr(skb);
	struct ecryptfs_message *msg = NLMSG_DATA(nlh);
	int rc;

	if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) {
		rc = -EINVAL;
		ecryptfs_printk(KERN_ERR, "Received netlink message with "
				"incorrectly specified data length\n");
		goto out;
	}
	rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid,
				       NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq);
	if (rc)
		printk(KERN_ERR
		       "Error processing response message; rc = [%d]\n", rc);
out:
	return rc;
}

/**
 * ecryptfs_process_nl_helo
 * @skb: The socket buffer containing the nlmsghdr in HELO state
 *
 * Gets uid and pid of the skb and adds the values to the daemon id
 * hash. Returns zero after adding a new daemon id to the hash list;
 * non-zero otherwise.
 */
static int ecryptfs_process_nl_helo(struct sk_buff *skb)
{
	int rc;

	rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK,
				   NETLINK_CREDS(skb)->uid,
				   NETLINK_CREDS(skb)->pid);
	if (rc)
		printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc);
	return rc;
}

/**
 * ecryptfs_process_nl_quit
 * @skb: The socket buffer containing the nlmsghdr in QUIT state
 *
 * Gets uid and pid of the skb and deletes the corresponding daemon
 * id, if it is the registered that is requesting the
 * deletion. Returns zero after deleting the desired daemon id;
 * non-zero otherwise.
 */
static int ecryptfs_process_nl_quit(struct sk_buff *skb)
{
	int rc;

	rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid,
				   NETLINK_CREDS(skb)->pid);
	if (rc)
		printk(KERN_WARNING
		       "Error processing QUIT message; rc = [%d]\n", rc);
	return rc;
}

/**
 * ecryptfs_receive_nl_message
 *
 * Callback function called by netlink system when a message arrives.
 * If the message looks to be valid, then an attempt is made to assign
 * it to its desired netlink context element and wake up the process
 * that is waiting for a response.
 */
static void ecryptfs_receive_nl_message(struct sk_buff *skb)
{
	struct nlmsghdr *nlh;

	nlh = nlmsg_hdr(skb);
	if (!NLMSG_OK(nlh, skb->len)) {
		ecryptfs_printk(KERN_ERR, "Received corrupt netlink "
				"message\n");
		goto free;
	}
	switch (nlh->nlmsg_type) {
		case ECRYPTFS_NLMSG_RESPONSE:
			if (ecryptfs_process_nl_response(skb)) {
				ecryptfs_printk(KERN_WARNING, "Failed to "
						"deliver netlink response to "
						"requesting operation\n");
			}
			break;
		case ECRYPTFS_NLMSG_HELO:
			if (ecryptfs_process_nl_helo(skb)) {
				ecryptfs_printk(KERN_WARNING, "Failed to "
						"fulfill HELO request\n");
			}
			break;
		case ECRYPTFS_NLMSG_QUIT:
			if (ecryptfs_process_nl_quit(skb)) {
				ecryptfs_printk(KERN_WARNING, "Failed to "
						"fulfill QUIT request\n");
			}
			break;
		default:
			ecryptfs_printk(KERN_WARNING, "Dropping netlink "
					"message of unrecognized type [%d]\n",
					nlh->nlmsg_type);
			break;
	}
free:
	kfree_skb(skb);
}

/**
 * ecryptfs_init_netlink
 *
 * Initializes the daemon id hash list, netlink context array, and
 * necessary locks.  Returns zero upon success; non-zero upon error.
 */
int ecryptfs_init_netlink(void)
{
	int rc;

	ecryptfs_nl_sock = netlink_kernel_create(&init_net, NETLINK_ECRYPTFS, 0,
						 ecryptfs_receive_nl_message,
						 NULL, THIS_MODULE);
	if (!ecryptfs_nl_sock) {
		rc = -EIO;
		ecryptfs_printk(KERN_ERR, "Failed to create netlink socket\n");
		goto out;
	}
	ecryptfs_nl_sock->sk_sndtimeo = ECRYPTFS_DEFAULT_SEND_TIMEOUT;
	rc = 0;
out:
	return rc;
}

/**
 * ecryptfs_release_netlink
 *
 * Frees all memory used by the netlink context array and releases the
 * netlink socket.
 */
void ecryptfs_release_netlink(void)
{
	if (ecryptfs_nl_sock && ecryptfs_nl_sock->sk_socket)
		sock_release(ecryptfs_nl_sock->sk_socket);
	ecryptfs_nl_sock = NULL;
}
