1 /* ******** netUstad: Network Ustadi (Network Master) *********/
2 /* This software is Copyright (C) 2004 by Ozkan KIRIK. */
3 /* Permission is granted to redistribute and modify this */
4 /* software under the terms of the GNU General Public License */
5 /* available at http://www.gnu.org/ */
6 /**************************************************************/
7
8 #include "common.h"
9
10 /******************/
11 /* Manage Request */
12 /******************/
13 void
accept_request(nunetwork_socket client,struct nunetwork_headerstruct * headerbuf)14 accept_request(nunetwork_socket client, struct nunetwork_headerstruct *headerbuf)
15 {
16 int auth_form = 0;
17 int p = 0,i,t;
18 char path[512], parameters[512];
19 char env_str[512];
20 struct stat st;
21 int cgi = 0; /* becomes true if server decides this is a CGI program */
22 char *query_string = NULL;
23 char *tmp_str = NULL;
24 char *tmp_url = NULL;
25 char *client_sid = " ";
26 char method[5];
27 char url[256];
28 char header[256];
29 char value[256];
30 /* Vars for processing HTTP 304*/
31 /*enum en_day { Sun = 0, Mon, Tue, Wed, Thu, Fri, Sat} days;
32 enum en_month { Jan = 0, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } months;*/
33 /*char *withoutsession[] = {
34 "/netustad.css",
35 "/authform",
36 "/images/bg.png",
37 "/images/buton_0.png",
38 "/images/buton_1.png",
39 "/images/buton_2.png",
40 "/images/buton_3.png",
41 "/images/buton_4.png",
42 "/images/buton_5.png",
43 "/images/buton_6.png",
44 "/images/buton_7.png",
45 "/images/banner.png",
46 "/images/banner-alt.png",
47 "/images/menu_login.png",
48 "/images/menu_rulelist.png",
49 "/images/menu_addrule.png",
50 "/images/menu_logout.png",
51 NULL
52 };
53 int ifwithoutsession=0;*/
54 /*struct tm zamanstr;
55 time_t zaman_t;
56 char str4[5]="123";*/
57 char *start;
58 /*****************************************/
59
60 /* Processing the header buffer */
61 /* GET request is saved to be processed at the end*/
62 for (t=0; t< headerbuf->number_of_headers; t++) {
63
64 if (!strcasecmp(headerbuf->headers[t].header_id, "POST") ) {
65 /* sorry maybe next time */
66 unimplemented(client);
67 return;
68 } else if (!strcasecmp(headerbuf->headers[t].header_id, "HEAD")) {
69 tmp_url = strdup(headerbuf->headers[t].header_value);
70
71 /*Getting the requested url */
72 start = headerbuf->headers[t].header_value;
73 while (*start!=' ' || *start!='\t') start++;
74 tmp_url = strstr(start, "HTTP/") - 1;
75 while ( *tmp_url!= ' ' || *tmp_url != '\t' ) tmp_url--;
76 snprintf(url, tmp_url - start + 1, "script%s", start );
77 headers(client, url);
78 return;
79 } else if (!strcasecmp(headerbuf->headers[t].header_id, "GET")) {
80 /* this is it ... getting the method and the url without HTTP id */
81 strncpy(method, headerbuf->headers[t].header_id, sizeof(method));
82 strncpy(url, headerbuf->headers[t].header_value, sizeof(url));
83 i=0; while(url[i++]!=' ');
84 url[i-1]='\0';
85 /*} else if (!strcasecmp(headerbuf->headers[t].header_id, "If-Modified-Since")) {*/
86
87 /* Processing If-Modified-Since header value if its not related with cgis */
88 /*if ( (strstr(url, ".png")!=NULL && strstr(url, "images")!=NULL) ||
89 strstr(url, "netustad.css") ) {*/
90
91 /* Getting Day */
92 /* HTTP/1.1 304 Not Modified
93 Date: Fri, 31 Dec 1999 23:59:59 GMT */
94
95 /*start = headerbuf->headers[t].header_value;
96 if (strlen(start)>10) {
97 while (*start==' ') start++;
98 start+=5;
99 snprintf(str4, 2, start, "%s");
100 zamanstr.tm_mday=atoi(start);
101
102 start+=2;
103 snprintf(str4, 3, start, "%s");
104 zamanstr.tm_mon=months[str4];
105
106 start+=4;
107 snprintf(str4, 4, start, "%s");
108 zamanstr.tm_year= atoi(str4)-1900;
109
110 start+=5;
111 snprintf(str4, 2, start, "%s");
112 zamanstr.tm_hour=atoi(str4);
113
114 start+=3;
115 snprintf(str4, 2, start, "%s");
116 zamanstr.tm_min=atoi(str4);
117
118 start+=3;
119 snprintf(str4, 2, start, "%s");
120 zamanstr.tm_sec=atoi(str4);
121 zamanstr.tm_isdst=-1;
122
123 zaman_t = mktime(&zamanstr);
124
125 }
126
127
128 }*/
129
130 }
131 }
132
133 query_string = url;
134 while ((*query_string != '?') && (*query_string != '\0'))
135 query_string++;
136
137 if (*query_string == '?') {
138 cgi = 1;
139 *query_string = '\0';
140 query_string++;
141 }
142
143 /*******************/
144 /* Parse SessionID */
145 /*******************/
146 if (query_string[0] == 0) {
147 tmp_str = url;
148 tmp_url = strtok(tmp_str, "$\n");
149 while (tmp_url != NULL && (int) p <= (int) strlen(value))
150 value[p++] = *tmp_url++;
151 } else {
152 tmp_str = strdup(query_string);
153 query_string = strtok(tmp_str, "$\n");
154 }
155 client_sid = strtok(NULL, "$\n");
156 if (client_sid == 0)
157 client_sid = "$";
158
159 /****************************/
160 /* add script folder to url */
161 /****************************/
162 snprintf(path, sizeof (path)-1, "script%s", url);
163
164 /*****************************/
165 /* Check Unwanted Characters */
166 /*****************************/
167 if (strstr(path, "..") != NULL) {
168 server_sid[0] = '$';
169 server_sid[1] = '\0';
170 snprintf(parameters, sizeof (parameters)-1,
171 " -- %s: %s. %s: %s\n",
172 (char *) gettext("Bad Request From"),
173 (char *) inet_ntoa(client_name.sin_addr),
174 (char *) gettext("The Request is"),
175 (char *) path);
176 log_msg(mainlogfile, parameters, 1);
177 log_msg(mainlogfile, gettext("Session Killed Because of Bad Request\n"), 1);
178 snprintf(auth_msg, sizeof (auth_msg)-1, " ");
179 auth_form = 1;
180 }
181
182 /************************/
183 /* Check Session Expire */
184 /************************/
185 time(¤tsec);
186 if ((long) currentsec - (long) lastactionsec <= sesexpiretime) { /* Session Not Expired */
187 time(&lastactionsec);
188 } else { /* Session Expired, close session */
189 server_sid[0] = '$';
190 server_sid[1] = '\0';
191 if (!(rightcmp(path, "/netustad.css") ||\
192 rightcmp(path, "/authform") ||\
193 rightcmp(path, "/images/bg.png") ||\
194 rightcmp(path, "/images/buton_0.png") ||\
195 rightcmp(path, "/images/buton_1.png") ||\
196 rightcmp(path, "/images/buton_2.png") ||\
197 rightcmp(path, "/images/buton_3.png") ||\
198 rightcmp(path, "/images/buton_4.png") ||\
199 rightcmp(path, "/images/buton_5.png") ||\
200 rightcmp(path, "/images/buton_6.png") ||\
201 rightcmp(path, "/images/buton_7.png") ||\
202 rightcmp(path, "/images/banner.png") ||\
203 rightcmp(path, "/images/banner-alt.png") ||\
204 rightcmp(path, "/images/editor.png") ||\
205 rightcmp(path, "/images/eraser.png") ||\
206 rightcmp(path, "/images/menu_rulelist.png") ||\
207 rightcmp(path, "/images/menu_addrule.png") ||\
208 rightcmp(path, "/images/menu_logout.png") ||\
209 rightcmp(path, "/images/menu_login.png"))) {
210 log_msg(mainlogfile, gettext("Administrator's Session Expired!\n"), 1);
211 }
212 /*t=0;
213 while (withoutsession[t]!=NULL && !rightcmp(path, withoutsession[t])) {
214 t++;
215 }
216 if (withoutsession[t]!=NULL && !rightcmp(path, withoutsession[t])) {
217 log_msg(mainlogfile, gettext("Administrator's Session Expired!\n"), 1);
218 } else {
219 ifwithoutsession=1;
220 }*/
221 snprintf(auth_msg, sizeof (auth_msg)-1, gettext("Session Expired!"));
222 auth_form = 1;
223 }
224
225 /********************/
226 /* Check Session ID */
227 /********************/
228 if (strcmp(server_sid, "$") != 0 && *client_sid != '$')
229 if (strcmp(client_sid, server_sid) != 0 ||
230 strcmp(client_ip,
231 (char *) inet_ntoa(client_name.sin_addr)) != 0) {
232 snprintf(auth_msg, sizeof (auth_msg)-1, gettext("You are not logged in!"));
233 auth_form = 1;
234 } else
235 auth_form = 0;
236 else {
237 if ((long) lastactionsec == 0)
238 snprintf(auth_msg, sizeof (auth_msg)-1, " ");
239 auth_form = 1;
240 }
241
242 /********************************/
243 /* Define Environment Variables */
244 /********************************/
245 snprintf(env_str, sizeof (env_str)-1, "netustadversion=%s", NUVERSION);
246 env_p[0] = strdup(env_str); /* netustad version */
247
248 snprintf(env_str, sizeof (env_str)-1, "work_path=%s/script", workdir);
249 env_p[1] = strdup(env_str); /* work_path */
250
251 env_p[2] = "auth_msg="; /* authform message */
252
253 snprintf(env_str, sizeof (env_str)-1, "server_sid=%s", server_sid);
254 env_p[3] = strdup(env_str); /* server session id */
255
256 snprintf(env_str, sizeof (env_str)-1, "fw_cmd=%s", fw_cmd);
257 env_p[4] = strdup(env_str); /* iptables command */
258
259 snprintf(env_str, sizeof (env_str)-1, "TEXTDOMAIN=%s", PACKAGE);
260 env_p[5] = strdup(env_str); /* TEXTDOMAIN (for gettext) */
261
262 snprintf(env_str, sizeof (env_str)-1, "TEXTDOMAINDIR=%s", PACKAGE_LOCALE_DIR);
263 env_p[6] = strdup(env_str); /* TEXTDOMAINDIR (for gettext) */
264
265 snprintf(env_str, sizeof (env_str)-1, "LC_ALL=%s", lc_all );
266 env_p[7] = strdup(env_str); /* Choose locale */
267
268 snprintf(env_str, sizeof (env_str)-1, "gettext_cmd=%s", gettext_cmd);
269 env_p[8] = strdup(env_str); /* gettext command */
270
271 snprintf(env_str, sizeof (env_str)-1, "cat_cmd=%s", cat_cmd);
272 env_p[9] = strdup(env_str); /* full path of cat command */
273
274 snprintf(env_str, sizeof (env_str)-1, "awk_cmd=%s", awk_cmd);
275 env_p[10] = strdup(env_str); /* full path of awk command */
276
277 snprintf(env_str, sizeof (env_str)-1, "MM_CHARSET=%s", gettext("charset"));
278 env_p[11] = strdup(env_str); /* charset environ */
279
280 snprintf(env_str, sizeof (env_str)-1, "LANG=%s", lc_all );
281 env_p[12] = strdup(env_str); /* LANG environ */
282
283 snprintf(env_str, sizeof (env_str)-1, "netstat_cmd=%s", netstat_cmd );
284 env_p[13] = strdup(env_str); /* netstat_cmd environ */
285
286 snprintf(env_str, sizeof (env_str)-1, "grep_cmd=%s", grep_cmd );
287 env_p[14] = strdup(env_str); /* grep_cmd environ */
288
289 snprintf(env_str, sizeof (env_str)-1, "tr_cmd=%s", tr_cmd );
290 env_p[15] = strdup(env_str); /* tr_cmd environ */
291
292 snprintf(env_str, sizeof (env_str)-1, "sed_cmd=%s", sed_cmd );
293 env_p[16] = strdup(env_str); /* sed_cmd environ */
294
295 snprintf(env_str, sizeof (env_str)-1, "tail_cmd=%s", tail_cmd );
296 env_p[17] = strdup(env_str); /* tail_cmd environ */
297
298 snprintf(env_str, sizeof (env_str)-1, "route_cmd=%s", route_cmd );
299 env_p[18] = strdup(env_str); /* route_cmd environ */
300
301 snprintf(env_str, sizeof (env_str)-1, "QUERY_STRING=a");
302 env_p[19] = strdup(env_str); /* QUERY_STRING environ */
303
304 snprintf(env_str, sizeof (env_str)-1, "ifconfig_cmd=%s", ifconfig_cmd );
305 env_p[20] = strdup(env_str); /* ifconfig_cmd environ */
306
307 env_p[21] = NULL; /*temporary variable */
308 env_p[22] = NULL; /*temporary variable */
309 env_p[23] = NULL; /*parameter terminate */
310
311 /***************************/
312 /* Parse Requested Address */
313 /***************************/
314
315 /* If Logout Requested Close Session and Goto Auth */
316 if (rightcmp(path, "/logout")) {
317 server_sid[0] = '$';
318 server_sid[1] = '\0';
319 snprintf(auth_msg, sizeof (auth_msg)-1, gettext("You are logged out"));
320 log_msg(mainlogfile, gettext("Administrator logged out\n"), 1);
321 auth_form = 1;
322 /*} else if (ifwithoutsession && strcmp(withoutsession[t], "/authform")!=0) {
323 snprintf(path, sizeof(path)-1, "script%s", withoutsession[t]);
324 }*/
325 } else if (rightcmp(path, "/images/bg.png")) {
326 snprintf(path, sizeof (path)-1, "script/images/bg.png");
327 } else if (rightcmp(path, "/images/buton_0.png")) {
328 snprintf(path, sizeof(path)-1, "script/images/buton_0.png");
329 } else if (rightcmp(path, "/images/buton_1.png")) {
330 snprintf(path, sizeof(path)-1, "script/images/buton_1.png");
331 } else if (rightcmp(path, "/images/buton_2.png")) {
332 snprintf(path, sizeof(path)-1, "script/images/buton_2.png");
333 } else if (rightcmp(path, "/images/buton_3.png")) {
334 snprintf(path, sizeof(path)-1, "script/images/buton_3.png");
335 } else if (rightcmp(path, "/images/menu_login.png")) {
336 snprintf(path, sizeof(path)-1, "script/images/menu_login.png");
337 } else if (rightcmp(path, "/images/menu_logout.png")) {
338 snprintf(path, sizeof(path)-1, "script/images/menu_logout.png");
339 } else if (rightcmp(path, "/images/menu_addrule.png")) {
340 snprintf(path, sizeof(path)-1, "script/images/menu_addrule.png");
341 } else if (rightcmp(path, "/images/menu_rulelist.png")) {
342 snprintf(path, sizeof(path)-1, "script/images/menu_rulelist.png");
343 } else if (rightcmp(path, "/images/buton_4.png")) {
344 snprintf(path, sizeof(path)-1, "script/images/buton_4.png");
345 } else if (rightcmp(path, "/images/buton_5.png")) {
346 snprintf(path, sizeof(path)-1, "script/images/buton_5.png");
347 } else if (rightcmp(path, "/images/buton_7.png")) {
348 snprintf(path, sizeof(path)-1, "script/images/buton_7.png");
349 } else if (rightcmp(path, "/images/banner.png")) {
350 snprintf(path, sizeof(path)-1, "script/images/banner.png");
351 } else if (rightcmp(path, "/images/banner-alt.png")) {
352 snprintf(path, sizeof(path)-1, "script/images/banner-alt.png");
353 } else if (rightcmp(path, "/images/editor.png")) {
354 snprintf(path, sizeof(path)-1, "script/images/editor.png");
355 } else if (rightcmp(path, "/images/eraser.png")) {
356 snprintf(path, sizeof(path)-1, "script/images/eraser.png");
357 } else if (rightcmp(path, "/netustad.css")) {
358 snprintf(path, sizeof(path)-1, "script/netustad.css");
359 }
360
361 /* Other Requests */
362 if (auth_form == 1 && \
363 !(rightcmp(path, "/auth")) && \
364 !(rightcmp(path, "/netustad.css")) && \
365 !(rightcmp(path, "/images/bg.png")) && \
366 !(rightcmp(path, "/images/buton_0.png")) && \
367 !(rightcmp(path, "/images/buton_1.png")) && \
368 !(rightcmp(path, "/images/buton_2.png")) && \
369 !(rightcmp(path, "/images/buton_3.png")) && \
370 !(rightcmp(path, "/images/buton_4.png")) && \
371 !(rightcmp(path, "/images/buton_5.png")) && \
372 !(rightcmp(path, "/images/buton_6.png")) && \
373 !(rightcmp(path, "/images/buton_7.png")) && \
374 !(rightcmp(path, "/images/banner.png")) && \
375 !(rightcmp(path, "/images/banner-alt.png")) && \
376 !(rightcmp(path, "/images/editor.png")) && \
377 !(rightcmp(path, "/images/eraser.png")) && \
378 !(rightcmp(path, "/images/menu_logout.png")) && \
379 !(rightcmp(path, "/images/menu_addrule.png")) && \
380 !(rightcmp(path, "/images/menu_rulelist.png")) && \
381 !(rightcmp(path, "/images/menu_login.png"))) {
382 snprintf(env_str, sizeof (env_str)-1, "auth_msg=%s", auth_msg);
383 env_p[2] = strdup(env_str);
384 snprintf(path, sizeof (path)-1, "script/authform");
385 } else if (path[strlen(path) - 1] == '/') {
386 strncat(path, "showrule", (size_t) (sizeof (path) - 1 - strlen(path)));
387 } else if (rightcmp(path, "/edit")) {
388 snprintf(env_str, sizeof (env_str)-1, "ruleno=%s", strtok(query_string,"@\n"));
389 env_p[21] = strdup(env_str);
390 #ifdef LINUX
391 snprintf(env_str, sizeof (env_str)-1, "chain=%s", strtok(NULL,"@\n"));
392 env_p[22] = strdup(env_str);
393 #endif
394 strncat(path, "form", (size_t) (sizeof (path) - 1 - strlen(path)));
395
396 } else if (rightcmp(path, "/if_edit")) {
397 snprintf(env_str, sizeof (env_str)-1, "if_name=%s", strtok(query_string,"@\n"));
398 env_p[21] = strdup(env_str);
399 snprintf(path, sizeof(path)-1, "script/if_edit");
400
401 } else if (rightcmp(path, "/nat_del")) {
402 snprintf(env_str, sizeof (env_str)-1, "nat_name=%s", strtok(query_string,"@\n"));
403 env_p[21] = strdup(env_str);
404 snprintf(path, sizeof(path)-1, "script/nat_del");
405
406 } else if (rightcmp(path, "/rt_del")) {
407 snprintf(env_str, sizeof (env_str)-1, "route=%s", strtok(query_string,"@\n"));
408 env_p[21] = strdup(env_str);
409 snprintf(path, sizeof(path)-1, "script/rt_del");
410
411 } else if (rightcmp(path, "/auth") && auth_form == 1) {
412 snprintf(path, sizeof (path)-1, "%s", auth(query_string));
413 snprintf(env_str, sizeof (env_str)-1, "auth_msg=%s", auth_msg);
414 env_p[2] = strdup(env_str);
415 snprintf(env_str, sizeof (env_str)-1, "server_sid=%s", server_sid);
416 env_p[3] = strdup(env_str);
417 #ifdef FREEBSD
418 } else if (rightcmp(path, "/write")) {
419 snprintf(path, sizeof(path)-1, "script/writeconfig");
420 #endif
421 }
422
423 /* If Rule Deleting Requested ("del" word) */
424 if (rightcmp(path, "/del")) {
425 strncpy(path, fw_cmd, sizeof (path)-1);
426 deleterule(client, path, header, query_string);
427 } else if (rightcmp(path, "/addnew")) {
428 strncpy(path, fw_cmd, sizeof (path)-1);
429 addnewrule(client, path, header, query_string);
430 } else if (rightcmp(path, "/applyedit")) {
431 strncpy(path, fw_cmd, sizeof (path)-1);
432 editrule(client, path, header, query_string);
433 } else if (stat(path, &st) == -1) {
434 snprintf(log_msg_text, sizeof(log_msg_text)-1, gettext("File not found: %s"), path);
435 log_msg(logfile, log_msg_text, 1);
436 not_found(client);
437 } else {
438 if ((st.st_mode & S_IFMT) == S_IFDIR)
439 strncat(path, "/showrule",
440 (size_t) (sizeof (path) - 1 - strlen(path)));
441 if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP)
442 || (st.st_mode & S_IXOTH))
443 cgi = 1;
444 if (!cgi)
445 serve_file(client, path);
446 else
447 snprintf(env_str, sizeof (env_str)-1, "QUERY_STRING=%s", query_string);
448 env_p[19] = strdup(env_str); /* QUERY_STRING environ */
449 execute_cgi(client, path, header, query_string, env_p, 1);
450 }
451 return;
452 }
453
454 /******************************/
455 /* Send client a regular file */
456 /******************************/
457 void
serve_file(nunetwork_socket client,char * filename)458 serve_file(nunetwork_socket client, char *filename)
459 {
460 FILE *resource = NULL;
461 char buf[1024];
462
463 buf[0] = 'A';
464 buf[1] = '\0';
465 resource = fopen(filename, "r");
466 if (resource == NULL)
467 not_found(client);
468 else {
469 headers(client, filename);
470 binarycat(client, resource);
471 }
472 fclose(resource);
473 }
474
475 /*********************************/
476 /* Compare two string from right */
477 /*********************************/
478 /* For example: */
479 /* str="abcd"; look4str="cd"*/
480 /* rightcmp(str,look4str) = 1 */
481 /* str="abcd"; look4str="ab"*/
482 /* rightcmp(str,look4str) = 0 */
483 /*********************************/
484 int
rightcmp(char * str,char * look4str)485 rightcmp(char *str, char *look4str)
486 {
487 int i = 0;
488 if (look4str == NULL || str == NULL) {
489 return 0;
490 } /* Oopps, invalid number of args */
491 if (strlen(look4str) > strlen(str)) { /* If look4str is longer then str, compare cannot be done */
492 return 0;
493 }
494 for (i = strlen(look4str); i >= 1; i--) {
495 if ((char) str[strlen(str) - i] !=
496 (char) look4str[strlen(look4str) - i]) {
497 return 0;
498 }
499 }
500 return 1;
501 }
502