patch-2.3.14 linux/net/khttpd/security.c

Next file: linux/net/khttpd/security.h
Previous file: linux/net/khttpd/rfc_time.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.13/linux/net/khttpd/security.c linux/net/khttpd/security.c
@@ -0,0 +1,271 @@
+/*
+
+kHTTPd -- the next generation
+
+Permissions/Security functions
+
+*/
+
+/****************************************************************
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2, or (at your option)
+ *	any later version.
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************/
+
+
+#include <linux/kernel.h>
+
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/net.h>
+#include <linux/sched.h>
+#include <linux/skbuff.h>
+#include <linux/smp_lock.h>
+#include <linux/un.h>
+#include <linux/unistd.h>
+
+#include <net/ip.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+#include <linux/file.h>
+
+#include "sysctl.h"
+#include "security.h"
+#include "prototypes.h"
+
+/*
+
+The basic security function answers "Userspace" when any one of the following 
+conditions is met:
+
+1) The filename contains a "?" (this is before % decoding, all others are 
+                                after % decoding)
+2) The filename doesn't start with a "/"                                
+3) The file does not exist
+4) The file does not have enough permissions 
+   (sysctl-configurable, default = worldreadble)
+5) The file has any of the "forbidden" permissions 
+   (sysctl-configurable, default = execute, directory and sticky)
+6) The filename contains a string as defined in the "Dynamic" list.
+
+*/	
+
+
+/* Prototypes */
+
+static void DecodeHexChars(char *URL);
+static struct DynamicString *DynamicList=NULL;
+
+	
+
+/*
+
+The function "OpenFileForSecurity" returns either the "struct file" pointer
+of the file, or NULL. NULL means "let userspace handle it". 
+
+*/
+struct file *OpenFileForSecurity(char *Filename)
+{
+	struct file *filp;
+	struct DynamicString *List;
+	umode_t permission;
+	
+	
+
+	EnterFunction("OpenFileForSecurity");
+	if (Filename==NULL)
+		return NULL;
+	
+	if (strlen(Filename)>=256 ) return NULL;  /* Sanity check */
+	
+	/* Rule no. 1  -- No "?" characters */
+#ifndef BENCHMARK	
+	if (strchr(Filename,'?')!=NULL)
+		return NULL;
+
+	/* Intermediate step: decode all %hex sequences */
+	
+	DecodeHexChars(Filename);
+
+	/* Rule no. 2  -- Must start with a "/" */
+	
+	
+	if (Filename[0]!='/')
+		return NULL;
+		
+#endif
+	/* Rule no. 3 -- Does the file exist ? */
+
+	
+		
+	filp = filp_open(Filename,00,O_RDONLY);
+	
+	
+	if ((IS_ERR(filp))||(filp==NULL)||(filp->f_dentry==NULL))
+	{
+		return NULL;
+	}
+
+#ifndef BENCHMARK		
+	permission = filp->f_dentry->d_inode->i_mode;
+	
+	/* Rule no. 4 : must have enough permissions */
+	
+	
+	if ((permission & sysctl_khttpd_permreq)==0)
+	{
+		if (filp!=NULL);
+			fput(filp);
+		filp=NULL;
+		return NULL;
+	}
+		
+	/* Rule no. 5 : cannot have "forbidden" permission */
+	
+	
+	if ((permission & sysctl_khttpd_permforbid)!=0)
+	{
+		if (filp!=NULL)
+			fput(filp);
+		filp=NULL;
+		return NULL;
+	}
+		
+	/* Rule no. 6 : No string in DynamicList can be a
+			substring of the filename */
+			
+	
+	List = DynamicList;
+	
+	while (List!=NULL)
+	{
+		if (strstr(List->value,Filename)!=NULL)
+		{
+			if (filp!=NULL)
+				fput(filp);
+			filp=NULL;
+			return NULL;
+		}
+		List = List->Next;
+	}
+	
+#endif	
+	LeaveFunction("OpenFileForSecurity - success");
+
+	return filp;
+}
+
+/* 
+
+DecodeHexChars does the actual %HEX decoding, in place. 
+In place is possible because strings only get shorter by this.
+
+*/
+static void DecodeHexChars(char *URL)
+{
+	char *Source,*Dest;
+	int val,val2;
+	
+	EnterFunction("DecodeHexChars");
+	
+	Source = strchr(URL,'%');
+	
+	if (Source==NULL) 
+		return;
+		
+	Dest = Source;
+	
+	while (*Source!=0)
+	{
+		if (*Source=='%')
+		{
+			Source++;
+			val = *Source;
+			
+			if (val>'Z') val-=0x20;
+			val = val - '0';
+			if (val<0) val=0; 
+			if (val>9) val-=7;
+			if (val>15) val=15;
+			
+			Source++;
+
+			val2 = *Source;
+			
+			if (val2>'Z') val2-=0x20;
+			val2 = val2 - '0';
+			if (val2<0) val2=0; 
+			if (val2>9) val2-=7;
+			if (val2>15) val2=15;
+
+			*Dest=val*16+val2;
+		} else *Dest = *Source;
+		Dest++;
+		Source++;
+	}
+	*Dest=0;	
+	
+	LeaveFunction("DecodeHexChars");
+}
+
+
+void AddDynamicString(const char *String)
+{
+	struct DynamicString *Temp;
+	
+	EnterFunction("AddDynamicString");
+	
+	Temp = (struct DynamicString*)kmalloc(sizeof(struct DynamicString),(int)GFP_KERNEL);
+	
+	if (Temp==NULL) 
+		return;
+		
+	memset(Temp->value,0,sizeof(Temp->value));
+	strncpy(Temp->value,String,sizeof(Temp->value)-1);
+	
+	Temp->Next = DynamicList;
+	DynamicList = Temp;
+	
+	LeaveFunction("AddDynamicString");
+}
+
+void GetSecureString(char *String)
+{
+	struct DynamicString *Temp;
+	int max;
+	
+	EnterFunction("GetSecureString");
+	
+	*String = 0;
+	
+	memset(String,0,255);
+	
+	strcat(String,"Dynamic strings are : -");
+	Temp = DynamicList;
+	while (Temp!=NULL)
+	{
+		max=253 - strlen(String) - strlen(Temp->value);
+		strncat(String,Temp->value,max);
+		strcat(String,"- -");
+		Temp = Temp->Next;
+	}	
+	
+	LeaveFunction("GetSecureString");
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)