📄 newkey.c
字号:
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#ifdef CONFIG_KEYS
#include <linux/key.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#endif
#include "../common.h"
#define MY_PROC_DIR "learning-key"
#define PROC_ENTRY_NAME "gateway"
#define DRIVER_AUTHOR "Avinesh Kumar <avinesh.kumar@in.ibm.com>"
#define DRIVER_DESC "Getting started with keys"
#define LICENSE "http://www.openafs.org/dl/license10.html"
#ifdef CONFIG_KEYS
void fresh_session(void);
int proc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
void key_destroy(struct key *key);
void key_desc(const struct key *key, struct seq_file *p);
int instantiate_key(struct key *key, const void *data, size_t datalen);
static int key_match(const struct key *key, const void *description);
static int install_session_keyring(struct task_struct *task,
struct key *keyring);
struct proc_dir_entry *myroot;
struct proc_dir_entry *myentry;
struct key_type *key_type_keyring_orig;
struct file_operations gateway_fops = {
.ioctl = proc_ioctl,
};
struct key_type new_key_type = {
.name = "mykey",
.instantiate = instantiate_key,
.describe = key_desc,
.destroy = key_destroy,
.match = key_match,
};
/* This function creates a new keyring and overrides the session keyring
* of calling task.
*/
static int
install_session_keyring(struct task_struct *task, struct key *keyring)
{
char desc[20];
int retval;
struct key *orig;
sprintf(desc, "session.%u", task->tgid);
/* Get the key tpye of original keyring of calling task */
key_type_keyring_orig = task->user->session_keyring->type;
/* Allocate a key for new session-keyring */
keyring = key_alloc(key_type_keyring_orig,/* Key type*/
desc, /* Key's description */
task->uid, /* UID */
task->gid, /* GID */
task,
KEY_POS_ALL | KEY_USR_ALL,/*perms*/
KEY_ALLOC_IN_QUOTA /* Flags */
);
if(IS_ERR(keyring)){
retval = PTR_ERR(keyring);
goto out;
}
printk(KERN_INFO "keyring allocated successfully.\n");
retval = key_instantiate_and_link(keyring, /* key */
NULL,/* data */
0, /* data length */
NULL, /* target key ring */
NULL /* Authorisation Key */
);
if(retval < 0 ){
key_put(keyring);
goto out;
}
printk(KERN_INFO "keyring instantiated and linked successfully.\n");
/* install the keyring */
spin_lock_irq(&task->sighand->siglock);
orig = task->signal->session_keyring;
task->signal->session_keyring = keyring;
/* On SMP systems, we need this for (write) memory barrier protection */
smp_wmb();
spin_unlock_irq(&task->sighand->siglock);
if(orig){
key_put(orig);
}
out:
return(retval);
}
void key_desc(const struct key *key, struct seq_file *p)
{
seq_puts(p, key->description);
seq_printf(p, ": %u", key->datalen);
}
int instantiate_key(struct key *key, const void *data, size_t datalen)
{
return(SUCCESS);
}
void key_destroy(struct key *key)
{
key_put(key);
}
static int key_match(const struct key *key, const void *description)
{
return strcmp(key->description, description) == 0;
}
void fresh_session(void)
{
key_perm_t perms;
struct key *key;
printk(KERN_INFO "Installing session keyring:\n");
install_session_keyring(current, NULL);
printk(KERN_INFO "New session keyring installed successfully.\n");
perms = KEY_POS_ALL | KEY_USR_ALL;
key = key_alloc(&new_key_type,
"New key type",
0,
0,
current,
perms,
KEY_ALLOC_IN_QUOTA
);
printk(KERN_INFO "key of new type allocated successfully.\n");
if(!IS_ERR(key)){
key_instantiate_and_link(key,
NULL,
sizeof(int),
current->signal->session_keyring,
NULL
);
printk(KERN_INFO "New key type linked to current session.\n");
}
}
int proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
switch(cmd){
case FRESH_SESSION:
fresh_session();
break;
default:
printk(KERN_INFO "Bad Argument.\n");
}
return(SUCCESS);
}
#endif /*ifdef CONFIG_KEYS*/
int init_module(void)
{
printk(KERN_INFO "Loading the module ...\n");
#ifdef CONFIG_KEYS
myroot = proc_mkdir(MY_PROC_DIR, NULL);
if(!myroot){
printk(KERN_ERR "Proc-dir creation failed.\n");
goto err;
}
myentry = create_proc_entry(PROC_ENTRY_NAME, 0666, myroot);
if(!myentry){
printk(KERN_ERR "Proc-entry creation failed.\n");
goto err;
}
myentry->proc_fops = &gateway_fops;
myentry->owner = THIS_MODULE;
register_key_type(&new_key_type);
printk(KERN_INFO "Registered \"learning_key\"\n");
#else
printk(KERN_INFO "Key Retention Service is not available.\n");
printk(KERN_INFO "Get latest kernel from http://kernel.org\n");
printk(KERN_INFO "Enable this feature at kernel configuration time.\n");
#endif
return(SUCCESS);
err:
return(FAILURE);
}
void cleanup_module(void)
{
printk(KERN_INFO "Unloading the module.\n");
#ifdef CONFIG_KEYS
remove_proc_entry(PROC_ENTRY_NAME, myroot);
remove_proc_entry(MY_PROC_DIR, NULL);
unregister_key_type(&new_key_type);
printk(KERN_INFO "Unregistered \"learning_key\"\n");
#endif
}
MODULE_LICENSE(LICENSE);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -