summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ncpfs')
-rw-r--r--fs/ncpfs/Config.in2
-rw-r--r--fs/ncpfs/Makefile3
-rw-r--r--fs/ncpfs/dir.c2
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/ncpfs/ioctl.c33
-rw-r--r--fs/ncpfs/ncpsign_kernel.c114
-rw-r--r--fs/ncpfs/ncpsign_kernel.h16
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