/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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"); }