Пример #1
0
/***************************************************************************
handle a file download
  ***************************************************************************/
static void cgi_download(char *file)
{
	struct stat st;
	char buf[1024];
	int fd, l, i;
	char *p;

	/* sanitise the filename */
	for (i=0;file[i];i++) {
		if (!isalnum(file[i]) && !strchr("/.-_", file[i])) {
			cgi_setup_error("404 File Not Found","",
					"Illegal character in filename");
		}
	}

	if (strstr(file,"..")) {
		cgi_setup_error("404 File Not Found","",
				"Relative paths not allowed");
	}

	if (!file_exist(file, &st)) {
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}
	fd = open(file,O_RDONLY);
	if (fd == -1) {
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}
	printf("HTTP/1.1 200 OK\r\n");
	if ((p=strrchr(file,'.'))) {
		if (strcmp(p,".gif")==0 || strcmp(p,".jpg")==0) {
			printf("Content-Type: image/gif\r\n");
		} else {
			printf("Content-Type: text/html\r\n");
		}
	}
	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);
	}
	close(fd);
	exit(0);
}
Пример #2
0
/***************************************************************************
handle a http authentication line
  ***************************************************************************/
static int cgi_handle_authorization(char *line)
{
	char *p, *user, *pass;
	struct passwd *pwd;
	int ret=0;

	if (strncasecmp(line,"Basic ", 6)) {
		cgi_setup_error("401 Bad Authorization", "", 
				"Only basic authorization is understood");
	}
	line += 6;
	while (line[0] == ' ') line++;
	base64_decode(line);
	if (!(p=strchr(line,':'))) {
		cgi_setup_error("401 Bad Authorization", "", 
				"username/password must be supplied");
	}
	*p = 0;
	user = line;
	pass = p+1;

	/* currently only allow connections as root */
	if (strcasecmp(user,"root")) {
		cgi_setup_error("401 Bad Authorization", "", 
				"incorrect username/password");
	}
	
	pwd = getpwnam(user);

	if (!strcmp((char *)crypt(pass, pwd->pw_passwd),pwd->pw_passwd)) {
		ret = 1;
	}

	memset(pass, 0, strlen(pass));

	return ret;
}
Пример #3
0
/***************************************************************************
tell a browser about a fatal authentication error
  ***************************************************************************/
static void cgi_auth_error(void)
{
	if (inetd_server) {
                cgi_setup_error("401 Authorization Required", 
                                "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
                                "You must be authenticated to use this service");
	} else {
		printf("Content-Type: text/html\r\n");

		printf("\r\n<HTML><HEAD><TITLE>SWAT</TITLE></HEAD>\n");
		printf("<BODY><H1>Installation Error</H1>\n");
		printf("SWAT must be installed via inetd. It cannot be run as a CGI script<p>\n");
		printf("</BODY></HTML>\r\n");
	}
	exit(0);
}
Пример #4
0
/***************************************************************************
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 authenticated = 0;
	char line[1024];
	char *url=NULL;
	char *p;

	if (chdir(rootdir)) {
		cgi_setup_error("400 Server Error", "",
				"chdir failed - the server is not configured correctly");
	}

	if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
		/* assume we are running under a real web server */
		return;
	}

	/* we are a mini-web server. We need to read the request from stdin
	   and handle authentication etc */
	while (fgets(line, sizeof(line)-1, stdin)) {
		if (line[0] == '\r' || line[0] == '\n') break;
		if (strncasecmp(line,"GET ", 4)==0) {
			request_get = 1;
			url = strdup(&line[4]);
		} else if (strncasecmp(line,"POST ", 5)==0) {
			request_post = 1;
			url = strdup(&line[5]);
		} else if (strncasecmp(line,"PUT ", 4)==0) {
			cgi_setup_error("400 Bad Request", "",
					"This server does not accept PUT requests");
		} else if (strncasecmp(line,"Authorization: ", 15)==0) {
			authenticated = cgi_handle_authorization(&line[15]);
		} else if (strncasecmp(line,"Content-Length: ", 16)==0) {
			content_length = atoi(&line[16]);
		}
		/* ignore all other requests! */
	}

	if (!authenticated) {
		cgi_setup_error("401 Authorization Required", 
				"WWW-Authenticate: Basic realm=\"root\"\r\n",
				"You must be authenticated to use this service");
	}

	if (!url) {
		cgi_setup_error("400 Bad Request", "",
				"You must specify a GET or POST request");
	}

	/* trim the URL */
	if ((p = strchr(url,' ')) || (p=strchr(url,'\t'))) {
		*p = 0;
	}
	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(url,'?'))) {
		query_string = p+1;
		*p = 0;
	}

	if (strcmp(url,"/")) {
		cgi_download(url+1);
	}

	printf("HTTP/1.1 200 OK\r\nConnection: close\r\n");
	
}
Пример #5
0
/**
 * @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)
{
	bool authenticated = False;
	char line[1024];
	char *url=NULL;
	char *p;
	char *lang;

	if (chdir(rootdir)) {
		cgi_setup_error("500 Server Error", "",
				"chdir failed - the server is not configured correctly");
	}

	/* Handle the possibility 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();
		}
		return;
	}

	inetd_server = True;

	if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) {
		cgi_setup_error("403 Forbidden", "",
				"Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf ");
	}

	/* we are a mini-web server. We need to read the request from stdin
	   and handle authentication etc */
	while (fgets(line, sizeof(line)-1, stdin)) {
		if (line[0] == '\r' || line[0] == '\n') break;
		if (strnequal(line,"GET ", 4)) {
			got_request = True;
			url = SMB_STRDUP(&line[4]);
		} else if (strnequal(line,"POST ", 5)) {
			got_request = True;
			request_post = 1;
			url = SMB_STRDUP(&line[5]);
		} else if (strnequal(line,"PUT ", 4)) {
			got_request = True;
			cgi_setup_error("400 Bad Request", "",
					"This server does not accept PUT requests");
		} else if (strnequal(line,"Authorization: ", 15)) {
			authenticated = cgi_handle_authorization(&line[15]);
		} else if (strnequal(line,"Content-Length: ", 16)) {
			content_length = atoi(&line[16]);
		} else if (strnequal(line,"Accept-Language: ", 17)) {
			web_set_lang(&line[17]);
		}
		/* ignore all other requests! */
	}

	if (auth_required && !authenticated) {
		cgi_auth_error();
	}

	if (!url) {
		cgi_setup_error("400 Bad Request", "",
				"You must specify a GET or POST request");
	}

	/* trim the URL */
	if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
		*p = 0;
	}
	while (*url && strchr_m("\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,'?'))) {
		query_string = p+1;
		*p = 0;
	}

	string_sub(url, "/swat/", "", 0);

	if (url[0] != '/' && strstr(url,"..")==0) {
		cgi_download(url);
	}

	printf("HTTP/1.0 200 OK\r\nConnection: close\r\n");
	printf("Date: %s\r\n", http_timestring(time(NULL)));
	baseurl = "";
	pathinfo = url+1;
}
Пример #6
0
/***************************************************************************
handle a file download
  ***************************************************************************/
