Ejemplo n.º 1
0
int serveconnection(int sockfd)
{
	FILE *in;
	char tempdata[8192], *ptr, *ptr2, *host_ptr1, *host_ptr2;
	char tempstring[8192], mimetype[50];
	char filename[255];
	unsigned int loop=0, flag=0;
	int numbytes=0;
	struct sockaddr_in sa;
	int addrlen = sizeof(struct sockaddr_in);
	t_vhost *thehost;
	
	thehost = &defaulthost;

// tempdata is the full header, tempstring is just the command

	while(!strstr(tempdata, "\r\n\r\n") && !strstr(tempdata, "\n\n"))
	{	
		if((numbytes=recv(sockfd, tempdata+numbytes, 4096-numbytes, 0))==-1)
			return -1;
	}
	for(loop=0; loop<4096 && tempdata[loop]!='\n' && tempdata[loop]!='\r'; loop++)
		tempstring[loop] = tempdata[loop];
	
	tempstring[loop] = '\0';
	ptr = strtok(tempstring, " ");
	if(ptr == 0) return -1;
	if(strcmp(ptr, "GET")) 
	{
		strcpy(filename, SERVERROOT);
		strcat(filename, "/cmderror.html");
		goto sendpage;
	}
	ptr = strtok(NULL, " ");
	if(ptr == NULL)
	{
		strcpy(filename, SERVERROOT);
		strcat(filename, "/cmderror.html");
		goto sendpage;
	}

	host_ptr1 = strstr(tempdata, "Host:");
	if(host_ptr1)
	{
		host_ptr2 = strtok(host_ptr1+6, " \r\n\t");
		
		for(loop=0; loop<no_vhosts; loop++)
			if(!gstricmp(vhosts[loop].host, host_ptr2))
				thehost = &vhosts[loop];
	}	
	else
		thehost = &defaulthost;
	if(strstr(ptr, "/.."))
	{
		strcpy(filename, SERVERROOT);
		strcat(filename, "/404.html");
		goto sendpage;
	}

	getpeername(sockfd, (struct sockaddr *)&sa, &addrlen);
	Log("Connection from %s, request = \"GET %s\"", inet_ntoa(sa.sin_addr), ptr);

	if(!strncmp(ptr, thehost->CGIBINDIR, strlen(thehost->CGIBINDIR)))
	{/* Trying to execute a cgi-bin file ? lets check */
		ptr2 = strstr(ptr, "?");
		if(ptr2!=NULL) { ptr2[0] = '\0'; flag = 1; }

		strcpy(filename, thehost->CGIBINROOT);
		ptr += strlen(thehost->CGIBINDIR);
		strcat(filename, ptr);

		// Filename = program to execute
		// ptr = filename in cgi-bin dir
		// ptr2+1 = parameters

		if(does_file_exist(filename)==TRUE && isDirectory(filename)==FALSE)
		{
			if(send(sockfd, "HTTP/1.1 200 OK\n", 16, 0)==-1)
			{
				fclose(in);
				return -1;
			}
			if(send(sockfd, "Server: "SERVERNAME"\n", strlen("Server: "SERVERNAME"\n"), 0)==-1)
			{
				fclose(in);
				return -1;
			}
			
			// Is a CGI-program that needs executing
			if(0 != dup2(sockfd, 0) || 1 != dup2(sockfd, 1))
				return -1;

			setbuf(stdin, 0);
			setbuf(stdout, 0);
			if(flag==1) setenv("QUERY_STRING", ptr2+1, 1);
			
			chdir(thehost->CGIBINROOT);
			
			execl(filename, "");
		}
		strcpy(filename, SERVERROOT);
		strcat(filename, "/cgierror.html");
		goto sendpage;
	}	

	strcpy(filename, thehost->DOCUMENTROOT);
	strcat(filename, ptr);
	      
	if(does_file_exist(filename)==FALSE)
	{		
		if(filename[strlen(filename)-1] == '/')
			strcat(filename, thehost->DEFAULTPAGE);
		else
		{
			strcat(filename, "/");
			strcat(filename, thehost->DEFAULTPAGE);
		}
		if(does_file_exist(filename) == FALSE)
		{
			filename[strlen(filename)-strlen(thehost->DEFAULTPAGE)-1] = '\0'; // Get rid of the /index.. 
			if(isDirectory(filename) == TRUE) { showdir(filename, sockfd, thehost); return 0; }
	
			// File does not exist, so we need to display the 404 error page..
			strcpy(filename, SERVERROOT);
			strcat(filename, "/404.html");
		}	
	
	}
sendpage:
	if((in = fopen(filename, "rb"))==NULL)
		return -1;
	
	fseek(in, 0, SEEK_END);
	
	if(send(sockfd, "HTTP/1.1 200 OK\n", 16, 0)==-1)
	{
		fclose(in);
		return -1;
	}
	if(send(sockfd, "Server: "SERVERNAME"\n", strlen("Server: "SERVERNAME"\n"), 0)==-1)
	{
		fclose(in);
		return -1;
	}
	sprintf(tempstring, "Content-Length: %d\n", ftell(in));
	if(send(sockfd, tempstring, strlen(tempstring), 0)==-1)
	{
		fclose(in);
		return -1;
	}

	getmimetype(filename, mimetype);
	sprintf(tempstring, "Content-Type: %s\n\n", mimetype);
	if(send(sockfd, tempstring, strlen(tempstring), 0)==-1)
	{
		fclose(in);
		return -1;
	}
	
	fseek(in, 0, SEEK_SET);

	while(!feof(in))
	{
		numbytes = fread(tempdata, 1, 1024, in);
		if(send(sockfd, tempdata, numbytes, 0)==-1)
		{
			fclose(in);
			return -1;
		}
	}
	fclose(in);

	close(sockfd);	
	return 0;
}
Ejemplo n.º 2
0
Archivo: proc.c Proyecto: Lembed/uTLS
/* In this function we assume that the file has been checked for
 * maliciousness (".."s, etc) and has been decoded
 */
