diff options
Diffstat (limited to 'fs/ncpfs')
-rw-r--r-- | fs/ncpfs/Config.in | 2 | ||||
-rw-r--r-- | fs/ncpfs/Makefile | 3 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 2 | ||||
-rw-r--r-- | fs/ncpfs/inode.c | 4 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 33 | ||||
-rw-r--r-- | fs/ncpfs/ncpsign_kernel.c | 114 | ||||
-rw-r--r-- | fs/ncpfs/ncpsign_kernel.h | 16 |
7 files changed, 155 insertions, 19 deletions
diff --git a/fs/ncpfs/Config.in b/fs/ncpfs/Config.in index 48cf4aa86..bdb973e41 100644 --- a/fs/ncpfs/Config.in +++ b/fs/ncpfs/Config.in @@ -1,7 +1,7 @@ # # NCP Filesystem configuration # -# bool ' Packet singatures' CONFIG_NCPFS_PACKET_SIGNING +bool ' Packet singatures' CONFIG_NCPFS_PACKET_SIGNING bool ' Proprietary file locking' CONFIG_NCPFS_IOCTL_LOCKING bool ' Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG bool ' Use NFS namespace if available' CONFIG_NCPFS_NFS_NS diff --git a/fs/ncpfs/Makefile b/fs/ncpfs/Makefile index 5c83ada11..9c33bc515 100644 --- a/fs/ncpfs/Makefile +++ b/fs/ncpfs/Makefile @@ -8,7 +8,8 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := ncpfs.o -O_OBJS := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o +O_OBJS := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o \ + ncpsign_kernel.o M_OBJS := $(O_TARGET) # If you want debugging output, please uncomment the following line diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 8424b2ec7..bec1c55a2 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -112,7 +112,7 @@ static int ncp_hash_dentry(struct dentry *, struct qstr *); static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); static void ncp_delete_dentry(struct dentry *); -static struct dentry_operations ncp_dentry_operations = +struct dentry_operations ncp_dentry_operations = { ncp_lookup_validate, /* d_validate(struct dentry *) */ ncp_hash_dentry, /* d_hash */ diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index f11f4640c..c872c2b84 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -25,9 +25,6 @@ #include <linux/fcntl.h> #include <linux/malloc.h> #include <linux/init.h> -#ifdef CONFIG_KERNELD -#include <linux/kerneld.h> -#endif #include <linux/ncp_fs.h> #include "ncplib_kernel.h" @@ -287,6 +284,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) server->buffer_size = 0; server->conn_status = 0; server->root_dentry = NULL; + server->root_setuped = 0; #ifdef CONFIG_NCPFS_PACKET_SIGNING server->sign_wanted = 0; server->sign_active = 0; diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 078d26596..2df6fee09 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -32,6 +32,22 @@ int ncp_ioctl(struct inode *inode, struct file *filp, struct ncp_ioctl_request request; struct ncp_fs_info info; +#ifdef NCP_IOC_GETMOUNTUID_INT + /* remove after ncpfs-2.0.13/2.2.0 gets released */ + if ((NCP_IOC_GETMOUNTUID != NCP_IOC_GETMOUNTUID_INT) && + (cmd == NCP_IOC_GETMOUNTUID_INT)) { + int tmp = server->m.mounted_uid; + + if ( (permission(inode, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) + { + return -EACCES; + } + if (put_user(tmp, (unsigned int*) arg)) return -EFAULT; + return 0; + } +#endif /* NCP_IOC_GETMOUNTUID_INT */ + switch (cmd) { case NCP_IOC_NCPREQUEST: @@ -80,6 +96,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp, && (current->uid != server->m.mounted_uid)) { return -EACCES; } + if (server->root_setuped) return -EBUSY; + server->root_setuped = 1; return ncp_conn_logged_in(server); case NCP_IOC_GET_FS_INFO: @@ -121,19 +139,6 @@ int ncp_ioctl(struct inode *inode, struct file *filp, put_user(server->m.mounted_uid, (uid_t *) arg); return 0; - case NCP_IOC_GETMOUNTUID_INT: - if ( (permission(inode, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) - { - return -EACCES; - } - - { - unsigned int tmp=server->m.mounted_uid; - if (put_user(tmp, (unsigned long*) arg)) return -EFAULT; - } - return 0; - #ifdef CONFIG_NCPFS_MOUNT_SUBDIR case NCP_IOC_GETROOT: { @@ -168,6 +173,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, { return -EACCES; } + if (server->root_setuped) return -EBUSY; if (copy_from_user(&sr, (struct ncp_setroot_ioctl*)arg, sizeof(sr))) return -EFAULT; @@ -184,6 +190,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, } } dentry = server->root_dentry; + server->root_setuped = 1; if (dentry) { struct inode* inode = dentry->d_inode; diff --git a/fs/ncpfs/ncpsign_kernel.c b/fs/ncpfs/ncpsign_kernel.c new file mode 100644 index 000000000..bae89c197 --- /dev/null +++ b/fs/ncpfs/ncpsign_kernel.c @@ -0,0 +1,114 @@ +/* + * ncpsign_kernel.c + * + * Arne de Bruijn (arne@knoware.nl), 1997 + * + */ + +#include <linux/config.h> + +#ifdef CONFIG_NCPFS_PACKET_SIGNING + +#include <linux/string.h> +#include <linux/ncp.h> +#include "ncpsign_kernel.h" + +#define rol32(i,c) (((((i)&0xffffffff)<<c)&0xffffffff)| \ + (((i)&0xffffffff)>>(32-c))) +/* i386: 32-bit, little endian, handles mis-alignment */ +#ifdef __i386__ +#define GET_LE32(p) (*(int *)(p)) +#define PUT_LE32(p,v) { *(int *)(p)=v; } +#else +/* from include/ncplib.h */ +#define BVAL(buf,pos) (((__u8 *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) +#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) + +static inline word +WVAL_LH(__u8 * buf, int pos) +{ + return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8; +} +static inline dword +DVAL_LH(__u8 * buf, int pos) +{ + return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16; +} +static inline void +WSET_LH(__u8 * buf, int pos, word val) +{ + BSET(buf, pos, val & 0xff); + BSET(buf, pos + 1, val >> 8); +} +static inline void +DSET_LH(__u8 * buf, int pos, dword val) +{ + WSET_LH(buf, pos, val & 0xffff); + WSET_LH(buf, pos + 2, val >> 16); +} + +#define GET_LE32(p) DVAL_LH(p,0) +#define PUT_LE32(p,v) DSET_LH(p,0,v) +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) + +static void nwsign(char *r_data1, char *r_data2, char *outdata) { + int i; + unsigned int w0,w1,w2,w3; + static int rbit[4]={0, 2, 1, 3}; +#ifdef __i386__ + unsigned int *data2=(int *)r_data2; +#else + unsigned int data2[16]; + for (i=0;i<16;i++) + data2[i]=GET_LE32(r_data2+(i<<2)); +#endif + w0=GET_LE32(r_data1); + w1=GET_LE32(r_data1+4); + w2=GET_LE32(r_data1+8); + w3=GET_LE32(r_data1+12); + for (i=0;i<16;i+=4) { + w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3); + w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7); + w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11); + w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3); + w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5); + w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9); + w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3); + w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9); + w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11); + w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15); + } + PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff); + PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff); + PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff); + PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff); +} + +/* Make a signature for the current packet and add it at the end of the */ +/* packet. */ +void sign_packet(struct ncp_server *server, int *size) { + char data[64]; + + memset(data,0,64); + memcpy(data,server->sign_root,8); + PUT_LE32(data+8,(*size)); + memcpy(data+12,server->packet+sizeof(struct ncp_request_header)-1, + min((*size)-sizeof(struct ncp_request_header)+1,52)); + + nwsign(server->sign_last,data,server->sign_last); + + memcpy(server->packet+(*size),server->sign_last,8); + (*size)+=8; +} + +#endif /* CONFIG_NCPFS_PACKET_SIGNING */ + diff --git a/fs/ncpfs/ncpsign_kernel.h b/fs/ncpfs/ncpsign_kernel.h new file mode 100644 index 000000000..85974f346 --- /dev/null +++ b/fs/ncpfs/ncpsign_kernel.h @@ -0,0 +1,16 @@ +/* + * ncpsign_kernel.h + * + * Arne de Bruijn (arne@knoware.nl), 1997 + * + */ + +#ifndef _NCPSIGN_KERNEL_H +#define _NCPSIGN_KERNEL_H + +#include <linux/ncp_fs.h> +#include <linux/ncp_fs_sb.h> + +void sign_packet(struct ncp_server *server, int *size); + +#endif |