linux-old/net/khttpd/security.c
<<
>>
Prefs
   1/*
   2
   3kHTTPd -- the next generation
   4
   5Permissions/Security functions
   6
   7*/
   8
   9/****************************************************************
  10 *      This program is free software; you can redistribute it and/or modify
  11 *      it under the terms of the GNU General Public License as published by
  12 *      the Free Software Foundation; either version 2, or (at your option)
  13 *      any later version.
  14 *
  15 *      This program is distributed in the hope that it will be useful,
  16 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *      GNU General Public License for more details.
  19 *
  20 *      You should have received a copy of the GNU General Public License
  21 *      along with this program; if not, write to the Free Software
  22 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 *
  24 ****************************************************************/
  25
  26
  27#include <linux/kernel.h>
  28
  29#include <linux/errno.h>
  30#include <linux/slab.h>
  31#include <linux/net.h>
  32#include <linux/sched.h>
  33#include <linux/skbuff.h>
  34#include <linux/smp_lock.h>
  35#include <linux/un.h>
  36#include <linux/unistd.h>
  37
  38#include <net/ip.h>
  39#include <net/sock.h>
  40#include <net/tcp.h>
  41
  42#include <asm/atomic.h>
  43#include <asm/semaphore.h>
  44#include <asm/processor.h>
  45#include <asm/uaccess.h>
  46
  47#include <linux/file.h>
  48
  49#include "sysctl.h"
  50#include "security.h"
  51#include "prototypes.h"
  52
  53/*
  54
  55The basic security function answers "Userspace" when any one of the following 
  56conditions is met:
  57
  581) The filename contains a "?" (this is before % decoding, all others are 
  59                                after % decoding)
  602) The filename doesn't start with a "/"                                
  613) The file does not exist
  624) The file does not have enough permissions 
  63   (sysctl-configurable, default = worldreadble)
  645) The file has any of the "forbidden" permissions 
  65   (sysctl-configurable, default = execute, directory and sticky)
  666) The filename contains a string as defined in the "Dynamic" list.
  67
  68*/      
  69
  70
  71/* Prototypes */
  72
  73static void DecodeHexChars(char *URL);
  74static struct DynamicString *DynamicList=NULL;
  75
  76        
  77
  78/*
  79
  80The function "OpenFileForSecurity" returns either the "struct file" pointer
  81of the file, or NULL. NULL means "let userspace handle it". 
  82
  83*/
  84struct file *OpenFileForSecurity(char *Filename)
  85{
  86        struct file *filp = NULL;
  87        struct DynamicString *List;
  88        umode_t permission;
  89        
  90        EnterFunction("OpenFileForSecurity");
  91        if (Filename==NULL)
  92                goto out_error;
  93        
  94        if (strlen(Filename)>=256 )
  95                goto out_error;  /* Sanity check */
  96        
  97        /* Rule no. 1  -- No "?" characters */
  98#ifndef BENCHMARK       
  99        if (strchr(Filename,'?')!=NULL)
 100                goto out_error;
 101
 102        /* Intermediate step: decode all %hex sequences */
 103        
 104        DecodeHexChars(Filename);
 105
 106        /* Rule no. 2  -- Must start with a "/" */
 107        
 108        if (Filename[0]!='/')
 109                goto out_error;
 110                
 111#endif
 112        /* Rule no. 3 -- Does the file exist ? */
 113
 114        filp = filp_open(Filename, O_RDONLY, 0);
 115        
 116        if (IS_ERR(filp))
 117                goto out_error;
 118
 119#ifndef BENCHMARK               
 120        permission = filp->f_dentry->d_inode->i_mode;
 121        
 122        /* Rule no. 4 : must have enough permissions */
 123        
 124        if ((permission & sysctl_khttpd_permreq)==0)
 125                goto out_error_put;     
 126
 127        /* Rule no. 5 : cannot have "forbidden" permission */
 128        
 129        if ((permission & sysctl_khttpd_permforbid)!=0)
 130                goto out_error_put;     
 131                
 132        /* Rule no. 6 : No string in DynamicList can be a
 133                        substring of the filename */
 134        
 135        List = DynamicList;
 136        while (List!=NULL)
 137        {
 138                if (strstr(Filename,List->value)!=NULL)
 139                        goto out_error_put;     
 140
 141                List = List->Next;
 142        }
 143        
 144#endif  
 145        LeaveFunction("OpenFileForSecurity - success");
 146out:
 147        return filp;
 148
 149out_error_put:
 150        fput(filp);
 151out_error:
 152        filp=NULL;
 153        LeaveFunction("OpenFileForSecurity - fail");
 154        goto out;
 155}
 156
 157/* 
 158
 159DecodeHexChars does the actual %HEX decoding, in place. 
 160In place is possible because strings only get shorter by this.
 161
 162*/
 163static void DecodeHexChars(char *URL)
 164{
 165        char *Source,*Dest;
 166        int val,val2;
 167        
 168        EnterFunction("DecodeHexChars");
 169        
 170        Source = strchr(URL,'%');
 171        
 172        if (Source==NULL) 
 173                return;
 174                
 175        Dest = Source;
 176        
 177        while (*Source!=0)
 178        {
 179                if (*Source=='%')
 180                {
 181                        Source++;
 182                        val = *Source;
 183                        
 184                        if (val>'Z') val-=0x20;
 185                        val = val - '0';
 186                        if (val<0) val=0; 
 187                        if (val>9) val-=7;
 188                        if (val>15) val=15;
 189                        
 190                        Source++;
 191
 192                        val2 = *Source;
 193                        
 194                        if (val2>'Z') val2-=0x20;
 195                        val2 = val2 - '0';
 196                        if (val2<0) val2=0; 
 197                        if (val2>9) val2-=7;
 198                        if (val2>15) val2=15;
 199
 200                        *Dest=val*16+val2;
 201                } else *Dest = *Source;
 202                Dest++;
 203                Source++;
 204        }
 205        *Dest=0;        
 206        
 207        LeaveFunction("DecodeHexChars");
 208}
 209
 210
 211void AddDynamicString(const char *String)
 212{
 213        struct DynamicString *Temp;
 214        
 215        EnterFunction("AddDynamicString");
 216        
 217        Temp = (struct DynamicString*)kmalloc(sizeof(struct DynamicString),(int)GFP_KERNEL);
 218        
 219        if (Temp==NULL) 
 220                return;
 221                
 222        memset(Temp->value,0,sizeof(Temp->value));
 223        strncpy(Temp->value,String,sizeof(Temp->value)-1);
 224        
 225        Temp->Next = DynamicList;
 226        DynamicList = Temp;
 227        
 228        LeaveFunction("AddDynamicString");
 229}
 230
 231void GetSecureString(char *String)
 232{
 233        struct DynamicString *Temp;
 234        int max;
 235        
 236        EnterFunction("GetSecureString");
 237        
 238        *String = 0;
 239        
 240        memset(String,0,255);
 241        
 242        strncpy(String,"Dynamic strings are : -",255);
 243        Temp = DynamicList;
 244        while (Temp!=NULL)
 245        {
 246                max=253 - strlen(String) - strlen(Temp->value);
 247                strncat(String,Temp->value,max);
 248                max=253 - strlen(String) - 3;
 249                strncat(String,"- -",max);
 250                Temp = Temp->Next;
 251        }       
 252        
 253        LeaveFunction("GetSecureString");
 254}
 255
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.