/*
 * Plan 9 style capability device implementation for the Linux Kernel
 *
 * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
 *
 * Released under the GPLv2
 *
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/cred.h>

#ifndef CAP_MAJOR
#define CAP_MAJOR 0
#endif

#ifndef CAP_NR_DEVS
#define CAP_NR_DEVS 2		/* caphash and capuse */
#endif

#ifndef CAP_NODE_SIZE
#define CAP_NODE_SIZE 20
#endif

#define MAX_DIGEST_SIZE  20

struct cap_node {
	char data[CAP_NODE_SIZE];
	struct list_head list;
};

struct cap_dev {
	struct cap_node *head;
	int node_size;
	unsigned long size;
	struct semaphore sem;
	struct cdev cdev;
};

static int cap_major = CAP_MAJOR;
static int cap_minor;
static int cap_nr_devs = CAP_NR_DEVS;
static int cap_node_size = CAP_NODE_SIZE;

module_param(cap_major, int, S_IRUGO);
module_param(cap_minor, int, S_IRUGO);
module_param(cap_nr_devs, int, S_IRUGO);

MODULE_AUTHOR("Ashwin Ganti");
MODULE_LICENSE("GPL");

static struct cap_dev *cap_devices;

static void hexdump(unsigned char *buf, unsigned int len)
{
	while (len--)
		printk("%02x", *buf++);
	printk("\n");
}

static char *cap_hash(char *plain_text, unsigned int plain_text_size,
		      char *key, unsigned int key_size)
{
	struct scatterlist sg;
	char *result;
	struct crypto_hash *tfm;
	struct hash_desc desc;
	int ret;

	tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(tfm)) {
		printk(KERN_ERR
		       "failed to load transform for hmac(sha1): %ld\n",
		       PTR_ERR(tfm));
		return NULL;
	}

	desc.tfm = tfm;
	desc.flags = 0;

	result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
	if (!result) {
		printk(KERN_ERR "out of memory!\n");
		goto out;
	}

	sg_set_buf(&sg, plain_text, plain_text_size);

	ret = crypto_hash_setkey(tfm, key, key_size);
	if (ret) {
		printk(KERN_ERR "setkey() failed ret=%d\n", ret);
		kfree(result);
		result = NULL;
		goto out;
	}

	ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
	if (ret) {
		printk(KERN_ERR "digest () failed ret=%d\n", ret);
		kfree(result);
		result = NULL;
		goto out;
	}

	printk(KERN_DEBUG "crypto hash digest size %d\n",
	       crypto_hash_digestsize(tfm));
	hexdump(result, MAX_DIGEST_SIZE);

out:
	crypto_free_hash(tfm);
	return result;
}

static int cap_trim(struct cap_dev *dev)
{
	struct cap_node *tmp;
	struct list_head *pos, *q;
	if (dev->head != NULL) {
		list_for_each_safe(pos, q, &(dev->head->list)) {
			tmp = list_entry(pos, struct cap_node, list);
			list_del(pos);
			kfree(tmp);
		}
	}
	return 0;
}

static int cap_open(struct inode *inode, struct file *filp)
{
	struct cap_dev *dev;
	dev = container_of(inode->i_cdev, struct cap_dev, cdev);
	filp->private_data = dev;

	/* trim to 0 the length of the device if open was write-only */
	if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
		if (down_interruptible(&dev->sem))
			return -ERESTARTSYS;
		cap_trim(dev);
		up(&dev->sem);
	}
	/* initialise the head if it is NULL */
	if (dev->head == NULL) {
		dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
		INIT_LIST_HEAD(&(dev->head->list));
	}
	return 0;
}

static int cap_release(struct inode *inode, struct file *filp)
{
	return 0;
}

