NCSA HTTPd 1.5.2a (export)

This commit is contained in:
I am not me 2013-03-13 03:17:57 -04:00
parent 3145f7d291
commit 21abffbc74
14 changed files with 59 additions and 7224 deletions

4
BUGS
View File

@ -1,6 +1,10 @@
NOTE: Bugs are mentioned in the version they are found in. This doesn't NOTE: Bugs are mentioned in the version they are found in. This doesn't
mean that they didn't exist prior to that version. mean that they didn't exist prior to that version.
Known Bugs in 1.5.2
---------------------
*) HTTPd doesn't recognize an HTTP/1.1 request correctlly
Known Bugs in 1.5.1 Known Bugs in 1.5.1
--------------------- ---------------------
*) Can only use a single group on a require group *) Can only use a single group on a require group

11
CHANGES
View File

@ -1,3 +1,14 @@
Changes for 1.5.2a
------------------
*) Only enable keep alive from CGI scripts with content lengths and if
keep alive is enabled on the server
*) Delete preceding white space on CGI headers
*) Fix HTTP/1.1 protocal bug (if agent requested HTTP/1.1, server responded
with HTTP, now responds with HTTP/1.0 which is spec)
*) Added SERVER_ROOT CGI var
*) Should escape # character in directory indexing
*) Add MaxRequestsPerChild support, so that errors in state can be swept under
the carpet
Changes for 1.5.2 Changes for 1.5.2
------------------ ------------------

View File

@ -45,6 +45,14 @@ StartServers 5
MaxServers 20 MaxServers 20
# MaxRequestsPerChild: the number of requests each child process is
# allowed to process before the child dies. The child will exit so as to
# avoid problems after prolonged use when HTTPd (and maybe the libraries
# it uses) leak. On most systems, this isn't really needed, but a few
# do have notable leaks in the libraries.
MaxRequestsPerChild 100
## TimeOut <seconds> ## TimeOut <seconds>
# The number of seconds the server will wait for a client to # The number of seconds the server will wait for a client to
# send its query once connected, or the maximum amount of time the # send its query once connected, or the maximum amount of time the

View File

@ -1,4 +1,16 @@
1.5.2a
---------
*) Only enable keep alive from CGI scripts with content lengths and if
keep alive is enabled on the server
*) Delete preceding white space on CGI headers
*) Fix HTTP/1.1 protocal bug (if agent requested HTTP/1.1, server responded
with HTTP, now responds with HTTP/1.0 which is spec)
*) Added SERVER_ROOT CGI var
*) Should escape # character in directory indexing
*) Add MaxRequestsPerChild support, so that errors in state can be swept under
the carpet
Fixes for 1.5.2 Fixes for 1.5.2
------------------ ------------------
*) Changed getline rfc822 line wrap to check for validity of the next bits *) Changed getline rfc822 line wrap to check for validity of the next bits

View File

@ -1,37 +0,0 @@
Port configurable per VirtualHost
kadow@msg.net (Kevin Kadow)
Server Parse CGI output
not feasible because SSI parser using buffered I/O, CGI uses getline()
(server buffered I/O)
But, we did it anyways. See CGI_SSI_HACK in config.h
Allow extra CGI environment variables to be specified via configuration
Kevin Kadow (kadow@msg.net) and Brian Millett (bpm@techapp.com)
Shouldn't be too hard, probably in 1.5.1b4
Ok, maybe in 1.5.2
AuthUserScript - Heiner Schorn (Heiner.Schorn@informatik.umu.se)
Pass a user name to a script, it returns the password to check against
the one the client sent to the server. This is safe from someone
writing a script to gather passwords, because the given password is
never sent to the script. This is unsafe on the server system because
it will return the password of a user. That could be made safer by
making the mechanism employ crypt on the password before hand..
Shouldn't be too hard, but needs some design work. Perhaps 1.5.1b4
Ok, maybe 1.5.2
Have separate UID/GID per CGI script - Marc Evans (marc@destek.net)
With Patch (NF-1.5b7-marc_cgi_uid_hack)
Basically, changes calls from setuid to seteuid, so it changes the
effective user id of the server. This makes any security hole
potentially dangerous, such as the one in 1.3, since the program
that you can force to run can set the euid back to root.
Look at it for 1.5.1b4, probably always have to be a #define for the
more security conscious users of NCSA HTTPd
Push off to 1.5.2
SHTTP
Alpha is done, but we need to test it more
SSL
Again, alpha code is in place, but it needs to be tested more
RADIUS
Ok, I was expecting something slightly different. Doesn't quite fit
the current way of doing things, but shouldn't be too hard to figure
out either. Probably 1.5.2

