1 /*
2 
3 kHTTPd -- the next generation
4 
5 Permissions/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 
55 The basic security function answers "Userspace" when any one of the following
56 conditions is met:
57 
58 1) The filename contains a "?" (this is before % decoding, all others are
59                                 after % decoding)
60 2) The filename doesn't start with a "/"
61 3) The file does not exist
62 4) The file does not have enough permissions
63    (sysctl-configurable, default = worldreadble)
64 5) The file has any of the "forbidden" permissions
65    (sysctl-configurable, default = execute, directory and sticky)
66 6) The filename contains a string as defined in the "Dynamic" list.
67 
68 */
69 
70 
71 /* Prototypes */
72 
73 static void DecodeHexChars(char *URL);
74 static struct DynamicString *DynamicList=NULL;
75 
76 
77 
78 /*
79 
80 The function "OpenFileForSecurity" returns either the "struct file" pointer
81 of the file, or NULL. NULL means "let userspace handle it".
82 
83 */
OpenFileForSecurity(char * Filename)84 struct 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");
146 out:
147 	return filp;
148 
149 out_error_put:
150 	fput(filp);
151 out_error:
152 	filp=NULL;
153 	LeaveFunction("OpenFileForSecurity - fail");
154 	goto out;
155 }
156 
157 /*
158 
159 DecodeHexChars does the actual %HEX decoding, in place.
160 In place is possible because strings only get shorter by this.
161 
162 */
DecodeHexChars(char * URL)163 static 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 
AddDynamicString(const char * String)211 void 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 
GetSecureString(char * String)231 void 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