void procsendhead(struct connstruct *cn)
{
    char buf[MAXREQUESTLENGTH];
    struct stat stbuf;
    time_t t_time;
    struct tm *ptm;
    char date[32];
    char last_modified[32];
    char expires[32];
    int file_exists;

    /* are we trying to access a file over the HTTP connection instead of a
     * HTTPS connection? Or is this directory disabled? */
    if (htaccess_check(cn)) {
        send_error(cn, 403);
        return;
    }

#ifdef CONFIG_HTTP_HAS_AUTHORIZATION
    if (auth_check(cn)) {   /* see if there is a '.htpasswd' file */
#ifdef CONFIG_HTTP_VERBOSE
        printf("axhttpd: access to %s denied\n", cn->filereq); TTY_FLUSH();
#endif
        removeconnection(cn);
        return;
    }
#endif

    file_exists = stat(cn->actualfile, &stbuf);

#if defined(CONFIG_HTTP_HAS_CGI)
    if (file_exists != -1 && cn->is_cgi) {
        proccgi(cn);
        return;
    }
#endif

    /* look for "index.html"? */
    if (isdir(cn->actualfile)) {
        char tbuf[MAXREQUESTLENGTH];
        snprintf(tbuf, MAXREQUESTLENGTH, "%s%s", cn->actualfile, index_file);

        if ((file_exists = stat(tbuf, &stbuf)) != -1)
            my_strncpy(cn->actualfile, tbuf, MAXREQUESTLENGTH);
        else {
#if defined(CONFIG_HTTP_DIRECTORIES)
            /* If not, we do a directory listing of it */
            procdirlisting(cn);
#else
            send_error(cn, 404);
#endif
            return;
        }
    }

    if (file_exists == -1) {
        send_error(cn, 404);
        return;
    }


    time(&t_time);
    ptm = gmtime(&t_time);
    strftime(date, sizeof(date), rfc1123_format, ptm);

    /* has the file been read before? */
    if (cn->if_modified_since != -1)

    {
        ptm = gmtime(&stbuf.st_mtime);
        t_time = mktime(ptm);

        if (cn->if_modified_since >= t_time) {
            snprintf(buf, sizeof(buf), HTTP_VERSION" 304 Not Modified\nServer: "
                     "%s\nDate: %s\n\n", server_version, date);
            special_write(cn, buf, strlen(buf));
            cn->state = STATE_WANT_TO_READ_HEAD;
            return;
        }
    }

    if (cn->reqtype == TYPE_HEAD) {
        removeconnection(cn);
        return;
    } else {
        int flags = O_RDONLY;
#if defined(CONFIG_PLATFORM_CYGWIN)
        flags |= O_BINARY;
#endif
        cn->filedesc = open(cn->actualfile, flags);

        if (cn->filedesc < 0) {
            send_error(cn, 404);
            return;
        }

        ptm = gmtime(&stbuf.st_mtime);
        strftime(last_modified, sizeof(last_modified), rfc1123_format, ptm);
        t_time += CONFIG_HTTP_TIMEOUT;
        ptm = gmtime(&t_time);
        strftime(expires, sizeof(expires), rfc1123_format, ptm);

        snprintf(buf, sizeof(buf), HTTP_VERSION" 200 OK\nServer: %s\n"
                 "Content-Type: %s\nContent-Length: %ld\n"
                 "Date: %s\nLast-Modified: %s\nExpires: %s\n\n", server_version,
                 getmimetype(cn->actualfile), (long) stbuf.st_size,
                 date, last_modified, expires);

        special_write(cn, buf, strlen(buf));

#ifdef CONFIG_HTTP_VERBOSE
        printf("axhttpd: %s:/%s\n", cn->is_ssl ? "https" : "http", cn->filereq);
        TTY_FLUSH();
#endif


        cn->state = STATE_WANT_TO_READ_FILE;
    }
}