View File

@ -201,6 +201,7 @@ int add_common_vars(per_request *reqInfo) {
make_env_str(reqInfo,"SERVER_SOFTWARE",SERVER_VERSION); make_env_str(reqInfo,"SERVER_SOFTWARE",SERVER_VERSION);
make_env_str(reqInfo,"SERVER_NAME",reqInfo->hostInfo->server_hostname); make_env_str(reqInfo,"SERVER_NAME",reqInfo->hostInfo->server_hostname);
make_env_str(reqInfo,"SERVER_ADMIN",reqInfo->hostInfo->server_admin); make_env_str(reqInfo,"SERVER_ADMIN",reqInfo->hostInfo->server_admin);
make_env_str(reqInfo,"SERVER_ROOT",server_root);
sprintf(str,"%d",port); sprintf(str,"%d",port);
make_env_str(reqInfo,"SERVER_PORT",str); make_env_str(reqInfo,"SERVER_PORT",str);
@ -318,6 +319,7 @@ int scan_cgi_header(per_request *reqInfo, int pd)
reqInfo->status = SC_REDIRECT_TEMP; reqInfo->status = SC_REDIRECT_TEMP;
set_stat_line(reqInfo); set_stat_line(reqInfo);
} }
while (l && *l && isspace(*l)) l++;
strncpy(reqInfo->outh_location,l,HUGE_STRING_LEN); strncpy(reqInfo->outh_location,l,HUGE_STRING_LEN);
reqInfo->outh_location[HUGE_STRING_LEN-1] = '\0'; reqInfo->outh_location[HUGE_STRING_LEN-1] = '\0';
} }
@ -331,7 +333,7 @@ int scan_cgi_header(per_request *reqInfo, int pd)
} }
} }
else if(!strcasecmp(str,"Content-length")) { else if(!strcasecmp(str,"Content-length")) {
keep_alive.bKeepAlive = 1; if (keep_alive.bAllowKeepAlive) keep_alive.bKeepAlive = 1;
sscanf(l,"%d",&(reqInfo->outh_content_length)); sscanf(l,"%d",&(reqInfo->outh_content_length));
} }
else if(!strcasecmp(str,"WWW-Authenticate")) { else if(!strcasecmp(str,"WWW-Authenticate")) {
@ -339,6 +341,7 @@ int scan_cgi_header(per_request *reqInfo, int pd)
reqInfo->status = SC_AUTH_REQUIRED; reqInfo->status = SC_AUTH_REQUIRED;
set_stat_line(reqInfo); set_stat_line(reqInfo);
} }
while (l && *l && isspace(*l)) l++;
strncpy(reqInfo->outh_www_auth,l,HUGE_STRING_LEN); strncpy(reqInfo->outh_www_auth,l,HUGE_STRING_LEN);
reqInfo->outh_www_auth[HUGE_STRING_LEN-1] = '\0'; reqInfo->outh_www_auth[HUGE_STRING_LEN-1] = '\0';
} }

View File