static void cgi_download(char *file)
{
	SMB_STRUCT_STAT st;
	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])) {
			cgi_setup_error("404 File Not Found","",
					"Illegal character in filename");
		}
	}

	if (sys_stat(file, &st) != 0) 
	{
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}

	if (S_ISDIR(st.st_mode))
	{
		snprintf(buf, sizeof(buf), "%s/index.html", file);
		if (!file_exist(buf, &st) || !S_ISREG(st.st_mode))
		{
			cgi_setup_error("404 File Not Found","",
					"The requested file was not found");
		}
	}
	else if (S_ISREG(st.st_mode))
	{
		snprintf(buf, sizeof(buf), "%s", file);
	}
	else
	{
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}

	fd = web_open(buf,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(buf, '.'))) {
		if (strcmp(p,".gif")==0) {
			printf("Content-Type: image/gif\r\n");
		} else if (strcmp(p,".jpg")==0) {
			printf("Content-Type: image/jpeg\r\n");
		} else if (strcmp(p,".png")==0) {
			printf("Content-Type: image/png\r\n");
		} else if (strcmp(p,".css")==0) {
			printf("Content-Type: text/css\r\n");
		} else if (strcmp(p,".txt")==0) {
			printf("Content-Type: text/plain\r\n");
		} else {
			printf("Content-Type: text/html\r\n");
		}
	}
	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) {
		if (fwrite(buf, 1, l, stdout) != l) {
			break;
		}
	}
	close(fd);
	exit(0);
}
Пример #7
0
/***************************************************************************
handle a http authentication line
  ***************************************************************************/
static bool cgi_handle_authorization(char *line)
{
	char *p;
	fstring user, user_pass;
	struct passwd *pass = NULL;

	if (!strnequal(line,"Basic ", 6)) {
		goto err;
	}
	line += 6;
	while (line[0] == ' ') line++;
	base64_decode_inplace(line);
	if (!(p=strchr_m(line,':'))) {
		/*
		 * Always give the same error so a cracker
		 * cannot tell why we fail.
		 */
		goto err;
	}
	*p = 0;

	convert_string(CH_UTF8, CH_UNIX, 
		       line, -1, 
		       user, sizeof(user), True);

	convert_string(CH_UTF8, CH_UNIX, 
		       p+1, -1, 
		       user_pass, sizeof(user_pass), True);

	/*
	 * Try and get the user from the UNIX password file.
	 */
	
	pass = getpwnam_alloc(talloc_autofree_context(), user);
	
	/*
	 * Validate the password they have given.
	 */
	
	if NT_STATUS_IS_OK(pass_check(pass, user, user_pass, 
		      strlen(user_pass), NULL, False)) {
		
		if (pass) {
			/*
			 * Password was ok.
			 */
			
			if ( initgroups(pass->pw_name, pass->pw_gid) != 0 )
				goto err;

			become_user_permanently(pass->pw_uid, pass->pw_gid);
			
			/* Save the users name */
			C_user = SMB_STRDUP(user);
			TALLOC_FREE(pass);
			return True;
		}
	}
	
err:
	cgi_setup_error("401 Bad Authorization", 
			"WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
			"username or password incorrect");

	TALLOC_FREE(pass);
	return False;
}