static ssize_t cap_write(struct file *filp, const char __user *buf,
			 size_t count, loff_t *f_pos)
{
	struct cap_node *node_ptr, *tmp;
	struct list_head *pos;
	struct cap_dev *dev = filp->private_data;
	ssize_t retval = -ENOMEM;
	struct cred *new;
	int len, target_int, source_int, flag = 0;
	char *user_buf, *user_buf_running, *source_user, *target_user,
	    *rand_str, *hash_str, *result;

	if (down_interruptible(&dev->sem))
		return -ERESTARTSYS;

	user_buf_running = NULL;
	hash_str = NULL;
	node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
	user_buf = kzalloc(count+1, GFP_KERNEL);
	if (!node_ptr || !user_buf)
		goto out;

	if (copy_from_user(user_buf, buf, count)) {
		retval = -EFAULT;
		goto out;
	}

	/*
	 * If the minor number is 0 ( /dev/caphash ) then simply add the
	 * hashed capability supplied by the user to the list of hashes
	 */
	if (0 == iminor(filp->f_dentry->d_inode)) {
		if (count > CAP_NODE_SIZE) {
			retval = -EINVAL;
			goto out;
		}
		printk(KERN_INFO "Capability being written to /dev/caphash : \n");
		hexdump(user_buf, count);
		memcpy(node_ptr->data, user_buf, count);
		list_add(&(node_ptr->list), &(dev->head->list));
		node_ptr = NULL;
	} else {
		char *tmpu;
		if (!cap_devices[0].head ||
				list_empty(&(cap_devices[0].head->list))) {
			retval = -EINVAL;
			goto out;
		}
		/*
		 * break the supplied string into tokens with @ as the
		 * delimiter If the string is "user1@user2@randomstring" we
		 * need to split it and hash 'user1@user2' using 'randomstring'
		 * as the key.
		 */
		tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL);
		source_user = strsep(&tmpu, "@");
		target_user = strsep(&tmpu, "@");
		rand_str = tmpu;
		if (!source_user || !target_user || !rand_str) {
			retval = -EINVAL;
			goto out;
		}

		/* hash the string user1@user2 with rand_str as the key */
		len = strlen(source_user) + strlen(target_user) + 1;
		/* src, @, len, \0 */
		hash_str = kzalloc(len+1, GFP_KERNEL);
		strcat(hash_str, source_user);
		strcat(hash_str, "@");
		strcat(hash_str, target_user);

		printk(KERN_ALERT "the source user is %s \n", source_user);
		printk(KERN_ALERT "the target user is %s \n", target_user);

		result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
		if (NULL == result) {
			retval = -EFAULT;
			goto out;
		}
		memcpy(node_ptr->data, result, CAP_NODE_SIZE);  /* why? */
		/* Change the process's uid if the hash is present in the
		 * list of hashes
		 */
		list_for_each(pos, &(cap_devices->head->list)) {
			/*
			 * Change the user id of the process if the hashes
			 * match
			 */
			if (0 ==
			    memcmp(result,
				   list_entry(pos, struct cap_node,
					      list)->data,
				   CAP_NODE_SIZE)) {
				target_int = (unsigned int)
				    simple_strtol(target_user, NULL, 0);
				source_int = (unsigned int)
				    simple_strtol(source_user, NULL, 0);
				flag = 1;

				/*
				 * Check whether the process writing to capuse
				 * is actually owned by the source owner
				 */
				if (source_int != current_uid()) {
					printk(KERN_ALERT
					       "Process is not owned by the source user of the capability.\n");
					retval = -EFAULT;
					goto out;
				}
				/*
				 * What all id's need to be changed here? uid,
				 * euid, fsid, savedids ??  Currently I am
				 * changing the effective user id since most of
				 * the authorisation decisions are based on it
				 */
				new = prepare_creds();
				if (!new) {
					retval = -ENOMEM;
					goto out;
				}
				new->uid = (uid_t) target_int;
				new->euid = (uid_t) target_int;
				retval = commit_creds(new);
				if (retval)
					goto out;

				/*
				 * Remove the capability from the list and
				 * break
				 */
				tmp = list_entry(pos, struct cap_node, list);
				list_del(pos);
				kfree(tmp);
				break;
			}
		}
		if (0 == flag) {
			/*
			 * The capability is not present in the list of the
			 * hashes stored, hence return failure
			 */
			printk(KERN_ALERT
			       "Invalid capabiliy written to /dev/capuse \n");
			retval = -EFAULT;
			goto out;
		}
	}
	*f_pos += count;
	retval = count;
	/* update the size */
	if (dev->size < *f_pos)
		dev->size = *f_pos;

out:
	kfree(node_ptr);
	kfree(user_buf);
	kfree(user_buf_running);
	kfree(hash_str);
	up(&dev->sem);
	return retval;
}

static const struct file_operations cap_fops = {
	.owner = THIS_MODULE,
	.write = cap_write,
	.open = cap_open,
	.release = cap_release,
};

static void cap_cleanup_module(void)
{
	int i;
	dev_t devno = MKDEV(cap_major, cap_minor);
	if (cap_devices) {
		for (i = 0; i < cap_nr_devs; i++) {
			cap_trim(cap_devices + i);
			cdev_del(&cap_devices[i].cdev);
		}
		kfree(cap_devices);
	}
	unregister_chrdev_region(devno, cap_nr_devs);

}

static void cap_setup_cdev(struct cap_dev *dev, int index)
{
	int err, devno = MKDEV(cap_major, cap_minor + index);
	cdev_init(&dev->cdev, &cap_fops);
	dev->cdev.owner = THIS_MODULE;
	dev->cdev.ops = &cap_fops;
	err = cdev_add(&dev->cdev, devno, 1);
	if (err)
		printk(KERN_NOTICE "Error %d adding cap%d", err, index);
}

static int cap_init_module(void)
{
	int result, i;
	dev_t dev = 0;

	if (cap_major) {
		dev = MKDEV(cap_major, cap_minor);
		result = register_chrdev_region(dev, cap_nr_devs, "cap");
	} else {
		result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
					     "cap");
		cap_major = MAJOR(dev);
	}

	if (result < 0) {
		printk(KERN_WARNING "cap: can't get major %d\n",
		       cap_major);
		return result;
	}

	cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
			      GFP_KERNEL);
	if (!cap_devices) {
		result = -ENOMEM;
		goto fail;
	}

	/* Initialize each device. */
	for (i = 0; i < cap_nr_devs; i++) {
		cap_devices[i].node_size = cap_node_size;
		init_MUTEX(&cap_devices[i].sem);
		cap_setup_cdev(&cap_devices[i], i);
	}

	return 0;

fail:
	cap_cleanup_module();
	return result;
}

module_init(cap_init_module);
module_exit(cap_cleanup_module);