@ -116,10 +116,12 @@
/* defines for new muli-child approach /* defines for new muli-child approach
DEFAULT_START_DAEMON defines how many children start at httpd start DEFAULT_START_DAEMON defines how many children start at httpd start
DEFAULT_MAX_DAEMON defines how many children can start DEFAULT_MAX_DAEMON defines how many children can start
DEFAULT_MAX_REQUESTS defines how many requests a child handles
*/ */
#define DEFAULT_START_DAEMON 5 #define DEFAULT_START_DAEMON 5
#define DEFAULT_MAX_DAEMON 10 #define DEFAULT_MAX_DAEMON 10
#define DEFAULT_MAX_REQUESTS 30
/* defines for debugging purposes /* defines for debugging purposes
PROFILE to set the server up to profile the code PROFILE to set the server up to profile the code

View File

@ -53,7 +53,7 @@
#endif /* NEXT */ #endif /* NEXT */
#define SERVER_VERSION "NCSA/1.5.2" #define SERVER_VERSION "NCSA/1.5.2"
#define SERVER_SOURCE "NCSA/1.5.2" #define SERVER_SOURCE "NCSA/1.5.2a"
#define SERVER_PROTOCOL "HTTP/1.0" #define SERVER_PROTOCOL "HTTP/1.0"
/* Response Codes from HTTP/1.0 Spec /* Response Codes from HTTP/1.0 Spec

View File

@ -58,6 +58,7 @@ int standalone;
int port; int port;
uid_t user_id; uid_t user_id;
gid_t group_id; gid_t group_id;
int max_requests;
char server_confname[MAX_STRING_LEN]; char server_confname[MAX_STRING_LEN];
int timeout; int timeout;
int do_rfc931; int do_rfc931;
@ -119,6 +120,7 @@ void set_defaults(per_host *host, FILE *errors)
max_servers = DEFAULT_MAX_DAEMON; max_servers = DEFAULT_MAX_DAEMON;
start_servers = DEFAULT_START_DAEMON; start_servers = DEFAULT_START_DAEMON;
#endif /* NO_PASS */ #endif /* NO_PASS */
max_requests = DEFAULT_MAX_REQUESTS;
/* ServerRoot set in httpd.c */ /* ServerRoot set in httpd.c */
@ -453,6 +455,9 @@ void process_server_config(per_host *host, FILE *cfg, FILE *errors,
server_confname,n,errors); server_confname,n,errors);
#endif /* NO_PASS */ #endif /* NO_PASS */
} }
else if(!strcasecmp(w,"MaxRequestsPerChild")) {
max_requests = atoi(l);
}
#ifdef DIGEST_AUTH #ifdef DIGEST_AUTH
else if(!strcasecmp(w,"AssumeDigestSupport")) { else if(!strcasecmp(w,"AssumeDigestSupport")) {
/* Doesn't do anything anymore, but if we take it out, anyone with /* Doesn't do anything anymore, but if we take it out, anyone with

View File

@ -34,6 +34,7 @@ extern uid_t user_id;
extern gid_t group_id; extern gid_t group_id;
extern int timeout; extern int timeout;
extern int do_rfc931; extern int do_rfc931;
extern int max_requests;
extern char server_confname[]; extern char server_confname[];
extern char server_root[]; extern char server_root[];
extern char core_dir[]; extern char core_dir[];

View File

@ -422,10 +422,11 @@ void decode_request(per_request *reqInfo, char *request)
reqInfo->http_version = P_HTTP_0_9; reqInfo->http_version = P_HTTP_0_9;
} }
else { else {
/* On an HTTP/1.0 or HTTP/1.1 request, respond with 1.0 */
if (!strcmp(protocal,protocals[P_HTTP_1_0])) if (!strcmp(protocal,protocals[P_HTTP_1_0]))
reqInfo->http_version = P_HTTP_1_0; reqInfo->http_version = P_HTTP_1_0;
else if (!strcmp(protocal,protocals[P_HTTP_1_0])) else if (!strcmp(protocal,protocals[P_HTTP_1_1]))
reqInfo->http_version = P_HTTP_1_1; reqInfo->http_version = P_HTTP_1_0;
else if (!strcasecmp(protocal,protocals[P_SHTTP_1_1])) else if (!strcasecmp(protocal,protocals[P_SHTTP_1_1]))
reqInfo->http_version = P_SHTTP_1_1; reqInfo->http_version = P_SHTTP_1_1;
else if (!strcasecmp(protocal,protocals[P_SHTTP_1_2])) else if (!strcasecmp(protocal,protocals[P_SHTTP_1_2]))

View File

@ -96,6 +96,7 @@ int Alone=0;
JMP_BUF jmpbuffer; JMP_BUF jmpbuffer;
int csd = -1; int csd = -1;
KeepAliveData keep_alive; /* global keep alive info */ KeepAliveData keep_alive; /* global keep alive info */
static int num_requests = 0;
#endif /* NOT_READY */ #endif /* NOT_READY */
ChildInfo *Children; ChildInfo *Children;
@ -399,7 +400,7 @@ void CompleteRequest(per_request *reqInfo, int pipe)
shutdown(csd,2); shutdown(csd,2);
close(csd); close(csd);
#ifndef NO_PASS #ifndef NO_PASS
if (pipe >= 0) { if ((pipe >= 0) && (num_requests < max_requests)) {
write(pipe,donemsg,sizeof(donemsg)); write(pipe,donemsg,sizeof(donemsg));
if (reqInfo != NULL) reqInfo->RequestFlags = 0; if (reqInfo != NULL) reqInfo->RequestFlags = 0;
free_request(reqInfo,NOT_LAST); free_request(reqInfo,NOT_LAST);
@ -510,6 +511,8 @@ void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
static per_request *reqInfo = NULL; static per_request *reqInfo = NULL;
close(mainSocket); close(mainSocket);
num_requests = 0;
#ifdef PROFILE #ifdef PROFILE
moncontrol(1); moncontrol(1);
#endif /* PROFILE */ #endif /* PROFILE */
@ -592,6 +595,7 @@ void child_main(int parent_pipe, SERVER_SOCK_ADDR *sa_server)
remote_logname = GetRemoteLogName(sa_server); remote_logname = GetRemoteLogName(sa_server);
keep_alive.nCurrRequests = 0; keep_alive.nCurrRequests = 0;
if (reqInfo != NULL) reqInfo->RequestFlags = 0; if (reqInfo != NULL) reqInfo->RequestFlags = 0;
num_requests++;
} }
reqInfo = initialize_request(reqInfo); reqInfo = initialize_request(reqInfo);
@ -885,8 +889,6 @@ void standalone_main(int argc, char **argv)
log_error("child error: read msg failure", log_error("child error: read msg failure",
gConfiguration->error_log); gConfiguration->error_log);
} else if (nread == 0) { } else if (nread == 0) {
log_error("child error: child connection closed",
gConfiguration->error_log);
close(Children[x].childfd); close(Children[x].childfd);
kill(Children[x].pid,SIGKILL); kill(Children[x].pid,SIGKILL);
make_child(argc, argv, x, &sa_server); make_child(argc, argv, x, &sa_server);

7177
src/patch

File diff suppressed because it is too large Load Diff

View File

@ -830,7 +830,7 @@ void escape_uri(char *url) {
strncpy(copy,url,HUGE_STRING_LEN); strncpy(copy,url,HUGE_STRING_LEN);
for(x=0,y=0;copy[x];x++,y++) { for(x=0,y=0;copy[x];x++,y++) {
if(ind(":% ?+&",url[y] = copy[x]) != -1) { if(ind("#:% ?+&",url[y] = copy[x]) != -1) {
c2x(copy[x],&url[y]); c2x(copy[x],&url[y]);
y+=2; y+=2;
} }