Viewing file: security.c (5.25 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
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/slab.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, O_RDONLY, 0); if (IS_ERR(filp)) 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(Filename,List->value)!=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); strncpy(String,"Dynamic strings are : -",255); Temp = DynamicList; while (Temp!=NULL) { max=253 - strlen(String) - strlen(Temp->value); strncat(String,Temp->value,max); max=253 - strlen(String) - 3; strncat(String,"- -",max); Temp = Temp->Next; } LeaveFunction("GetSecureString"); }
|