diff options
Diffstat (limited to 'source/web/cgi.c')
-rw-r--r-- | source/web/cgi.c | 211 |
1 files changed, 90 insertions, 121 deletions
diff --git a/source/web/cgi.c b/source/web/cgi.c index 7415fbe3f15..0b86265a1e5 100644 --- a/source/web/cgi.c +++ b/source/web/cgi.c @@ -19,7 +19,7 @@ #include "includes.h" -#include "../web/swat_proto.h" +#include "smb.h" #define MAX_VARIABLES 10000 @@ -50,12 +50,12 @@ static void unescape(char *buf) { char *p=buf; - while ((p=strchr_m(p,'+'))) + while ((p=strchr(p,'+'))) *p = ' '; p = buf; - while (p && *p && (p=strchr_m(p,'%'))) { + while (p && *p && (p=strchr(p,'%'))) { int c1 = p[1]; int c2 = p[2]; @@ -111,7 +111,7 @@ static char *grab_line(FILE *f, int *cl) if (c == '\r') continue; - if (strchr_m("\n&", c)) break; + if (strchr("\n&", c)) break; ret[i++] = c; @@ -127,33 +127,40 @@ static char *grab_line(FILE *f, int *cl) with the same name and the same or different values. Takes a file parameter for simulating CGI invocation eg loading saved preferences. ***************************************************************************/ -void cgi_load_variables(void) +void cgi_load_variables(FILE *f1) { + FILE *f = f1; static char *line; char *p, *s, *tok; - int len, i; - FILE *f = stdin; + int len; #ifdef DEBUG_COMMENTS char dummy[100]=""; print_title(dummy); - d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__); + printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__); #endif - if (!content_length) { - p = getenv("CONTENT_LENGTH"); - len = p?atoi(p):0; + if (!f1) { + f = stdin; + if (!content_length) { + p = getenv("CONTENT_LENGTH"); + len = p?atoi(p):0; + } else { + len = content_length; + } } else { - len = content_length; + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); } if (len > 0 && - (request_post || + (f1 || request_post || ((s=getenv("REQUEST_METHOD")) && strcasecmp(s,"POST")==0))) { while (len && (line=grab_line(f, &len))) { - p = strchr_m(line,'='); + p = strchr(line,'='); if (!p) continue; *p = 0; @@ -181,12 +188,19 @@ void cgi_load_variables(void) } } + if (f1) { +#ifdef DEBUG_COMMENTS + printf("<!== End dump in cgi_load_variables() ==>\n"); +#endif + return; + } + fclose(stdin); open("/dev/null", O_RDWR); if ((s=query_string) || (s=getenv("QUERY_STRING"))) { for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) { - p = strchr_m(tok,'='); + p = strchr(tok,'='); if (!p) continue; *p = 0; @@ -214,24 +228,6 @@ void cgi_load_variables(void) #ifdef DEBUG_COMMENTS printf("<!== End dump in cgi_load_variables() ==>\n"); #endif - - /* variables from the client are in display charset - convert them - to our internal charset before use */ - for (i=0;i<num_variables;i++) { - pstring dest; - - convert_string(CH_DISPLAY, CH_UNIX, - variables[i].name, -1, - dest, sizeof(dest)); - free(variables[i].name); - variables[i].name = strdup(dest); - - convert_string(CH_DISPLAY, CH_UNIX, - variables[i].value, -1, - dest, sizeof(dest)); - free(variables[i].value); - variables[i].value = strdup(dest); - } } @@ -269,7 +265,7 @@ static void cgi_setup_error(char *err, char *header, char *info) } } - d_printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info); + printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info); fclose(stdin); fclose(stdout); exit(0); @@ -296,37 +292,6 @@ static void cgi_auth_error(void) exit(0); } -/*************************************************************************** -authenticate when we are running as a CGI - ***************************************************************************/ -static void cgi_web_auth(void) -{ - char *user = getenv("REMOTE_USER"); - struct passwd *pwd; - char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n"; - char *tail = "</BODY></HTML>\r\n"; - - if (!user) { - printf("%sREMOTE_USER not set. Not authenticated by web server.<br>%s\n", - head, tail); - exit(0); - } - - pwd = getpwnam_alloc(user); - if (!pwd) { - printf("%sCannot find user %s<br>%s\n", head, user, tail); - exit(0); - } - - setuid(0); - setuid(pwd->pw_uid); - if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) { - printf("%sFailed to become user %s - uid=%d/%d<br>%s\n", - head, user, (int)geteuid(), (int)getuid(), tail); - exit(0); - } - passwd_free(&pwd); -} /*************************************************************************** decode a base64 string in-place - simple and slow algorithm @@ -340,7 +305,7 @@ static void base64_decode(char *s) n=i=0; - while (*s && (p=strchr_m(b64,*s))) { + while (*s && (p=strchr(b64,*s))) { idx = (int)(p - b64); byte_offset = (i*6)/8; bit_offset = (i*6)%8; @@ -367,6 +332,14 @@ static BOOL cgi_handle_authorization(char *line) { char *p, *user, *user_pass; struct passwd *pass = NULL; + BOOL got_name = False; + BOOL tested_pass = False; + fstring default_user_lookup; + fstring default_user_pass; + + /* Dummy user lookup to take the same time as a valid user. */ + fstrcpy(default_user_lookup, "zzzz bibble"); + fstrcpy(default_user_pass, "123456789"); if (strncasecmp(line,"Basic ", 6)) { goto err; @@ -374,7 +347,7 @@ static BOOL cgi_handle_authorization(char *line) line += 6; while (line[0] == ' ') line++; base64_decode(line); - if (!(p=strchr_m(line,':'))) { + if (!(p=strchr(line,':'))) { /* * Always give the same error so a cracker * cannot tell why we fail. @@ -384,39 +357,58 @@ static BOOL cgi_handle_authorization(char *line) *p = 0; user = line; user_pass = p+1; - + /* * Try and get the user from the UNIX password file. */ - - pass = getpwnam_alloc(user); - + + if(!(pass = Get_Pwnam(user,False))) { + /* + * Always give the same error so a cracker + * cannot tell why we fail. + */ + got_name = True; + goto err; + } + /* * Validate the password they have given. */ - - if NT_STATUS_IS_OK(pass_check(pass, user, user_pass, - strlen(user_pass), NULL, False)) { - - if (pass) { + + tested_pass = True; + + if(pass_check(user, user_pass, strlen(user_pass), NULL, NULL) == True) { + + /* + * Password was ok. + */ + + if(pass->pw_uid != 0) { /* - * Password was ok. + * We have not authenticated as root, + * become the user *permanently*. */ - become_user_permanently(pass->pw_uid, pass->pw_gid); - - /* Save the users name */ - C_user = strdup(user); - passwd_free(&pass); - return True; } + + /* Save the users name */ + C_user = strdup(user); + return True; } - -err: + + err: + + /* Always take the same time. */ + if (!got_name) + Get_Pwnam(default_user_lookup,False); + + if (!tested_pass) + pass_check(default_user_lookup, default_user_pass, + strlen(default_user_pass), NULL, NULL); + cgi_setup_error("401 Bad Authorization", "", "username or password incorrect"); - passwd_free(&pass); return False; } @@ -450,11 +442,10 @@ static void cgi_download(char *file) char buf[1024]; int fd, l, i; char *p; - char *lang; /* sanitise the filename */ for (i=0;file[i];i++) { - if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) { + if (!isalnum((int)file[i]) && !strchr("/.-_", file[i])) { cgi_setup_error("404 File Not Found","", "Illegal character in filename"); } @@ -464,14 +455,13 @@ static void cgi_download(char *file) cgi_setup_error("404 File Not Found","", "The requested file was not found"); } - - fd = web_open(file,O_RDONLY,0); + fd = sys_open(file,O_RDONLY,0); if (fd == -1) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } printf("HTTP/1.0 200 OK\r\n"); - if ((p=strrchr_m(file,'.'))) { + if ((p=strrchr(file,'.'))) { if (strcmp(p,".gif")==0) { printf("Content-Type: image/gif\r\n"); } else if (strcmp(p,".jpg")==0) { @@ -484,11 +474,6 @@ static void cgi_download(char *file) } printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME)); - lang = lang_tdb_current(); - if (lang) { - printf("Content-Language: %s\r\n", lang); - } - printf("Content-Length: %d\r\n\r\n", (int)st.st_size); while ((l=read(fd,buf,sizeof(buf)))>0) { fwrite(buf, 1, l, stdout); @@ -498,40 +483,26 @@ static void cgi_download(char *file) } - - -/** - * @brief Setup the CGI framework. - * - * Setup the cgi framework, handling the possibility that this program - * is either run as a true CGI program with a gateway to a web server, or - * is itself a mini web server. - **/ -void cgi_setup(const char *rootdir, int auth_required) +/*************************************************************************** +setup the cgi framework, handling the possability that this program is either +run as a true cgi program by a web browser or is itself a mini web server + ***************************************************************************/ +void cgi_setup(char *rootdir, int auth_required) { BOOL authenticated = False; char line[1024]; char *url=NULL; char *p; - char *lang; if (chdir(rootdir)) { cgi_setup_error("400 Server Error", "", "chdir failed - the server is not configured correctly"); } - /* Handle the possability we might be running as non-root */ - sec_init(); - - if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) { - /* if running as a cgi program */ - web_set_lang(lang); - } - /* maybe we are running under a web server */ if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) { if (auth_required) { - cgi_web_auth(); + cgi_auth_error(); } return; } @@ -562,8 +533,6 @@ void cgi_setup(const char *rootdir, int auth_required) authenticated = cgi_handle_authorization(&line[15]); } else if (strncasecmp(line,"Content-Length: ", 16)==0) { content_length = atoi(&line[16]); - } else if (strncasecmp(line,"Accept-Language: ", 17)==0) { - web_set_lang(&line[17]); } /* ignore all other requests! */ } @@ -578,15 +547,15 @@ void cgi_setup(const char *rootdir, int auth_required) } /* trim the URL */ - if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) { + if ((p = strchr(url,' ')) || (p=strchr(url,'\t'))) { *p = 0; } - while (*url && strchr_m("\r\n",url[strlen(url)-1])) { + while (*url && strchr("\r\n",url[strlen(url)-1])) { url[strlen(url)-1] = 0; } /* anything following a ? in the URL is part of the query string */ - if ((p=strchr_m(url,'?'))) { + if ((p=strchr(url,'?'))) { query_string = p+1; *p = 0; } |