View | Details | Raw Unified | Return to bug 6935
Collapse All | Expand All

(-)w3c-httpd/patches/CacheCheckSize.patch (+147 lines)
Line 0 Link Here
1
*** /dev/null	Tue Feb  6 11:05:04 1996
2
--- WWW/README-CACHE_CHECK_SIZE	Tue Feb  6 13:27:32 1996
3
***************
4
*** 0 ****
5
--- 1,11 ----
6
+ Patch to avoid serving truncated files from the cache.
7
+ 
8
+ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
9
+ system) and add '-DCACHE_CHECK_SIZE' to CFLAGS.
10
+ 
11
+ With the patch, the server checks the size of a file in the cache before
12
+ returning it to the user; if the size is incorrect, the server will
13
+ refresh the file in the cache.
14
+ 
15
+ -- 
16
+ -- 19960205, Gertjan van Oosten, gertjan@West.NL, West Consulting bv
17
*** WWW/Daemon/Implementation/HTCache.c.orig	Fri Aug 12 12:36:11 1994
18
--- WWW/Daemon/Implementation/HTCache.c	Mon Feb  5 14:02:11 1996
19
***************
20
*** 382,387 ****
21
--- 382,437 ----
22
  }
23
  
24
  
25
+ #ifdef CACHE_CHECK_SIZE
26
+ /*
27
+ **	Check whether cache file has correct size
28
+ **
29
+ ** On exit:
30
+ **	return YES
31
+ **		if size is good
32
+ **	return NO
33
+ **		if size is too small or too large
34
+ **
35
+ */
36
+ PRIVATE BOOL cache_check_size ARGS2(char *, cfn,
37
+                                     struct stat *, stat_info)
38
+ {
39
+     char buf[BUF_SIZE+2];
40
+     FILE *cf;
41
+     long cl = 0, pos, size, actual;
42
+ 
43
+     if (!cfn)
44
+ 	return NO;
45
+ 
46
+     cf = fopen(cfn, "r");
47
+     if (!cf)
48
+ 	return NO;
49
+ 
50
+     while (fgets(buf, sizeof(buf), cf)) {
51
+ 	if (!buf[0]
52
+ 	    || (buf[0] == '\n' && !buf[1])
53
+ 	    || (buf[0] == '\r' && buf[1] == '\n' && !buf[2]))
54
+ 	    break;
55
+ 
56
+         if (!strncasecomp(buf, "content-length:", 15))
57
+ 	    sscanf(buf+15, "%ld", &cl);
58
+     }
59
+     pos = ftell(cf);
60
+     fclose(cf);
61
+ 
62
+     size = stat_info->st_size;
63
+ 
64
+     actual = size - pos;
65
+     if (TRACE) {
66
+ 	fprintf(stderr,"Cache....... checking \"%s\": content-length %ld =?= %ld\n",
67
+ 		cfn,cl,actual);
68
+     }
69
+ 
70
+     return (cl == actual ? YES : NO);
71
+ }
72
+ #endif /* CACHE_CHECK_SIZE */
73
+ 
74
+ 
75
  PRIVATE BOOL do_caching ARGS1(char *, url)
76
  {
77
      HTList * cur = cc.no_caching;
78
***************
79
*** 460,465 ****
80
--- 510,518 ----
81
  				      time_t *,	expires)
82
  {
83
      struct stat stat_info;
84
+ #ifdef CACHE_CHECK_SIZE
85
+     BOOL size_ok;
86
+ #endif
87
  
88
      if (!url || !cfn || !cf || !if_ms) return CACHE_NO;
89
      *cfn = NULL;
90
***************
91
*** 497,503 ****
92
--- 550,563 ----
93
  	    }
94
  
95
  	    success = HTCacheInfo_for(*cfn, &ld, &lc, &ex, &mu, &lm);
96
+ #ifdef CACHE_CHECK_SIZE
97
+ 	    /* Check whether file in cache has correct size */
98
+ 	    size_ok = cache_check_size(*cfn, &stat_info);
99
+ #endif
100
  	    if (!success				  /* no entry */
101
+ #ifdef CACHE_CHECK_SIZE
102
+ 		|| !size_ok				  /* wrong size */
103
+ #endif
104
  		|| ex - cc.cache_time_margin <= cur_time  /* expired */
105
  		|| cur_time - lc >= refresh_interval	  /* time to refresh */
106
  		|| in.no_cache_pragma) {		  /* override cache */
107
***************
108
*** 507,512 ****
109
--- 567,576 ----
110
  		if (TRACE) {
111
  		    if (!success)
112
  			fprintf(stderr, "NoEntry..... %s -- expiring\n",*cfn);
113
+ #ifdef CACHE_CHECK_SIZE
114
+ 		    else if (!size_ok)
115
+ 			fprintf(stderr, "Truncated...... %s -- refresh\n",*cfn);
116
+ #endif
117
  		    else if (in.no_cache_pragma)
118
  			fprintf(stderr, "Forced...... refresh of %s\n",*cfn);
119
  		    else if (ex - cc.cache_time_margin <= cur_time)
120
***************
121
*** 527,533 ****
122
--- 591,601 ----
123
  		if (cc.cache_no_connect) {
124
  		    CTRACE(stderr, "Standalone.. caching mode but expired\n");
125
  		    cache_hit = YES;
126
+ #ifdef CACHE_CHECK_SIZE
127
+ 		    return size_ok ? CACHE_IF_MODIFIED : CACHE_CREATE;
128
+ #else
129
  		    return CACHE_IF_MODIFIED;
130
+ #endif
131
  		}
132
  
133
  		if (!(*cf = do_lock(*cfn))) {
134
***************
135
*** 550,556 ****
136
--- 618,628 ----
137
  		CTRACE(stderr,"IfModSince.. time: %s", ctime(if_ms));
138
  
139
  		free(backup);
140
+ #ifdef CACHE_CHECK_SIZE
141
+ 		return size_ok ? CACHE_IF_MODIFIED : CACHE_CREATE;
142
+ #else
143
  		return CACHE_IF_MODIFIED;
144
+ #endif
145
  	    }
146
  	    else {
147
  		CTRACE(stderr, "Cache....... not expired %s\n", *cfn);
(-)w3c-httpd/patches/CacheDirs.patch (+101 lines)
Line 0 Link Here
1
*** /dev/null	Tue Feb  6 11:05:04 1996
2
--- WWW/README-CACHEDIRS	Tue Feb  6 13:03:37 1996
3
***************
4
*** 0 ****
5
--- 1,12 ----
6
+ Patch to translate directory names in the cache from e.g.
7
+   /www-cache/http/www.some.where.org/
8
+ to
9
+   /www-cache/http/org/where/some/www/
10
+ 
11
+ Note that this can lead to unexpected problems, when you have two URLs
12
+ like <URL:http://some.where.org/www/> and <URL:http://www.some.where.org/>.
13
+ [This does happen, e.g. many sites out there have "some.where.org" and
14
+ "www.some.where.org" point to the same machine.]
15
+ 
16
+ --
17
+ -- 19950915, Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
18
*** WWW/Daemon/Implementation/HTCache.c.orig	Fri Aug 12 12:36:11 1994
19
--- WWW/Daemon/Implementation/HTCache.c	Fri Sep 15 16:25:33 1995
20
***************
21
*** 5,16 ****
22
--- 5,19 ----
23
  ** AUTHORS:
24
  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
25
  **	FM	Fote Macrides	macrides@sci.wfeb.edu
26
+ **	GJ	Gertjan van Oosten	gertjan@West.NL
27
  **
28
  ** HISTORY:
29
  **	31 Jan 94  AL	Written from scratch on a *very* beautiful
30
  **			Sunday afternoon -- seems like the spring
31
  **			is already coming, yippee!
32
  **	 8 Jul 94  FM	Insulate free() from _free structure element.
33
+ **	15 Sep 95  GJ	Translate host names in cache to (reversed)
34
+ **			directories.
35
  **
36
  ** BUGS:
37
  **
38
***************
39
*** 243,248 ****
40
--- 246,252 ----
41
  {
42
      char * access = NULL;
43
      char * host = NULL;
44
+     char * revhost = NULL;
45
      char * path = NULL;
46
      char * cfn = NULL;
47
      BOOL welcome = NO;
48
***************
49
*** 274,291 ****
50
  	    *cur = TOLOWER(*cur);
51
  	    cur++;
52
  	}
53
      }
54
  
55
      cfn = (char*)malloc(strlen(cc.cache_root) +
56
  			strlen(access) +
57
! 			(host ? strlen(host) : 0) +
58
  			(path ? strlen(path) : 0) +
59
  			(welcome ? strlen(WELCOME_FILE) : 0) + 3);
60
      if (!cfn) outofmem(__FILE__, "cache_file_name");
61
!     sprintf(cfn, "%s/%s/%s%s%s", cc.cache_root, access, host, path,
62
  	    (welcome ? WELCOME_FILE : ""));
63
  
64
!     FREE(access); FREE(host); FREE(path);
65
  
66
      /*
67
      ** This checks that the last component is not too long.
68
--- 278,310 ----
69
  	    *cur = TOLOWER(*cur);
70
  	    cur++;
71
  	}
72
+ 	/*
73
+ 	** Now transform host name from "www.some.where.org"
74
+ 	** to "org/where/some/www".
75
+ 	** [For nameless hosts, you'd want the IP address
76
+ 	** translated from "10.127.7.254" to "10/127/7/254",
77
+ 	** but that is left as an exercise.]
78
+ 	*/
79
+ 	revhost = malloc(strlen(host)+1);
80
+ 	revhost[0] = '\0';
81
+ 	while (cur = strrchr(host, '.')) {
82
+ 	    strcat(revhost, cur+1);
83
+ 	    strcat(revhost, "/");
84
+ 	    *cur = '\0';
85
+ 	}
86
+ 	strcat(revhost, host);
87
      }
88
  
89
      cfn = (char*)malloc(strlen(cc.cache_root) +
90
  			strlen(access) +
91
! 			(revhost ? strlen(revhost) : 0) +
92
  			(path ? strlen(path) : 0) +
93
  			(welcome ? strlen(WELCOME_FILE) : 0) + 3);
94
      if (!cfn) outofmem(__FILE__, "cache_file_name");
95
!     sprintf(cfn, "%s/%s/%s%s%s", cc.cache_root, access, revhost, path,
96
  	    (welcome ? WELCOME_FILE : ""));
97
  
98
!     FREE(access); FREE(host); FREE(revhost); FREE(path);
99
  
100
      /*
101
      ** This checks that the last component is not too long.
(-)w3c-httpd/patches/DenyAccess.patch (+97 lines)
Line 0 Link Here
1
*** /dev/null	Tue Feb  6 11:05:04 1996
2
--- WWW/README-DENYACCESS	Tue Feb  6 13:11:03 1996
3
***************
4
*** 0 ****
5
--- 1,28 ----
6
+ Patch to allow denial of IP addresses or domain names in a protection
7
+ mask.
8
+ 
9
+ With the patch, you can now specify patterns as:
10
+ 
11
+ Protection HEY-INTEL-NO-SECURITY-HOLES {
12
+ 	Mask		@(*.*.*.*, !132.233.*.*, !143.183.*.*, !137.46.*.*)
13
+ }
14
+ Protect	/*		HEY-INTEL-NO-SECURITY-HOLES
15
+ 
16
+ The comment from the patch is:
17
+ 
18
+ **	 9 Aug 95  GJ	Modified ip_in_def_list() to allow exclusions;
19
+ **			patterns can now be e.g.
20
+ **				@(*.*.*.*, !192.43.210.*)
21
+ **			which means: allow anyone in except West.NL;
22
+ **			the strange order of the patterns is because the
23
+ **			access list is built back to front, so be careful
24
+ **			to put the most restrictive patterns at the end!
25
+ **			The old patterns still work, of course, so
26
+ **				@(192.43.210.*)
27
+ **			would allow only West.NL, just as
28
+ **				@(!*.*.*.*, 192.43.210.*)
29
+ **			does (remember that this is matched back-to-front
30
+ **			by the server).
31
+ 
32
+ --
33
+ -- 19950809, Gertjan van Oosten, gertjan@west.nl, West Consulting B.V.
34
*** WWW/Daemon/Implementation/HTGroup.c.orig	Wed May  4 21:03:24 1994
35
--- WWW/Daemon/Implementation/HTGroup.c	Wed Aug  9 10:55:57 1995
36
***************
37
*** 8,18 ****
38
--- 8,37 ----
39
  **
40
  ** AUTHORS:
41
  **	AL	Ari Luotonen	luotonen@dxcern.cern.ch
42
+ **	GJ	Gertjan van Oosten	gertjan@West.NL
43
  **
44
  ** HISTORY:
45
+ **	 9 Aug 95  GJ	Modified ip_in_def_list() to allow exclusions;
46
+ **			patterns can now be e.g.
47
+ **				@(*.*.*.*, !192.43.210.*)
48
+ **			which means: allow anyone in except West.NL;
49
+ **			the strange order of the patterns is because the
50
+ **			access list is built back to front, so be careful
51
+ **			to put the most restrictive patterns at the end!
52
+ **			The old patterns still work, of course, so
53
+ **				@(192.43.210.*)
54
+ **			would allow only West.NL, just as
55
+ **				@(!*.*.*.*, 192.43.210.*)
56
+ **			does (remember that this is matched back-to-front
57
+ **			by the server).
58
  **
59
  **
60
  ** BUGS:
61
+ **	GJ	The modifications in ip_in_def_list() do not treat the
62
+ **		HTPattern as an abstract datatype; it is probably best
63
+ **		to encapsulate these manipulations in a few extra routines
64
+ **		in HTWild.c, but I can't be bothered.
65
+ **		A five-minute hack is a five-minute hack...
66
  **
67
  **
68
  **
69
***************
70
*** 581,590 ****
71
  	    /* Value of ref->translation is ignored, i.e. */
72
  	    /* no recursion for ip address tamplates.	  */
73
  	    HTPattern * pat = HTPattern_new(ref->name);
74
! 	    BOOL flag = HTIpMaskMatch(pat, ip_number, ip_name);
75
  	    HTPattern_free(pat);
76
  	    if (flag)
77
! 		return YES;
78
  	}
79
      }
80
      return NO;
81
--- 600,615 ----
82
  	    /* Value of ref->translation is ignored, i.e. */
83
  	    /* no recursion for ip address tamplates.	  */
84
  	    HTPattern * pat = HTPattern_new(ref->name);
85
! 	    BOOL negate = (*(pat->text)=='!');	/* "!bla.bla.bla.bla" ? */
86
! 	    BOOL flag;
87
! 	    if (negate)
88
! 	        pat->text++;			/* Skip '!' */
89
! 	    flag = HTIpMaskMatch(pat, ip_number, ip_name);
90
! 	    if (negate)
91
! 	        pat->text--;			/* Back to '!' */
92
  	    HTPattern_free(pat);
93
  	    if (flag)
94
! 		return negate ? NO : YES;
95
  	}
96
      }
97
      return NO;
(-)w3c-httpd/patches/HTParse.c.patch (+28 lines)
Line 0 Link Here
1
*** Library/Implementation/HTParse.c	Sun Sep 25 14:53:34 1994
2
--- Library/Implementation/HTParse.c.patch	Wed Nov  9 10:42:15 1994
3
***************
4
*** 350,360 ****
5
  	path = filename;
6
      if (*path == '/' && *(path+1)=='/') {	  /* Some URLs start //<foo> */
7
  	path += 1;
8
!     } else if (!strncmp(path, "news:", 5)) {	    /* Make group lower case */
9
! 	char *group = path+5;
10
! 	while (*group && *group!='@' && *group!='/') {
11
! 	    *group = TOLOWER(*group);
12
! 	    group++;
13
  	}
14
  	if (URI_TRACE)
15
  	    fprintf(stderr, "into\n............ `%s'\n", filename);
16
--- 322,333 ----
17
  	path = filename;
18
      if (*path == '/' && *(path+1)=='/') {	  /* Some URLs start //<foo> */
19
  	path += 1;
20
!     } else if (!strncmp(path, "news:", 5)) {
21
! 	char *ptr = strchr(path+5, '@');
22
! 	if (!ptr) ptr = path+5;
23
! 	while (*ptr) {			    /* Make group or host lower case */
24
! 	    *ptr = TOLOWER(*ptr);
25
! 	    ptr++;
26
  	}
27
  	if (URI_TRACE)
28
  	    fprintf(stderr, "into\n............ `%s'\n", filename);
(-)w3c-httpd/patches/HTTPS.patch (+553 lines)
Line 0 Link Here
1
*** /dev/null	Mon Apr 15 09:53:26 1996
2
--- WWW/README-HTTPS	Mon Apr 15 10:11:26 1996
3
***************
4
*** 0 ****
5
--- 1,45 ----
6
+ Patch to enable SSL support, i.e. serving documents via 'https://' URLs.
7
+ I built this using CERN httpd 3.0 with Library 2.17 and SSLeay-0.5.1b.
8
+ For further information on CERN httpd see:
9
+ 
10
+ 	http://www.w3.org/pub/WWW/Daemon/
11
+ 
12
+ For further information on SSLeay see:
13
+ 
14
+ 	http://www.psy.uq.oz.au/~ftp/Crypto/
15
+ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/
16
+ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/
17
+ 
18
+ REMEMBER: export and/or import of crypto software or crypto hooks is
19
+ illegal in many parts of the world.
20
+ 
21
+ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
22
+ system) and add '-DUSE_SSL -I/usr/local/ssl/include' to CFLAGS
23
+ and '-L/usr/local/ssl/lib -lssl -lcrypto' to LDFLAGS (fill in the
24
+ correct paths to your SSL include files and libraries).
25
+ 
26
+ Add the following lines to your httpd.conf:
27
+  
28
+ Port			443
29
+ UseSSL			Yes
30
+ SSLRSAPrivateKeyFile	/usr/local/ssl/certs/httpsd.pem
31
+ SSLCertificateFile	/usr/local/ssl/certs/httpsd.pem
32
+ 
33
+ If you don't have UseSSL set, or have UseSSL set to No, it won't use SSL.
34
+ 
35
+ If you don't specify SSLRSAPrivateKeyFile or SSLCertificateFile, it will
36
+ use the default files (specific to your installation of SSL, the paths
37
+ given in the example are from the default installation of SSLeay).
38
+ 
39
+ Important note: don't use a pass phrase to encrypt your keys, or the
40
+                 daemon won't be able to read them!
41
+ 
42
+ Run 'make certificate' to generate a self-signed certificate for testing
43
+ purposes (set SSLTOP to the installation directory of SSLeay).
44
+ 
45
+ For more general remarks on SSLified applications, see:
46
+ 
47
+ 	ftp://ftp.psy.uq.oz.au/pub/Crypto/SSLapps/README.apps
48
+ 
49
+ -- 
50
+ -- 19960410, Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
51
*** WWW/Makefile.orig	Sat Jun 11 13:52:14 1994
52
--- WWW/Makefile	Mon Apr 15 10:13:51 1996
53
***************
54
*** 24,26 ****
55
--- 24,38 ----
56
  	rm -f Daemon/[a-z0-9]*/cgiparse
57
  	rm -f Daemon/[a-z0-9]*/cgiutils
58
  
59
+ #
60
+ # Target for generating a self-signed test certificate for the SSLified
61
+ # version of httpd (see README-HTTPS).
62
+ #
63
+ SSLTOP=/usr/local/ssl
64
+ certificate:
65
+ 	(\
66
+ 	cd $(SSLTOP)/certs; \
67
+ 	req -new -x509 -nodes -out httpsd.pem -keyout httpsd.pem; \
68
+ 	ln -s httpsd.pem `x509 -noout -hash < httpsd.pem`.0 ;\
69
+ 	chmod 644 $(SSLTOP)/certs/httpsd.pem; \
70
+ 	)
71
*** WWW/Library/Implementation/HTFormat.h.orig	Sun Sep 25 15:15:26 1994
72
--- WWW/Library/Implementation/HTFormat.h	Wed Apr 10 17:25:38 1996
73
***************
74
*** 61,66 ****
75
--- 61,67 ----
76
          char * input_pointer;
77
          char * input_limit;
78
          int input_file_number;
79
+         void *  ssl_con;
80
          BOOL    s_do_buffering;
81
          char *  s_buffer;
82
          int     s_buffer_size;
83
*** WWW/Library/Implementation/HTFormat.c.orig	Thu Sep 29 14:24:15 1994
84
--- WWW/Library/Implementation/HTFormat.c	Wed Apr 10 17:25:39 1996
85
***************
86
*** 51,56 ****
87
--- 51,59 ----
88
  #include "HTGuess.h"
89
  #include "HTError.h"
90
  
91
+ #ifdef USE_SSL
92
+ #include <ssl.h>
93
+ #endif /* USE_SSL */
94
  
95
  PUBLIC	BOOL HTOutputSource = NO;	/* Flag: shortcut parser to stdout */
96
  
97
***************
98
*** 474,480 ****
99
      int ch;
100
      do {
101
  	if (isoc-> input_pointer >= isoc->input_limit) {
102
! 	    int status = NETREAD(
103
  		   isoc->input_file_number,
104
  		   isoc->input_buffer, INPUT_BUFFER_SIZE);
105
  	    if (status <= 0) {
106
--- 477,491 ----
107
      int ch;
108
      do {
109
  	if (isoc-> input_pointer >= isoc->input_limit) {
110
! 	    int status =
111
! #ifdef USE_SSL
112
! 	        (isoc->ssl_con != NULL) ?
113
! 	        SSL_read(
114
! 		   isoc->ssl_con,
115
! 		   isoc->input_buffer, INPUT_BUFFER_SIZE)
116
! 		:
117
! #endif /* USE_SSL */
118
! 	        NETREAD(
119
  		   isoc->input_file_number,
120
  		   isoc->input_buffer, INPUT_BUFFER_SIZE);
121
  	    if (status <= 0) {
122
***************
123
*** 507,513 ****
124
  					   int *,		len)
125
  {
126
      if (isoc->input_pointer >= isoc->input_limit) {
127
! 	int status = NETREAD(isoc->input_file_number,
128
  			     isoc->input_buffer,
129
  			     ((*len < INPUT_BUFFER_SIZE) ?
130
  			      *len : INPUT_BUFFER_SIZE));
131
--- 518,533 ----
132
  					   int *,		len)
133
  {
134
      if (isoc->input_pointer >= isoc->input_limit) {
135
! 	int status =
136
! #ifdef USE_SSL
137
! 	    (isoc->ssl_con != NULL) ?
138
! 	    SSL_read(isoc->ssl_con,
139
! 			     isoc->input_buffer,
140
! 			     ((*len < INPUT_BUFFER_SIZE) ?
141
! 			      *len : INPUT_BUFFER_SIZE))
142
! 	    :
143
! #endif /* USE_SSL */
144
! 	    NETREAD(isoc->input_file_number,
145
  			     isoc->input_buffer,
146
  			     ((*len < INPUT_BUFFER_SIZE) ?
147
  			      *len : INPUT_BUFFER_SIZE));
148
***************
149
*** 538,544 ****
150
  	int status;
151
  
152
  	isoc->input_pointer = isoc->input_buffer;
153
! 	status = NETREAD(isoc->input_file_number,
154
  			 isoc->input_buffer,
155
  			 INPUT_BUFFER_SIZE);
156
  	if (status <= 0) {
157
--- 558,572 ----
158
  	int status;
159
  
160
  	isoc->input_pointer = isoc->input_buffer;
161
! 	status =
162
! #ifdef USE_SSL
163
! 	    (isoc->ssl_con != NULL) ?
164
! 	    SSL_read(isoc->ssl_con,
165
! 			 isoc->input_buffer,
166
! 			 INPUT_BUFFER_SIZE)
167
! 	    :
168
! #endif /* USE_SSL */
169
! 	    NETREAD(isoc->input_file_number,
170
  			 isoc->input_buffer,
171
  			 INPUT_BUFFER_SIZE);
172
  	if (status <= 0) {
173
*** WWW/Library/Implementation/HTWriter.h.orig	Sun Sep 25 15:15:20 1994
174
--- WWW/Library/Implementation/HTWriter.h	Wed Apr 10 17:25:41 1996
175
***************
176
*** 17,26 ****
177
  
178
  #include "HTStream.h"
179
  
180
! extern HTStream * HTWriter_new PARAMS((int soc));
181
! extern HTStream * HTWriter_newNoClose PARAMS((int soc));
182
  
183
! extern HTStream * HTASCIIWriter PARAMS((int soc));
184
  
185
  #endif
186
  
187
--- 17,26 ----
188
  
189
  #include "HTStream.h"
190
  
191
! extern HTStream * HTWriter_new PARAMS((int soc, void *ssl_con));
192
! extern HTStream * HTWriter_newNoClose PARAMS((int soc, void *ssl_con));
193
  
194
! extern HTStream * HTASCIIWriter PARAMS((int soc, void *ssl_con));
195
  
196
  #endif
197
  
198
*** WWW/Library/Implementation/HTWriter.c.orig	Sun Sep 25 14:53:45 1994
199
--- WWW/Library/Implementation/HTWriter.c	Wed Apr 10 17:25:40 1996
200
***************
201
*** 9,14 ****
202
--- 9,18 ----
203
  #include "HTUtils.h"
204
  #include "tcp.h"
205
  
206
+ #ifdef USE_SSL
207
+ #include <ssl.h>
208
+ #endif /* USE_SSL */
209
+ 
210
  /*		HTML Object
211
  **		-----------
212
  */
213
***************
214
*** 17,22 ****
215
--- 21,27 ----
216
  	CONST HTStreamClass *	isa;
217
  
218
  	int	soc;
219
+ 	void	*ssl_con;
220
  	char	*write_pointer;
221
  	char 	buffer[BUFFER_SIZE];
222
  	BOOL	leave_open;
223
***************
224
*** 48,54 ****
225
  	status = NETWRITE(me->soc, me->buffer,  /* Put timeout? @@@ */
226
  			write_pointer - read_pointer);
227
  #endif /* OLD_CODE */
228
! 	status = NETWRITE(me->soc, read_pointer, write_pointer - read_pointer);
229
  	if (status<0) {
230
  	    if(TRACE) fprintf(stderr,
231
  	    "HTWrite: Error: write() on socket returns %d !!!\n", status);
232
--- 53,65 ----
233
  	status = NETWRITE(me->soc, me->buffer,  /* Put timeout? @@@ */
234
  			write_pointer - read_pointer);
235
  #endif /* OLD_CODE */
236
! 	status =
237
! #ifdef USE_SSL
238
! 	    (me->ssl_con != NULL) ?
239
! 	    SSL_write(me->ssl_con, read_pointer, write_pointer - read_pointer)
240
! 	    :
241
! #endif /* USE_SSL */
242
! 	    NETWRITE(me->soc, read_pointer, write_pointer - read_pointer);
243
  	if (status<0) {
244
  	    if(TRACE) fprintf(stderr,
245
  	    "HTWrite: Error: write() on socket returns %d !!!\n", status);
246
***************
247
*** 110,116 ****
248
      }
249
  #endif
250
      while (read_pointer < write_pointer) {
251
!         int status = NETWRITE(me->soc, read_pointer,
252
  			write_pointer - read_pointer);
253
  	if (status<0) {
254
  	    if(TRACE) fprintf(stderr,
255
--- 121,134 ----
256
      }
257
  #endif
258
      while (read_pointer < write_pointer) {
259
!         int status =
260
! #ifdef USE_SSL
261
! 	    (me->ssl_con != NULL) ?
262
! 	    SSL_write(me->ssl_con, read_pointer,
263
! 			write_pointer - read_pointer)
264
! 	    :
265
! #endif /* USE_SSL */
266
! 	    NETWRITE(me->soc, read_pointer,
267
  			write_pointer - read_pointer);
268
  	if (status<0) {
269
  	    if(TRACE) fprintf(stderr,
270
***************
271
*** 161,167 ****
272
  **	-------------------------
273
  */
274
  
275
! PUBLIC HTStream* HTWriter_new ARGS1(int, soc)
276
  {
277
      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
278
      if (me == NULL) outofmem(__FILE__, "HTML_new");
279
--- 179,185 ----
280
  **	-------------------------
281
  */
282
  
283
! PUBLIC HTStream* HTWriter_new ARGS2(int, soc, void *, ssl_con)
284
  {
285
      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
286
      if (me == NULL) outofmem(__FILE__, "HTML_new");
287
***************
288
*** 171,183 ****
289
      me->make_ascii = NO;
290
  #endif    
291
      me->soc = soc;
292
      me->write_pointer = me->buffer;
293
      return me;
294
  }
295
  
296
! PUBLIC HTStream* HTWriter_newNoClose ARGS1(int, soc)
297
  {
298
!     HTStream * me = HTWriter_new(soc);
299
      if (me) me->leave_open = YES;
300
      return me;
301
  }
302
--- 189,202 ----
303
      me->make_ascii = NO;
304
  #endif    
305
      me->soc = soc;
306
+     me->ssl_con = ssl_con;
307
      me->write_pointer = me->buffer;
308
      return me;
309
  }
310
  
311
! PUBLIC HTStream* HTWriter_newNoClose ARGS2(int, soc, void *, ssl_con)
312
  {
313
!     HTStream * me = HTWriter_new(soc, ssl_con);
314
      if (me) me->leave_open = YES;
315
      return me;
316
  }
317
***************
318
*** 187,193 ****
319
  **	-------------------------
320
  */
321
  
322
! PUBLIC HTStream* HTASCIIWriter ARGS1(int, soc)
323
  {
324
      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
325
      if (me == NULL) outofmem(__FILE__, "HTML_new");
326
--- 206,212 ----
327
  **	-------------------------
328
  */
329
  
330
! PUBLIC HTStream* HTASCIIWriter ARGS2(int, soc, void *, ssl_con)
331
  {
332
      HTStream* me = (HTStream*)calloc(1,sizeof(*me));
333
      if (me == NULL) outofmem(__FILE__, "HTML_new");
334
***************
335
*** 197,202 ****
336
--- 216,222 ----
337
      me->make_ascii = YES;
338
  #endif    
339
      me->soc = soc;
340
+     me->ssl_con = ssl_con;
341
      me->write_pointer = me->buffer;
342
      return me;
343
  }
344
*** WWW/Daemon/Implementation/HTConfig.h.orig	Sun Sep 25 14:55:28 1994
345
--- WWW/Daemon/Implementation/HTConfig.h	Wed Apr 10 17:17:09 1996
346
***************
347
*** 45,50 ****
348
--- 45,53 ----
349
      char *	hostname;		/* Used for CGI scripts		*/
350
      HTServType	server_type;		/* Standalone or inetd		*/
351
      int		port;			/* Default port number string	*/
352
+     BOOL	use_ssl;		/* Am I an https server?	*/
353
+     char *	ssl_key_file;		/* RSA private key file		*/
354
+     char *	ssl_cert_file;		/* Certificate file		*/
355
      BOOL	no_bg;			/* Don't auto-go background	*/
356
      BOOL	standalone;		/* Am I standalone?		*/
357
      char *	server_root;		/* Server's "home directory"	*/
358
*** WWW/Daemon/Implementation/HTConfig.c.orig	Mon Sep 26 15:22:52 1994
359
--- WWW/Daemon/Implementation/HTConfig.c	Wed Apr 10 17:17:09 1996
360
***************
361
*** 115,120 ****
362
--- 115,123 ----
363
      sc.output_timeout = DEFAULT_OUTPUT_TIMEOUT;
364
      sc.script_timeout = DEFAULT_SCRIPT_TIMEOUT;
365
      sc.do_accept_hack = YES;
366
+     sc.use_ssl = NO;
367
+     sc.ssl_key_file = NULL;
368
+     sc.ssl_cert_file = NULL;
369
      sc.disabled[ (int)METHOD_PUT ] = YES;
370
      sc.disabled[ (int)METHOD_DELETE ] = YES;
371
      sc.disabled[ (int)METHOD_CHECKIN ] = YES;
372
***************
373
*** 1819,1824 ****
374
--- 1822,1839 ----
375
  		}
376
  	    }
377
  
378
+ #ifdef USE_SSL
379
+ 	} else if (!strcmp(vec[0], "usessl")) {
380
+ 	    sc.use_ssl = positive(vec[1]);
381
+ 	    CTRACE(stderr,"SSL......... %sabled\n",
382
+ 		   sc.use_ssl ? "en" : "dis");
383
+ 	} else if (!strcmp(vec[0], "sslrsaprivatekeyfile")) {
384
+ 	    sc.ssl_key_file = tilde_to_home(vec[1]);
385
+ 	    CTRACE(stderr, "SSLKeyFile.. %s\n", sc.ssl_key_file);
386
+ 	} else if (!strcmp(vec[0], "sslcertificatefile")) {
387
+ 	    sc.ssl_cert_file = tilde_to_home(vec[1]);
388
+ 	    CTRACE(stderr, "SSLCertFile. %s\n", sc.ssl_cert_file);
389
+ #endif /* USE_SSL */
390
  	} else if (!strncmp(vec[0],"pidfile",7)) {
391
  	    sc.pid_file = tilde_to_home(vec[1]);
392
  	    CTRACE(stderr, "PidFile..... %s\n", sc.pid_file);
393
*** WWW/Daemon/Implementation/HTDaemon.c.orig	Mon Sep 26 15:23:00 1994
394
--- WWW/Daemon/Implementation/HTDaemon.c	Wed Apr 10 17:17:11 1996
395
***************
396
*** 193,198 ****
397
--- 193,202 ----
398
  #endif
399
  
400
  
401
+ #ifdef USE_SSL
402
+ #include <ssl.h>
403
+ #endif /* USE_SSL */
404
+ 
405
  
406
  #ifdef VMS
407
  #define gc()
408
***************
409
*** 228,233 ****
410
--- 232,243 ----
411
  #endif /* FORKING */
412
  PRIVATE int script_pid = 0;
413
  
414
+ #ifdef USE_SSL
415
+ SSL_CTX	*ssl_ctx;
416
+ char	ssl_file_path[1024];
417
+ #endif /* USE_SSL */
418
+ void	*ssl_con;
419
+ 
420
  /*      Program-Global Variables
421
  **      ------------------------
422
  */
423
***************
424
*** 1559,1564 ****
425
--- 1569,1575 ----
426
      reset_server_env();
427
  
428
      isoc = HTInputSocket_new(soc);
429
+     isoc->ssl_con = ssl_con;
430
  
431
      input_timeout_on();
432
      req = HTParseRequest(isoc);
433
***************
434
*** 1571,1577 ****
435
  
436
      HTSoc = soc;
437
      req->isoc = isoc;
438
!     req->output_stream = HTWriter_newNoClose(soc);
439
  
440
      if (req->method == METHOD_INVALID) {
441
          if (HTReqLine) {
442
--- 1582,1588 ----
443
  
444
      HTSoc = soc;
445
      req->isoc = isoc;
446
!     req->output_stream = HTWriter_newNoClose(soc, isoc->ssl_con);
447
  
448
      if (req->method == METHOD_INVALID) {
449
          if (HTReqLine) {
450
***************
451
*** 2183,2188 ****
452
--- 2194,2243 ----
453
                  CTRACE(stderr, "Child....... I'%s\n",
454
                         do_gc ? "ll do gc upon exit" : "m alive");
455
  
456
+ #ifdef USE_SSL
457
+ 		if (sc.use_ssl) {
458
+ 		    SSL_set_fd(ssl_con, com_soc);
459
+ 
460
+ 		    /*
461
+ 		     * Use default paths and filename "httpsd.pem" for public
462
+ 		     * and private key if not specified in the config.
463
+ 		     * Note: don't encrypt the key with a pass phrase!
464
+ 		     */
465
+ 		    if (SSL_use_RSAPrivateKey_file(ssl_con,
466
+ 			    sc.ssl_key_file ? sc.ssl_key_file : ssl_file_path,
467
+ 			    X509_FILETYPE_PEM) <= 0) {
468
+ 			fprintf(stderr, "SSL_use_RSAPrivateKey_file(%s) error ",
469
+ 			    sc.ssl_key_file ? sc.ssl_key_file : ssl_file_path);
470
+ 			ERR_print_errors(stderr);
471
+ 			fflush(stderr);
472
+ 			_exit(1);
473
+ 		    }
474
+ 
475
+ 		    if (SSL_use_certificate_file(ssl_con,
476
+ 			    sc.ssl_cert_file ? sc.ssl_cert_file : ssl_file_path,
477
+ 			    X509_FILETYPE_PEM) <= 0) {
478
+ 			fprintf(stderr, "SSL_use_certificate_file(%s) error ",
479
+ 			    sc.ssl_cert_file ? sc.ssl_cert_file : ssl_file_path);
480
+ 			ERR_print_errors(stderr);
481
+ 			fflush(stderr);
482
+ 			_exit(1);
483
+ 		    }
484
+ 
485
+ 		    /*
486
+ 		     * TODO:
487
+ 		     * Call SSL_set_verify(ssl_con, SSL_VERIFY_..., ...)
488
+ 		     */
489
+ 
490
+ 		    if (SSL_accept(ssl_con) <= 0) {
491
+ 			fprintf(stderr, "SSL_accept error %s\n",
492
+ 			    ERR_error_string(ERR_get_error(), NULL));
493
+ 			fflush(stderr);
494
+ 			SSL_free(ssl_con);
495
+ 			_exit(1);
496
+ 		    }
497
+ 		}
498
+ #endif /* USE_SSL */
499
+ 
500
                  /*
501
                   * This no-linger stuff is borrowed from NCSA httpd code.
502
                   * In Linux this causes problems -- is this necessary at
503
***************
504
*** 3044,3051 ****
505
  
506
      if (sc.server_type == SERVER_TYPE_STANDALONE) {
507
          if (!sc.port) {
508
!             sc.port = 80;
509
!             CTRACE(stderr,"Default..... port 80 for standalone server\n");
510
          }
511
      }
512
      else if (sc.server_type == SERVER_TYPE_INETD) {
513
--- 3099,3113 ----
514
  
515
      if (sc.server_type == SERVER_TYPE_STANDALONE) {
516
          if (!sc.port) {
517
!             sc.port =
518
! #ifdef USE_SSL
519
!                 sc.use_ssl ?
520
!                 443
521
!                 :
522
! #endif /* SSL */
523
!                 80;
524
!             CTRACE(stderr,"Default..... port %d for standalone server\n",
525
!                 sc.port);
526
          }
527
      }
528
      else if (sc.server_type == SERVER_TYPE_INETD) {
529
***************
530
*** 3243,3248 ****
531
--- 3305,3326 ----
532
      if (status<0 && role != passive) {
533
          exit(status);
534
      }
535
+ 
536
+     ssl_con = NULL;
537
+ #ifdef USE_SSL
538
+     if (sc.use_ssl) {
539
+ 	SSL_load_error_strings();
540
+ 	ssl_ctx = (SSL_CTX *)SSL_CTX_new();
541
+ 	ssl_con = (SSL *)SSL_new(ssl_ctx);
542
+ 	sprintf(ssl_file_path, "%s/%s", X509_get_default_cert_dir(), "httpsd.pem");
543
+ 
544
+ 	if (!X509_set_default_verify_paths(ssl_ctx->cert)) {
545
+ 	    fprintf(stderr,"HTTPSD ERROR: cannot load certificates via X509_set_default_verify_paths\n");
546
+ 	    ERR_print_errors(stderr);
547
+ 	    exit(1);
548
+ 	}
549
+     }
550
+ #endif /* USE_SSL */
551
  
552
      exit(0);
553
      return 0;   /* NOTREACHED -- For gcc */
(-)w3c-httpd/patches/PATCHKIT.diff (+707 lines)
Line 0 Link Here
1
*** 1.1	1995/07/11 17:09:01
2
--- Library/Implementation/HTAAServ.c	1995/07/12 20:54:32
3
***************
4
*** 571,576 ****
5
--- 571,588 ----
6
       */
7
      StrAllocCopy(untranslated, HTReqArgPath);
8
  
9
+     if (sc.virtualize) {					/* JPH003 */
10
+         char * vpath;						/* JPH003 */
11
+ 								/* JPH003 */
12
+         vpath = (char *)malloc(1 + strlen(HTVirtualHost) +	/* JPH003 */
13
+                                strlen(HTReqArgPath) + 1);	/* JPH003 */
14
+         sprintf(vpath, "/%s%s", HTVirtualHost, HTReqArgPath);	/* JPH003 */
15
+         CTRACE(stderr, "Virtualize.. %s -> %s\n",		/* JPH003 */
16
+                HTReqArgPath, vpath);				/* JPH003 */
17
+         StrAllocCopy(HTReqArgPath, vpath);			/* JPH003 */
18
+         free(vpath);						/* JPH003 */
19
+     }								/* JPH003 */
20
+ 
21
      /*
22
      ** Translate into absolute pathname, and
23
      ** get protection by "protect" and "defprot" rules.
24
***************
25
*** 618,623 ****
26
--- 630,646 ----
27
  			    StrAllocCat(welcome, "/");
28
  			    physical = HTMulti(req, welcome, &stat_info2);
29
  			    free(welcome);
30
+ 
31
+                             if (physical &&			/* JPH003 */
32
+                                 !S_ISDIR(stat_info2.st_mode) &&	/* JPH003 */
33
+                                 sc.virtualize) {		/* JPH003 */
34
+                                 CTRACE(stderr,			/* JPH003 */
35
+                                   "UnVirtualize %s -> %s\n",	/* JPH003 */
36
+                                   HTReqArgPath,			/* JPH003 */
37
+                                   untranslated);		/* JPH003 */
38
+                                 strcpy(HTReqArgPath,		/* JPH003 */
39
+                                        untranslated);		/* JPH003 */
40
+                             }					/* JPH003 */
41
  
42
  			    if (physical && !S_ISDIR(stat_info2.st_mode)) {
43
  				char * escaped = HTEscape(HTReqArgPath,
44
*** 1.1	1995/07/14 15:49:18
45
--- Library/Implementation/HTConfig.c	1995/07/14 15:56:01
46
***************
47
*** 111,116 ****
48
--- 111,118 ----
49
   */
50
  PUBLIC void HTDefaultConfig NOARGS
51
  {
52
+     sc.virtualize = NO;						/* JPH003 */
53
+     sc.workers = 0;						/* JPH004 */
54
      sc.input_timeout = DEFAULT_INPUT_TIMEOUT;
55
      sc.output_timeout = DEFAULT_OUTPUT_TIMEOUT;
56
      sc.script_timeout = DEFAULT_SCRIPT_TIMEOUT;
57
***************
58
*** 1233,1238 ****
59
--- 1235,1255 ----
60
  	} else if (strstr(vec[0],"icon")) {	/* All *Icon* directives */
61
  	    icon_config(vec,c);
62
  
63
+ 	} else if (strstr(vec[0], "virtualize")) {		/* JPH003 */
64
+ 	    sc.virtualize = positive(vec[1]);			/* JPH003 */
65
+ 	    CTRACE(stderr, "Virtualize.. %s\n",			/* JPH003 */
66
+ 		   sc.virtualize ? "On" : "Off");		/* JPH003 */
67
+ 								/* JPH003 */
68
+ 	} else if (strstr(vec[0], "workers")) {			/* JPH004 */
69
+ 	    sc.workers = atoi(vec[1]);				/* JPH004 */
70
+ 	    if (sc.workers) {					/* JPH004 */
71
+ 		CTRACE(stderr,					/* JPH004 */
72
+ 		       "PreForking.. On, %d workers\n",		/* JPH004 */
73
+ 		       sc.workers);				/* JPH004 */
74
+ 	    } else { 						/* JPH004 */
75
+ 		CTRACE(stderr, "PreForking.. Off\n");		/* JPH004 */
76
+ 	    }							/* JPH004 */
77
+ 								/* JPH004 */
78
  	} else if (!strncmp(vec[0], "serverroot", 10)) {
79
  	    sc.server_root = tilde_to_home(vec[1]);
80
  	    HTSaveLocallyDir = sc.server_root;		/* Henrik Aug 31, 94 */
81
*** 1.1	1995/07/11 17:09:06
82
--- Library/Implementation/HTConfig.h	1995/07/12 21:50:59
83
***************
84
*** 47,52 ****
85
--- 47,54 ----
86
      int		port;			/* Default port number string	*/
87
      BOOL	no_bg;			/* Don't auto-go background	*/
88
      BOOL	standalone;		/* Am I standalone?		*/
89
+     BOOL	virtualize;		/* multi-home mode? */	/* JPH003 */
90
+     int		workers;		/* preforking mode? */	/* JPH004 */
91
      char *	server_root;		/* Server's "home directory"	*/
92
      int		security_level;		/* 0 = normal, 1 = high		*/
93
      char *	errormsg_path;		/* URL for error messages	*/
94
*** 1.1	1995/07/11 17:09:07
95
--- Library/Implementation/HTDaemon.c	1995/10/11 16:56:00
96
***************
97
*** 161,166 ****
98
--- 161,168 ----
99
  #include <signal.h>
100
  #include <sys/param.h>
101
  #include <errno.h>
102
+ #include <sys/uio.h>						/* JPH004 */
103
+ #include <setjmp.h>						/* JPH007 */
104
  
105
  #ifndef SIGCLD
106
  #ifdef SIGCHLD
107
***************
108
*** 251,256 ****
109
--- 253,260 ----
110
  /*      Server environment when handling requests
111
  **      -----------------------------------------
112
  */
113
+ PUBLIC jmp_buf		HTJumpEnv;				/* JPH007 */
114
+ PUBLIC char *           HTVirtualHost           = NULL;		/* JPH003 */
115
  PUBLIC char *           HTReasonLine            = NULL;
116
  PUBLIC int              HTSoc                   = 0;
117
  PUBLIC char *           HTReqLine               = NULL;
118
***************
119
*** 532,543 ****
120
--- 536,556 ----
121
  {
122
      if (sc.standalone) {
123
  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
124
+         if (kill(-pgrp, SIGTERM) == 0) {			/* JPH001 */
125
+         	kill(-pgrp, SIGCONT);				/* JPH001 */
126
+ 		sleep(5);					/* JPH001 */
127
+ 	}							/* JPH001 */
128
          kill(-pgrp, SIGKILL);
129
  #else
130
+         if (killpg(pgrp, SIGTERM) == 0) {			/* JPH001 */
131
+         	killpg(pgrp, SIGCONT);				/* JPH001 */
132
+ 		sleep(5);					/* JPH001 */
133
+ 	}							/* JPH001 */
134
          killpg(pgrp, SIGKILL);
135
  #endif
136
          shutdown(master_soc, 2);
137
          close(master_soc);
138
+ 	exit(1);						/* JPH001 */
139
      }
140
  }
141
  
142
***************
143
*** 580,585 ****
144
--- 593,600 ----
145
  
146
  PRIVATE void sig_pipe NOARGS
147
  {
148
+     PRIVATE void clean_exit NOARGS;				/* JPH007 */
149
+ 
150
      if (!sigpipe_caught) {
151
          if (HTReqLine)
152
              HTLog_error2("Connection interrupted [SIGPIPE], req:",HTReqLine);
153
***************
154
*** 587,592 ****
155
--- 602,614 ----
156
              HTLog_error("Connection interrupted [SIGPIPE]");
157
      }
158
  
159
+     if (sc.workers) {						/* JPH004 */
160
+         CTRACE(stderr, "SIGPIPE..... ignored (pre-forking)\n");	/* JPH004 */
161
+         sigpipe_caught = YES;					/* JPH004 */
162
+         set_signals();						/* JPH004 */
163
+         return;							/* JPH004 */
164
+     }								/* JPH004 */
165
+ 
166
      if (ignore_sigpipes) {
167
          CTRACE(stderr, "SIGPIPE..... ignored (writing to cache)\n");
168
          sigpipe_caught = YES;
169
***************
170
*** 595,605 ****
171
      else {
172
          timeout_off();  /* So timeouts don't go to parent */
173
          CTRACE(stderr, "SIGPIPE..... caught, exiting...\n");
174
!         if (com_soc > 0) {
175
!             shutdown(com_soc, 2);
176
!             NETCLOSE(com_soc);
177
!         }
178
!         exit(0);
179
      }
180
  }
181
  
182
--- 617,623 ----
183
      else {
184
          timeout_off();  /* So timeouts don't go to parent */
185
          CTRACE(stderr, "SIGPIPE..... caught, exiting...\n");
186
!         clean_exit();						/* JPH007 */
187
      }
188
  }
189
  
190
***************
191
*** 1444,1449 ****
192
--- 1462,1471 ----
193
          shutdown(com_soc, 2);
194
          NETCLOSE(com_soc);
195
      }
196
+     if (sc.workers) {						/* JPH007 */
197
+         longjmp(HTJumpEnv, 1);					/* JPH007 */
198
+         HTLog_error("Worker failed to long-jump back");		/* JPH007 */
199
+     }								/* JPH007 */
200
      exit(0);
201
  }
202
  
203
***************
204
*** 1625,1630 ****
205
--- 1647,1666 ----
206
      HTVMS_enableSysPrv();
207
  #endif /* VMS */
208
  
209
+     if (sc.virtualize) {					/* JPH003 */
210
+         SockA vaddr;						/* JPH003 */
211
+         int vlen = sizeof(vaddr);				/* JPH003 */
212
+ 								/* JPH003 */
213
+         memset((char*)&vaddr, 0, sizeof(vaddr));		/* JPH003 */
214
+         getsockname(com_soc, (struct sockaddr*)&vaddr, &vlen);	/* JPH003 */
215
+         StrAllocCopy(HTVirtualHost, HTInetString(&vaddr));	/* JPH003 */
216
+         if (!HTVirtualHost || !*HTVirtualHost) {		/* JPH003 */
217
+ 		StrAllocCopy(HTVirtualHost, "0.0.0.0");		/* JPH003 */
218
+ 	}							/* JPH003 */
219
+         CTRACE(stderr, "Connection... via address %s\n",	/* JPH003 */
220
+                HTVirtualHost);					/* JPH003 */
221
+     }								/* JPH003 */
222
+ 
223
      out.status_code = HTAA_checkAuthorization(req);
224
      CTRACE(stderr, "AA.......... check returned %d\n", out.status_code);
225
      CTRACE(stderr, "Translated.. \"%s\"\n",
226
***************
227
*** 2063,2069 ****
228
  }
229
  #endif /* not VMS */
230
  
231
! 
232
  
233
  /*                                                    standalone_server_loop()
234
   *      New server_loop() for Unixes in standalone mode
235
--- 2099,2413 ----
236
  }
237
  #endif /* not VMS */
238
  
239
! #if !defined(VMS) && defined(FORKING)				/* JPH004 */
240
! PRIVATE int wait_for_work ARGS1(int, fd)			/* JPH004 */
241
! {								/* JPH004 */
242
!     struct iovec iov[1];					/* JPH004 */
243
!     struct msghdr msg;						/* JPH004 */
244
!     int passedfd = -1;		/* just in case */		/* JPH004 */
245
!     char dummy;							/* JPH004 */
246
! 								/* JPH004 */
247
!     iov[0].iov_base = &dummy;					/* JPH004 */
248
!     iov[0].iov_len = 1;						/* JPH004 */
249
!     msg.msg_name = NULL;					/* JPH004 */
250
!     msg.msg_namelen = 0;					/* JPH004 */
251
!     msg.msg_iov = iov;						/* JPH004 */
252
!     msg.msg_iovlen = 1;						/* JPH004 */
253
!     msg.msg_accrights = (caddr_t)&passedfd;			/* JPH004 */
254
!     msg.msg_accrightslen = sizeof(passedfd);			/* JPH004 */
255
!     while (recvmsg(fd, &msg, 0) == -1) {			/* JPH007 */
256
!         if (errno != EINTR) {					/* JPH007 */
257
!             HTLog_error("Failed to recvmsg in worker\n");	/* JPH004 */
258
!             _exit(1);						/* JPH004 */
259
!         }							/* JPH007 */
260
!     }								/* JPH004 */
261
!     return passedfd;						/* JPH004 */
262
! }								/* JPH004 */
263
! 								/* JPH004 */
264
! PRIVATE int work_completed ARGS1(HTWorkerStruct *, wp)		/* JPH004 */
265
! {								/* JPH004 */
266
!     return send(wp->fd, &wp->index, sizeof(wp->index), 0);	/* JPH004 */
267
! }								/* JPH004 */
268
! 								/* JPH004 */
269
! PRIVATE int do_work ARGS1(HTWorkerStruct *, wp)			/* JPH004 */
270
! {								/* JPH004 */
271
!     int tcp_status;						/* JPH004 */
272
!     static struct linger sl = {1, 600};				/* JPH004 */
273
!     SockA addr;							/* JPH004 */
274
!     int alen = sizeof(addr);					/* JPH004 */
275
!     char * host;						/* JPH004 */
276
!     int fd;							/* JPH008 */
277
!     int closemask = 0;						/* JPH008 */
278
! 								/* JPH004 */
279
!     for (fd = 0; fd < 32; ++fd) {				/* JPH008 */
280
!         closemask |= (!~fcntl(fd, F_GETFD, 0) << fd);		/* JPH008 */
281
!     }								/* JPH008 */
282
!     for (;;) {							/* JPH004 */
283
!         com_soc = wait_for_work(wp->fd);			/* JPH004 */
284
!         time(&cur_time);					/* JPH004 */
285
!         child_serial++;						/* JPH004 */
286
!         CTRACE(stderr, "Worker...... I'm awake\n");		/* JPH004 */
287
!         if (sc.do_linger) {					/* JPH004 */
288
!             setsockopt(com_soc, SOL_SOCKET, SO_LINGER,		/* JPH004 */
289
!                        (char*)&sl, sizeof(sl));			/* JPH004 */
290
!         }							/* JPH004 */
291
!         memset((char*)&addr, 0, sizeof(addr));			/* JPH004 */
292
!         getpeername(com_soc, (struct sockaddr*)&addr, &alen);	/* JPH004 */
293
!         host = HTInetString(&addr);				/* JPH004 */
294
!         if (!host || !*host) host = "0.0.0.0";			/* JPH004 */
295
!         StrAllocCopy(HTClientHost, host);			/* JPH004 */
296
!         FREE(HTClientHostName);					/* JPH004 */
297
!         if (sc.do_dns_lookup) {					/* JPH004 */
298
!             HTClientHostName = HTGetHostBySock(com_soc);	/* JPH004 */
299
!         }							/* JPH004 */
300
!         CTRACE(stderr, "Reading..... socket %d from host %s\n",	/* JPH004 */
301
!                com_soc, HTClientHost);				/* JPH004 */
302
!         remote_ident = NULL;					/* JPH004 */
303
!         if (sc.do_rfc931) { /* ...broken?... */ }		/* JPH004 */
304
!         sigpipe_caught = NO;					/* JPH004 */
305
!         if (setjmp(HTJumpEnv) == 0) {				/* JPH007 */
306
!             tcp_status = HTHandle(com_soc);			/* JPH004 */
307
!         }							/* JPH007 */
308
!         if (TRACE) {						/* JPH004 */
309
!             if (tcp_status < 0) {				/* JPH004 */
310
!                 fprintf(stderr,					/* JPH004 */
311
!                   "ERROR....... %d handling msg (errno=%d).\n",	/* JPH004 */
312
!                   tcp_status, errno);				/* JPH004 */
313
!             } else if (tcp_status == 0) {			/* JPH004 */
314
!                 fprintf(stderr,					/* JPH004 */
315
!                   "Socket...... %d disconnected by peer\n",	/* JPH004 */
316
!                   com_soc);					/* JPH004 */
317
!             }							/* JPH004 */
318
!         }							/* JPH004 */
319
!         shutdown(com_soc, 2);					/* JPH004 */
320
!         NETCLOSE(com_soc);					/* JPH004 */
321
!         for (fd = 0; fd < 32; ++fd) {				/* JPH008 */
322
!             if (closemask & (1 << fd)) close(fd);		/* JPH008 */
323
!         }							/* JPH008 */
324
!         work_completed(wp);					/* JPH004 */
325
!     }								/* JPH004 */
326
!     /*NOTREACHED*/						/* JPH004 */
327
! }								/* JPH004 */
328
! 								/* JPH004 */
329
! PRIVATE int getlocaldgram ARGS2(struct sockaddr_un *, sunp,	/* JPH004 */
330
!                                 int *, alenp)			/* JPH004 */
331
! {								/* JPH004 */
332
!     int sockfd;							/* JPH004 */
333
! 								/* JPH004 */
334
!     if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {	/* JPH004 */
335
!         HTLog_error("Failed to create UNIX/DGRAM socket\n");	/* JPH004 */
336
!         return -1;						/* JPH004 */
337
!     }								/* JPH004 */
338
!     sunp->sun_family = AF_UNIX;					/* JPH004 */
339
!     strcpy(sunp->sun_path, tempnam(NULL, "wwwSS"));		/* JPH004 */
340
!     *alenp = sizeof(sunp->sun_family) + strlen(sunp->sun_path);	/* JPH004 */
341
!     if (bind(sockfd, sunp, *alenp) == -1) {			/* JPH004 */
342
!         HTLog_error2("Failed to bind UNIX/DGRAM socket to %s",	/* JPH004 */
343
!                      sunp->sun_path);				/* JPH004 */
344
!         return -1;						/* JPH004 */
345
!     }								/* JPH004 */
346
!     return sockfd;						/* JPH004 */
347
! }								/* JPH004 */
348
! 								/* JPH004 */
349
! PRIVATE int make_worker ARGS3(HTWorkerStruct *, wp,		/* JPH004 */
350
!                               struct sockaddr_un *, bossp,	/* JPH004 */
351
!                               int, bosslen)			/* JPH004 */
352
! {								/* JPH004 */
353
!     wp->fd = getlocaldgram(&wp->addr, &wp->addrlen);		/* JPH004 */
354
!     if (wp->fd == -1) {						/* JPH004 */
355
!         HTLog_error("Failed to make worker process\n");		/* JPH004 */
356
!         return -1;						/* JPH004 */
357
!     }								/* JPH004 */
358
!     if (connect(wp->fd, bossp, bosslen) == -1) {		/* JPH004 */
359
!         HTLog_error("Failed to connect worker process\n");	/* JPH004 */
360
!         return -1;						/* JPH004 */
361
!     }								/* JPH004 */
362
!     if ((wp->pid = fork()) == 0) do_work(wp);			/* JPH004 */
363
!     if (wp->pid == -1) {					/* JPH004 */
364
!         HTLog_error("Failed to fork worker process\n");		/* JPH004 */
365
!     }								/* JPH004 */
366
!     close(wp->fd);						/* JPH004 */
367
!     wp->fd = -1;						/* JPH004 */
368
!     return (wp->pid);						/* JPH004 */
369
! }								/* JPH004 */
370
! 								/* JPH004 */
371
! PRIVATE int assign_work ARGS3(int, workerfd,			/* JPH004 */
372
!                               int, clientfd,			/* JPH004 */
373
!                               HTWorkerStruct *, wp)		/* JPH004 */
374
! {								/* JPH004 */
375
!     struct iovec iov[1];					/* JPH004 */
376
!     struct msghdr msg;						/* JPH004 */
377
! 								/* JPH004 */
378
!     iov[0].iov_base = "?";		/* any old byte */	/* JPH004 */
379
!     iov[0].iov_len = 1;						/* JPH004 */
380
!     msg.msg_name = (caddr_t)&wp->addr;				/* JPH004 */
381
!     msg.msg_namelen = wp->addrlen;				/* JPH004 */
382
!     msg.msg_iov = iov;						/* JPH004 */
383
!     msg.msg_iovlen = 1;						/* JPH004 */
384
!     msg.msg_accrights = (caddr_t)&clientfd;			/* JPH004 */
385
!     msg.msg_accrightslen = sizeof(clientfd);			/* JPH004 */
386
!     if (sendmsg(workerfd, &msg, 0) == -1) {			/* JPH004 */
387
!         HTLog_error("Failed to sendmsg to worker\n");		/* JPH004 */
388
!         return -1;						/* JPH004 */
389
!     }								/* JPH004 */
390
!     return 0;							/* JPH004 */
391
! }								/* JPH004 */
392
! 								/* JPH004 */
393
! PRIVATE int worker_done ARGS1(int, fd)				/* JPH004 */
394
! {								/* JPH004 */
395
!     int index = -1;			/* just in case */	/* JPH004 */
396
! 								/* JPH004 */
397
!     (void)recv(fd, &index, sizeof(index));			/* JPH004 */
398
!     return index;						/* JPH004 */
399
! }								/* JPH004 */
400
! 								/* JPH004 */
401
! 								/* JPH004 */
402
! /*      New server_loop() for Unixes in preforking mode */	/* JPH004 */
403
! 								/* JPH004 */
404
! PRIVATE int preforking_server_loop NOARGS			/* JPH004 */
405
! {								/* JPH004 */
406
!     int soc_addr_len = sizeof(client_soc_addr);			/* JPH004 */
407
!     int timeout;						/* JPH004 */
408
!     int worker_soc = -1;					/* JPH004 */
409
!     struct sockaddr_un boss;					/* JPH004 */
410
!     int blen;							/* JPH004 */
411
!     int nw = 0;							/* JPH004 */
412
!     HTWorkerStruct * worker = NULL;				/* JPH004 */
413
!     int * roster = NULL;					/* JPH004 */
414
!     int nIdle;							/* JPH004 */
415
!     int idle_index;	/* index in worker of just completed */	/* JPH004 */
416
!     int idle_slot;	/* and its slot in roster table */	/* JPH004 */
417
!     fd_set read_chans;						/* JPH004 */
418
!     struct timeval max_wait;					/* JPH004 */
419
!     int nfound;							/* JPH004 */
420
! 								/* JPH004 */
421
!     CTRACE(stderr, "ServerLoop.. Unix preforking\n");		/* JPH004 */
422
! 								/* JPH004 */
423
!     worker_soc = getlocaldgram(&boss, &blen);			/* JPH004 */
424
!     if (worker_soc == -1) goto fallback;			/* JPH004 */
425
!     worker = (HTWorkerStruct *)					/* JPH004 */
426
!       malloc(sc.workers * sizeof(HTWorkerStruct));		/* JPH004 */
427
!     if (worker == NULL) {					/* JPH004 */
428
!         HTLog_error("Worker alloc failed\n");			/* JPH004 */
429
!         goto fallback;						/* JPH004 */
430
!     }								/* JPH004 */
431
!     roster = (int *)malloc(sc.workers * sizeof(int));		/* JPH004 */
432
!     if (roster == NULL) {					/* JPH004 */
433
!         HTLog_error("Worker roster alloc failed\n");		/* JPH004 */
434
!         goto fallback;						/* JPH004 */
435
!     }								/* JPH004 */
436
!     for (nIdle = 0; nIdle < sc.workers; ++nIdle) {		/* JPH004 */
437
!         roster[nIdle] = nIdle;					/* JPH004 */
438
!     }								/* JPH004 */
439
!     for (nw = 0; nw < sc.workers; ++nw) {			/* JPH004 */
440
!         worker[nw].index = nw;					/* JPH004 */
441
!         worker[nw].slot = nw;					/* JPH004 */
442
!         if (make_worker(worker + nw, &boss, blen) == -1) break;	/* JPH004 */
443
!     }								/* JPH004 */
444
!     if (nw == 0) {						/* JPH004 */
445
!         HTLog_error("Unable to create any worker processes\n");	/* JPH004 */
446
!         goto fallback;						/* JPH004 */
447
!     }								/* JPH004 */
448
!     if (nw != sc.workers) {					/* JPH004 */
449
!         HTLog_errorN("Worker processes reduced to", nw);	/* JPH004 */
450
!         sc.workers = nw;					/* JPH004 */
451
!     }								/* JPH004 */
452
! 								/* JPH004 */
453
!     FD_ZERO(&open_sockets);					/* JPH004 */
454
!     FD_SET(worker_soc, &open_sockets);				/* JPH004 */
455
!     FD_SET(master_soc, &open_sockets);				/* JPH004 */
456
!     num_sockets = 1 +						/* JPH004 */
457
!       ((worker_soc > master_soc) ? worker_soc : master_soc);	/* JPH004 */
458
!     for (;;) {							/* JPH004 */
459
!         if (nIdle == 0) {					/* JPH004 */
460
!             HTLog_error("All workers busy, not accepting\n");	/* JPH004 */
461
!             FD_CLR(master_soc, &open_sockets);			/* JPH004 */
462
!         }							/* JPH004 */
463
!         read_chans = open_sockets;				/* JPH004 */
464
!         timeout = get_next_timeout();				/* JPH004 */
465
!         max_wait.tv_sec = timeout/100;				/* JPH004 */
466
!         max_wait.tv_usec = (timeout%100)*10000;			/* JPH004 */
467
!         timeout /= 100;						/* JPH004 */
468
!         if (TRACE) {						/* JPH004 */
469
!             fprintf(stderr,					/* JPH004 */
470
!               "Next timeout after %d hours %d mins %d secs\n",	/* JPH004 */
471
!                timeout/3600, (timeout/60)%60, timeout%60);	/* JPH004 */
472
!             fprintf(stderr,					/* JPH004 */
473
!               "Daemon...... %s (Mask=%x hex, max=%x hex).\n",	/* JPH004 */
474
!               "Waiting for connection",				/* JPH004 */
475
!               *(unsigned int *)(&read_chans),			/* JPH004 */
476
!               (unsigned int)num_sockets);			/* JPH004 */
477
!         }							/* JPH004 */
478
! #ifdef __hpux							/* JPH004 */
479
!         nfound = select(num_sockets,				/* JPH004 */
480
!           (int *)&read_chans, NULL, NULL,			/* JPH004 */
481
!           timeout > 0 ? &max_wait : NULL);			/* JPH004 */
482
! #else								/* JPH004 */
483
!         nfound = select(num_sockets,				/* JPH004 */
484
!           &read_chans, NULL, NULL,				/* JPH004 */
485
!           timeout > 0 ? &max_wait : NULL);			/* JPH004 */
486
! #endif								/* JPH004 */
487
!         if (nfound < 0) {   /* Interrupted */			/* JPH004 */
488
!             if (errno != EINTR) (void)HTInetStatus("select");	/* JPH004 */
489
!             continue;						/* JPH004 */
490
!         }							/* JPH004 */
491
!         if (nfound == 0) {  /* Timeout */			/* JPH004 */
492
!             CTRACE(stderr,					/* JPH004 */
493
!               "Time to do.. daily garbage collection\n");	/* JPH004 */
494
!             gc_pid = fork();					/* JPH004 */
495
!             if (!gc_pid) gc_and_exit(1,0);			/* JPH004 */
496
!             else continue;					/* JPH004 */
497
!         }							/* JPH004 */
498
!         if (FD_ISSET(worker_soc, &read_chans)) {		/* JPH004 */
499
!                 idle_index = worker_done(worker_soc);		/* JPH004 */
500
!                 if (idle_index != -1) {				/* JPH004 */
501
!                         idle_slot = worker[idle_index].slot;	/* JPH004 */
502
!                         roster[idle_slot] = roster[nIdle];	/* JPH004 */
503
!                         worker[roster[nIdle]].slot = idle_slot;	/* JPH004 */
504
!                         roster[nIdle] = idle_index;		/* JPH004 */
505
!                         worker[idle_index].slot = nIdle;	/* JPH004 */
506
!                         if (nIdle++ == 0) {			/* JPH004 */
507
!                             HTLog_error(			/* JPH004 */
508
!                               "A worker is now available\n");	/* JPH004 */
509
!                             FD_SET(master_soc, &open_sockets);	/* JPH004 */
510
!                         }					/* JPH004 */
511
!                 }						/* JPH004 */
512
!         }							/* JPH004 */
513
!         if (FD_ISSET(master_soc, &read_chans)) {		/* JPH004 */
514
!             CTRACE(stderr,					/* JPH004 */
515
!               "Daemon...... accepting connection...\n");	/* JPH004 */
516
!             com_soc = accept(master_soc,			/* JPH004 */
517
!               (struct sockaddr *)&client_soc_addr,		/* JPH004 */
518
!               &soc_addr_len);					/* JPH004 */
519
!             if (com_soc < 0) {					/* JPH004 */
520
!                 if (errno != EINTR) HTInetStatus("accept");	/* JPH004 */
521
!                 continue;					/* JPH004 */
522
!             }							/* JPH004 */
523
!             --nIdle;						/* JPH004 */
524
!             CTRACE(stderr,					/* JPH004 */
525
!               "Accepted.... socket %d, worker %d slot %d\n",	/* JPH004 */
526
!               com_soc, roster[nIdle], nIdle);			/* JPH004 */
527
!             assign_work(worker_soc, com_soc,			/* JPH004 */
528
!               worker + roster[nIdle]);				/* JPH004 */
529
!             NETCLOSE(com_soc);					/* JPH004 */
530
! #ifdef SIGTSTP  /* BSD */					/* JPH004 */
531
!             sig_child();	/* ??? redundant ??? */		/* JPH004 */
532
! #endif								/* JPH004 */
533
!         }							/* JPH004 */
534
!     } /* for loop */						/* JPH004 */
535
! 								/* JPH004 */
536
! fallback:							/* JPH004 */
537
!     if (worker_soc != -1) {					/* JPH004 */
538
!         close(worker_soc);					/* JPH004 */
539
!         unlink(boss.sun_path);					/* JPH004 */
540
!     }								/* JPH004 */
541
!     if (roster != NULL) free(roster);				/* JPH004 */
542
!     if (worker != NULL) free(worker);				/* JPH004 */
543
!     sc.workers = 0;						/* JPH004 */
544
!     HTLog_error("Falling back to non-preforking mode\n");	/* JPH004 */
545
!     return 1;							/* JPH004 */
546
! }								/* JPH004 */
547
! #endif								/* JPH004 */
548
  
549
  /*                                                    standalone_server_loop()
550
   *      New server_loop() for Unixes in standalone mode
551
***************
552
*** 2300,2305 ****
553
--- 2644,2652 ----
554
          /*
555
           * Use new server loop, old one is a mess.
556
           */
557
+         if ((role == master) && (sc.workers)) {			/* JPH004 */
558
+             preforking_server_loop();				/* JPH004 */
559
+         }							/* JPH004 */
560
          if (role == master) standalone_server_loop();
561
  #endif
562
  
563
***************
564
*** 2674,2685 ****
565
  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
566
      pgrp = setsid();
567
  #else
568
!     pgrp = setpgrp(0, getpid());
569
  
570
      if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
571
          ioctl(fd, TIOCNOTTY, (char*)NULL);      /* Lose controlling tty */
572
          close(fd);
573
      }
574
  #endif
575
      if (pgrp == -1)
576
          HTLog_error("Can't change process group");
577
--- 3021,3038 ----
578
  #if defined(__svr4__) || defined(_POSIX_SOURCE) || defined(__hpux)
579
      pgrp = setsid();
580
  #else
581
!     pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0);	/* JPH002 */
582
  
583
      if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
584
          ioctl(fd, TIOCNOTTY, (char*)NULL);      /* Lose controlling tty */
585
          close(fd);
586
      }
587
+ 
588
+     /* TIOCNOTTY can reset pgrp to zero! */			/* JPH002 */
589
+ 								/* JPH002 */
590
+     if (getpgrp(0) == 0) {					/* JPH002 */
591
+         pgrp = (setpgrp(0, getpid()) == -1) ? -1 : getpgrp(0);	/* JPH002 */
592
+     }								/* JPH002 */
593
  #endif
594
      if (pgrp == -1)
595
          HTLog_error("Can't change process group");
596
*** 1.1	1995/07/11 17:09:08
597
--- Library/Implementation/HTDaemon.h	1995/07/13 02:57:04
598
***************
599
*** 14,19 ****
600
--- 14,20 ----
601
  extern BOOL ignore_sigpipes;	/* Should we catch and ignore SIGPIPE	*/
602
  extern BOOL sigpipe_caught;	/* If so, have we caught a SIGPIPE	*/
603
  
604
+ extern char *		HTVirtualHost;				/* JPH003 */
605
  extern char *		HTClientProtocol;
606
  extern int		HTServerPort;
607
  
608
***************
609
*** 53,58 ****
610
--- 54,71 ----
611
  extern BOOL		trace_all;
612
  #define VTRACE		if(trace_all)fprintf
613
  
614
+ #ifdef FORKING							/* JPH004 */
615
+ #include <sys/un.h>						/* JPH004 */
616
+ 								/* JPH004 */
617
+ typedef struct _HTWorkerStruct {				/* JPH004 */
618
+     struct sockaddr_un	addr;					/* JPH004 */
619
+     int			addrlen;				/* JPH004 */
620
+     int			index;	/* into worker table */		/* JPH004 */
621
+     int			slot;	/* into roster table */		/* JPH004 */
622
+     int			pid;					/* JPH004 */
623
+     int			fd;	/* valid in workers only */	/* JPH004 */
624
+ } HTWorkerStruct;						/* JPH004 */
625
+ #endif								/* JPH004 */
626
  
627
  typedef struct _HTInStruct {
628
      BOOL	no_cache_pragma;
629
*** 1.1	1995/07/11 17:09:11
630
--- Library/Implementation/HTLog.c	1995/07/14 00:08:39
631
***************
632
*** 62,68 ****
633
  
634
      /* If we have a date format to paste on the file names. Else use default */
635
      time(&t);
636
!     gmt = gmtime(&t);
637
      result = malloc(strlen(filename)+DATE_EXT_LEN+2);
638
      if (sc.log_file_date_ext) {
639
  
640
--- 62,68 ----
641
  
642
      /* If we have a date format to paste on the file names. Else use default */
643
      time(&t);
644
!     gmt = sc.use_gmt ? gmtime(&t) : localtime(&t);		/* JPH005 */
645
      result = malloc(strlen(filename)+DATE_EXT_LEN+2);
646
      if (sc.log_file_date_ext) {
647
  
648
***************
649
*** 300,305 ****
650
--- 300,312 ----
651
  	}
652
  	else strcpy(buf, "- -");
653
  
654
+ 	if (sc.virtualize) {					/* JPH003 */
655
+ 	    fprintf(log, "%s %s %s %s [%s] \"%s\" %s\n",	/* JPH003 */
656
+ 		    HTVirtualHost,				/* JPH003 */
657
+ 		    n_pick(HTClientHostName,HTClientHost),	/* JPH003 */
658
+ 		    r_ident, authuser, log_time(),		/* JPH003 */
659
+ 		    n_noth(HTReqLine), buf);			/* JPH003 */
660
+ 	} else							/* JPH003 */
661
  	fprintf(log, "%s %s %s [%s] \"%s\" %s\n",
662
  		n_pick(HTClientHostName,HTClientHost),
663
  		r_ident, authuser, log_time(), n_noth(HTReqLine), buf);
664
*** 1.1	1995/07/11 17:09:15
665
--- Library/Implementation/HTScript.c	1995/07/15 01:24:04
666
***************
667
*** 833,838 ****
668
--- 833,839 ----
669
      char ** argv = NULL;
670
      char ** envp = NULL;
671
      BOOL nph_script = NO;
672
+     int fd;							/* JPH006 */
673
  
674
      FREE(msg);		/* From previous call */
675
  
676
***************
677
*** 939,944 ****
678
--- 940,948 ----
679
  	pid = fork();
680
  	if (pid < 0) {	/* fork() failed */
681
  	    char msg[100];
682
+ 
683
+             close(pin[0]),close(pin[1]);			/* JPH006 */
684
+             close(pout[0]),close(pout[1]);			/* JPH006 */
685
  	    sprintf(msg, "Internal error: fork() failed with %s script",
686
  		    (nph_script ? "NPH-" : HTMethod_name(req->method)));
687
  	    return HTLoadError(req, 500, msg);
688
***************
689
*** 954,959 ****
690
--- 958,964 ----
691
  	    ** Standalone server, redirect socket to stdin/stdout.
692
  	    */
693
  	    CTRACE(stderr, "Child....... doing IO redirections\n");
694
+             close(0);						/* JPH006 */
695
  	    if (req->content_length > 0) {	/* Need to give stdin */
696
  		if (pin[0] != 0) {
697
  		    CTRACE(stderr, "Child....... stdin from input pipe\n");
698
***************
699
*** 981,986 ****
700
--- 986,992 ----
701
  		   "Child....... Standalone specific IO redirections done.\n");
702
  	    CTRACE(stderr, "Child....... redirecting stderr to stdout, and then doing execve()\n");
703
  	    dup2(1, 2);	/* Redirect stderr to stdout */
704
+             for (fd = 3; fd < pout[1]; ++fd) close(fd);		/* JPH006 */
705
  	    if (-1 == execve(HTReqScript, argv, envp)) {
706
  		CTRACE(stderr, "ERROR....... execve() failed\n");
707
  		HTLoadError(req, 500, "Internal error: execve() failed");
(-)w3c-httpd/patches/RefererLog.patch (+240 lines)
Line 0 Link Here
1
*** /dev/null	Tue Feb  6 11:05:04 1996
2
--- WWW/README-REFERER_LOG	Tue Feb  6 13:24:53 1996
3
***************
4
*** 0 ****
5
--- 1,30 ----
6
+ Patch to add RefererLog to the configuration.
7
+ 
8
+ Apply the patch, modify WWW/All/<model>/Makefile.include (for your model
9
+ system) and add '-DREFERER_LOG' to CFLAGS.
10
+ 
11
+ Add the following line to your httpd.conf:
12
+ 
13
+ RefererLog	/www/logs/referer
14
+ 
15
+ The syntax is identical to that for AccessLog, in fact: for each entry
16
+ in the AccessLog there will be an entry in the RefererLog.
17
+ 
18
+ The format of the RefererLog is slightly different from the NCSA one
19
+ <URL:http://hoohoo.ncsa.uiuc.edu/docs/setup/httpd/RefererLog.html>:
20
+ 
21
+ host.some.where.org [05/Feb/1996:12:38:36 -0100] http://lycos-tmp1.psc.edu/cgi-bin/pursuit?query=something -> /
22
+ host.some.where.org [05/Feb/1996:12:38:55 -0100] http://www.my.domain/ -> /info/
23
+ some.one.else [05/Feb/1996:12:40:02 -0100] - -> /HotNews/
24
+ 
25
+ So:
26
+ 
27
+ referring-host [timestamp] referring-URL -> document
28
+ 
29
+ The referring-host and timestamp will be in the same format as in the
30
+ AccessLog.  If there is no referring-URL, a minus sign will be printed.
31
+ Anything matching the NoLog directive (so it isn't logged in the
32
+ AccessLog) is not logged in the RefererLog.
33
+ 
34
+ --
35
+ -- 19960205, Gertjan van Oosten, gertjan@West.NL, West Consulting bv
36
*** WWW/Daemon/Implementation/HTConfig.h.orig	Sun Sep 25 14:55:28 1994
37
--- WWW/Daemon/Implementation/HTConfig.h	Mon Feb  5 15:01:23 1996
38
***************
39
*** 76,81 ****
40
--- 76,84 ----
41
      BOOL	always_welcome;		/* Redirect directory names to	*/
42
  					/* welcome page on that dir.	*/
43
      char *	access_log_name;	/* Access log file name		*/
44
+ #ifdef REFERER_LOG
45
+     char *	referer_log_name;	/* Referer log file name	*/
46
+ #endif
47
      char *	proxy_log_name;		/* Proxy access log file name	*/
48
      char *	cache_log_name;		/* Cache access log file name	*/
49
      char *	error_log_name;		/* Error log file name		*/
50
*** WWW/Daemon/Implementation/HTConfig.c.orig	Mon Sep 26 15:22:52 1994
51
--- WWW/Daemon/Implementation/HTConfig.c	Mon Feb  5 15:00:35 1996
52
***************
53
*** 1675,1680 ****
54
--- 1675,1686 ----
55
  	    sc.access_log_name = tilde_to_home(vec[1]);
56
  	    CTRACE(stderr, "AccessLog... %s\n", sc.access_log_name);
57
  
58
+ #ifdef REFERER_LOG
59
+ 	} else if (!strncmp(vec[0],"refererlog",10)) {
60
+ 	    sc.referer_log_name = tilde_to_home(vec[1]);
61
+ 	    CTRACE(stderr, "RefererLog... %s\n", sc.referer_log_name);
62
+ 
63
+ #endif
64
  	} else if (!strncmp(vec[0],"cacheaccesslog",12)) {
65
  	    sc.cache_log_name = tilde_to_home(vec[1]);
66
  	    CTRACE(stderr, "Cache log... %s\n", sc.cache_log_name);
67
*** WWW/Daemon/Implementation/HTLog.h.orig	Sun Sep 25 14:55:29 1994
68
--- WWW/Daemon/Implementation/HTLog.h	Mon Feb  5 14:58:06 1996
69
***************
70
*** 8,13 ****
71
--- 8,16 ----
72
  PUBLIC BOOL HTLog_openAll NOPARAMS;
73
  PUBLIC void HTLog_closeAll NOPARAMS;
74
  PUBLIC void HTLog_access PARAMS((HTRequest *	req));
75
+ #ifdef REFERER_LOG
76
+ PUBLIC void HTLog_referer PARAMS((HTRequest *	req));
77
+ #endif
78
  PUBLIC void HTLog_error PARAMS((CONST char * msg));
79
  PUBLIC void HTLog_error2 PARAMS((CONST char *	msg,
80
  				 CONST char *	param));
81
*** WWW/Daemon/Implementation/HTLog.c.orig	Sun Sep 25 19:53:37 1994
82
--- WWW/Daemon/Implementation/HTLog.c	Mon Feb  5 16:02:10 1996
83
***************
84
*** 40,45 ****
85
--- 40,48 ----
86
  PRIVATE FILE *	proxy_log	= NULL;		
87
  PRIVATE FILE *	cache_log	= NULL;
88
  PRIVATE FILE *	error_log	= NULL;
89
+ #ifdef REFERER_LOG
90
+ PRIVATE FILE *	referer_log	= NULL;
91
+ #endif
92
  
93
  extern char * HTClientHost;
94
  extern char * HTClientHostName;
95
***************
96
*** 125,130 ****
97
--- 128,136 ----
98
  static access_log_times = 0;
99
  static error_log_times = 0;
100
  static cache_log_times = 0;
101
+ #ifdef REFERER_LOG
102
+ static referer_log_times = 0;
103
+ #endif
104
  
105
     /* flush C rtl buffers */
106
     fflush(fptr);
107
***************
108
*** 165,170 ****
109
--- 171,189 ----
110
  				cache_log, "shr=get","shr=put", "shr=upd");
111
        }
112
     }
113
+ #ifdef REFERER_LOG
114
+    else
115
+    if (fptr == referer_log)
116
+    {
117
+       referer_log_times++;
118
+       if (referer_log_times > TIMES_TO_REOPEN)
119
+       {
120
+          referer_log_times = 0;
121
+          referer_log = freopen(time_escapes(sc.referer_log_name), "a+", 
122
+ 				referer_log, "shr=get","shr=put", "shr=upd");
123
+       }
124
+    }
125
+ #endif
126
  
127
     return(1);
128
  }
129
***************
130
*** 316,324 ****
131
--- 335,378 ----
132
      }
133
  
134
      HTFlush(log);
135
+ 
136
+ #ifdef REFERER_LOG
137
+     if (log == access_log)
138
+ 	HTLog_referer(req);
139
+ #endif
140
  }
141
  
142
  
143
+ #ifdef REFERER_LOG
144
+ PUBLIC void HTLog_referer ARGS1(HTRequest *, req)
145
+ {
146
+     time_t t;
147
+     struct tm * gorl;
148
+     FILE * log = referer_log;
149
+ 
150
+     if (!log) return;
151
+ 
152
+     if (sc.new_logfile_format) {
153
+ 	fprintf(log, "%s [%s] %s -> %s\n",
154
+ 		n_pick(HTClientHostName,HTClientHost),
155
+ 		log_time(), n_hyph(HTReferer), n_noth(HTReqArg));
156
+     }
157
+     else {	/* Still old format */
158
+ 	time(&t);
159
+ 	if (sc.use_gmt)
160
+ 	    gorl = gmtime(&t);
161
+ 	else
162
+ 	    gorl = localtime(&t);
163
+ 
164
+ 	fprintf(log, "%24.24s %s %s -> %s\n",
165
+ 		asctime(gorl), HTClientHost, n_hyph(HTReferer), n_noth(HTReqArg));
166
+     }
167
+ 
168
+     HTFlush(log);
169
+ }
170
+ #endif /* REFERER_LOG */
171
+ 
172
+ 
173
  PRIVATE char * status_name NOARGS
174
  {
175
      switch (HTReason) {
176
***************
177
*** 431,436 ****
178
--- 485,496 ----
179
  	fclose(cache_log);
180
  	cache_log = NULL;
181
      }
182
+ #ifdef REFERER_LOG
183
+     if (referer_log) {
184
+ 	fclose(referer_log);
185
+ 	referer_log = NULL;
186
+     }
187
+ #endif
188
  }
189
  
190
  
191
***************
192
*** 467,472 ****
193
--- 527,535 ----
194
      char * aln = NULL;
195
      char * pln = NULL;
196
      char * cln = NULL;
197
+ #ifdef REFERER_LOG
198
+     char * rln = NULL;
199
+ #endif
200
      char * eln = NULL;
201
  
202
      /*
203
***************
204
*** 517,522 ****
205
--- 580,602 ----
206
  	}
207
      }
208
  
209
+ #ifdef REFERER_LOG
210
+     /*
211
+      * Open referer log file
212
+      */
213
+     if (sc.referer_log_name) {
214
+ 	rln = time_escapes(sc.referer_log_name);
215
+ 	referer_log = do_open(rln);
216
+ 	if (referer_log) {
217
+ 	    CTRACE(stderr, "Referer log... \"%s\" opened\n", rln);
218
+ 	}
219
+ 	else {
220
+ 	    HTLog_error2("Can't open referer log:", rln);
221
+ 	    flag = NO;
222
+ 	}
223
+     }
224
+ #endif
225
+ 
226
      /*
227
       * Open error log and flush the current error queue to it
228
       */
229
***************
230
*** 549,554 ****
231
--- 629,637 ----
232
      FREE(pln);
233
      FREE(eln);
234
      FREE(cln);
235
+ #ifdef REFERER_LOG
236
+     FREE(rln);
237
+ #endif
238
  
239
      return flag;
240
  }
(-)w3c-httpd/patches/SSL.patch (+532 lines)
Line 0 Link Here
1
============================================================================
2
README:
3
============================================================================
4
5
OVERVIEW
6
7
	This SSL tunneling patch for CERN httpd adds support for the
8
	CONNECT method used by SSL enhanced clients to open a secure
9
	tunnel through the proxy.
10
11
THEORY
12
13
	The CONNECT method takes
14
15
		hostname:port
16
17
	as its argument, and the request is in the form of the
18
	HTTP/1.0 request (that is, the string "HTTP/1.0" and the
19
	request headers must follow the request).  Example:
20
21
		CONNECT home1.netscape.com:443 HTTP/1.0<crlf>
22
		<crlf>
23
24
	The response will be either a normal HTTP/1.0 error response
25
	(in case the host is unreachable for one reason or another),
26
	or in case of success:
27
28
		HTTP/1.0 200 Connection established<crlf>
29
		<crlf>
30
31
	after which the connection is open, and the client may start
32
	the SSL handshake.
33
34
	This is a superior approach because it allows the HTTP request
35
	headers to be passed, making it possible to do authentication
36
	on the proxy, and allows any other future extension.
37
38
CONFIGURATION
39
40
	Because the configuration of CERN httpd is based on URL
41
	patterns, for ease of configuration, the hostname:port
42
	argument in automatically transformed into an internal
43
	representation:
44
45
		connect://hostname:port
46
47
	connect:// URLs do not exist in real life -- this is just a
48
	notion in the configuration file to make life easier!!
49
50
ENABLING
51
52
	SSL tunneling is disabled by default.  To enable it for HTTPS
53
	(uses the port 443), add the following line in the
54
	configuration file:
55
56
		Pass connect://*:443
57
58
	To enable secure news (SNEWS, uses port 563) tunneling, add
59
	line:
60
61
		Pass connect://*:563
62
63
	DO NOT use trailing slashes.  DO NOT allow all connect://
64
	requests, the following is unsafe:
65
66
		Pass connect://*
67
68
PROTECTION
69
70
	IP address protection should always be used in connection with
71
	SSL tunneling.  To create a protection template P which allows
72
	access only for hosts with IP addresses 198.93.*.* and
73
	198.95.*.*, use the template:
74
75
		Protection P {
76
		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
77
		}
78
79
	Note that this only declares a template; to actually apply the
80
	protection use the Protect rule, AFTER the Protection
81
	declaration, but BEFORE the Pass rule:
82
83
		Protect connect://* P
84
85
	Or, to collect them all together:
86
87
		Protection P {
88
		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
89
		}
90
		Protect	connect://* P
91
		Pass connect://*:443
92
		Pass connect://*:563
93
94
	The Protection binding to name P may be left out in case it's
95
	only used once, and the protection configuration may be
96
	inlined in place of the protection name in Protect rule:
97
98
		Protect connect://* {
99
		    CONNECT-Mask @(198.93.*.*, 198.95.*.*)
100
		}
101
		Pass connect://*:443
102
		Pass connect://*:563
103
104
	For a better insight of the CERN httpd's configuration system,
105
	please refer to the online manual:
106
107
		http://www.w3.org/httpd/
108
109
PROXY AUTHENTICATION
110
111
	This patch does not enable proxy authentication.  Proxy
112
	authentication is not supported by the CERN proxy.  Proxy
113
	authentication uses the status code 407, and headers
114
	Proxy-Authenticate and Proxy-Authorization.
115
116
	You MUST NOT try to use the Protect directive to turn on
117
	normal user authentication on (the one that uses the 401
118
	status code, and WWW-Authenticate and Authorization headers).
119
	That is an incorrect way to do authentication for the proxy,
120
	and causes compatibility and security problems.
121
122
CHAINING PROXIES
123
124
	This patch does not enable chaining proxies to do SSL
125
	tunneling.  More specifically, the CERN proxy with this patch
126
	IS able to act as the OUTMOST proxy in the chain, but it
127
	doesn't work if it is the inner proxy that has to speak to
128
	another, outer proxy to establish a secure connection through
129
	that.  Therefore, a combination such as inner Netscape Proxy
130
	and outer CERN httpd would work, but not vice versa.
131
132
THE NETSCAPE PROXY SERVER
133
134
	The Netscape Proxy Server is a commercially supported proxy
135
	server available from Netscape Communications Corporation.  In
136
	addition to it's unique, more efficient architecture, it
137
	natively supports proxy authentication, proxy chaining, SSL
138
	tunneling and HTTPS proxying, enabling also clients without
139
	native SSL support to use HTTPS.
140
141
AUTHOR
142
	Ari Luotonen, Netscape Communications Corporation, 1995
143
	<ari@netscape.com>
144
145
DISCLAIMER
146
147
	I do not have any official connection to the CERN httpd
148
	development anymore.  I have left the CERN WWW project in
149
	summer '94.  I do not provide any support for this software or
150
	this patch.  For general CERN httpd support, please contact:
151
152
		httpd@w3.org
153
154
	THIS PATCH IS PROVIDED IN GOOD FAITH, AS IS.  I AND NETSCAPE
155
	MAKE NO CLAIMS TO ITS SUITABILITY FOR ANY PARTICULAR PURPOSE,
156
	AND I AND NETSCAPE PROVIDE ABSOLUTELY NO WARRANTY OF ANY KIND
157
	WITH RESPECT TO THIS PATCH OR THIS SOFTWARE.  THE ENTIRE RISK
158
	AS TO THE QUALITY AND PERFORMANCE OF THIS SOFTWARE/PATCH IS
159
	WITH THE USER.  IN NO EVENT WILL I OR NETSCAPE BE LIABLE TO
160
	ANYONE FOR ANY DAMAGES ARISING OUT THE USE OF THIS
161
	SOFTWARE/PATCH, INCLUDING, WITHOUT LIMITATION, DAMAGES
162
	RESULTING FROM LOST DATA OR LOST PROFITS, OR FOR ANY SPECIAL,
163
	INCIDENTAL OR CONSEQUENTIAL DAMAGES.
164
165
166
============================================================================
167
PATCH TO WWW COMMON LIBRARY 2.17 AND CERN HTTPD 3.0:
168
============================================================================
169
170
*** WWW/Library/Implementation/HTAccess.c.orig	Thu Sep 29 04:53:28 1994
171
--- WWW/Library/Implementation/HTAccess.c	Tue May  9 13:16:50 1995
172
***************
173
*** 146,151 ****
174
--- 146,152 ----
175
      "SHOWMETHOD",
176
      "LINK",
177
      "UNLINK",
178
+     "CONNECT",
179
      NULL
180
  };
181
  
182
*** WWW/Library/Implementation/HTAccess.h.orig	Sun Sep 25 07:15:14 1994
183
--- WWW/Library/Implementation/HTAccess.h	Tue May  9 13:15:47 1995
184
***************
185
*** 60,65 ****
186
--- 60,66 ----
187
          METHOD_SHOWMETHOD,
188
          METHOD_LINK,
189
          METHOD_UNLINK,
190
+ 	METHOD_CONNECT,
191
          MAX_METHODS
192
  } HTMethod;
193
  /*
194
*** WWW/Daemon/Implementation/HTAAProt.h.orig	Sun Sep 25 06:55:47 1994
195
--- WWW/Daemon/Implementation/HTAAProt.h	Mon May 15 21:05:40 1995
196
***************
197
*** 52,57 ****
198
--- 52,58 ----
199
      GroupDef *    put_mask;     /*  - " - (PUT)                         */
200
      GroupDef *    post_mask;    /*  - " - (POST)                        */
201
      GroupDef *    delete_mask;  /*  - " - (DELETE)                      */
202
+     GroupDef *    connect_mask;	/*  - " - (CONNECT)			*/
203
      GroupDef *    gen_mask;     /* General mask (used when needed but   */
204
                                  /* other masks not set).                */
205
      HTList *      valid_schemes;/* Valid authentication schemes         */
206
*** WWW/Daemon/Implementation/HTAAProt.c.orig	Sun Sep 25 11:53:03 1994
207
--- WWW/Daemon/Implementation/HTAAProt.c	Mon May 15 21:18:05 1995
208
***************
209
*** 356,361 ****
210
--- 356,373 ----
211
  		    }
212
  		} /* if "Post-Mask" */
213
  
214
+ 		else if (0==strncasecomp(fieldname, "connect", 7)) {
215
+ 		    prot->connect_mask = HTAA_parseGroupDef(fp);
216
+ 		    lex_item=LEX_REC_SEP; /*groupdef parser read this already*/
217
+ 		    if (TRACE) {
218
+ 			if (prot->connect_mask) {
219
+ 			    fprintf(stderr, "CONNECT-Mask\n");
220
+ 			    HTAA_printGroupDef(prot->connect_mask);
221
+ 			}
222
+ 			else fprintf(stderr,"SYNTAX ERROR parsing CONNECT-Mask\n");
223
+ 		    }
224
+ 		} /* if "Connect-Mask" */
225
+ 
226
  		else if (0==strncasecomp(fieldname, "delete", 6)) {
227
  		    prot->delete_mask = HTAA_parseGroupDef(fp);
228
  		    lex_item=LEX_REC_SEP; /*groupdef parser read this already*/
229
*** WWW/Daemon/Implementation/HTAAServ.c.orig	Sun Sep 25 06:52:53 1994
230
--- WWW/Daemon/Implementation/HTAAServ.c	Mon May 15 21:06:18 1995
231
***************
232
*** 208,213 ****
233
--- 208,215 ----
234
  	    mask = prot->post_mask;
235
  	else if (!strcmp(method_name, "DELETE"))
236
  	    mask = prot->delete_mask;
237
+ 	else if (!strcmp(method_name, "CONNECT"))
238
+ 	    mask = prot->connect_mask;
239
  	if (!mask)
240
  	    mask = prot->gen_mask;
241
      }
242
*** WWW/Daemon/Implementation/HTRequest.c.orig	Fri Aug 12 03:36:29 1994
243
--- WWW/Daemon/Implementation/HTRequest.c	Mon May 15 21:32:44 1995
244
***************
245
*** 1006,1011 ****
246
--- 1006,1028 ----
247
      }
248
  
249
      /*
250
+      * SSL tunneling -- make host:port appear as connect://host:port
251
+      * to make it work better with the configuration system.
252
+      * Ari Luotonen <ari@netscape.com> May 1995
253
+      */
254
+     if (req->method == METHOD_CONNECT && HTReqArg) {
255
+ 	char *tmp = HTReqArg;
256
+ 	HTReqArg = NULL;
257
+ 	StrAllocCopy(HTReqArg, "connect://");
258
+ 	StrAllocCat(HTReqArg, tmp);
259
+ 	free(tmp);
260
+ 	if ((tmp = strchr(HTReqArg + 10, ':'))) {
261
+ 	    for (tmp++; *tmp && isdigit(*tmp); tmp++);
262
+ 	    *tmp = '\0';
263
+ 	}
264
+     }
265
+ 
266
+     /*
267
      ** Check that the third argument actually is a valid
268
      ** client protocol specifier (if it is not we might wait
269
      ** for an eternity for the rest of an HTTP1 request when it
270
*** WWW/Daemon/Implementation/HTDaemon.c.orig	Mon Sep 26 07:23:00 1994
271
--- WWW/Daemon/Implementation/HTDaemon.c	Mon Jun 12 15:58:58 1995
272
***************
273
*** 65,70 ****
274
--- 65,71 ----
275
  **			defined via "ServerRoot" in the configuration file.
276
  **			Commented out dead extern declarations.
277
  **	 8 Jul 94  FM	Insulate free() from _free structure element.
278
+ **	   May 95  AL   SSL tunneling support
279
  */
280
  
281
  /* (c) CERN WorldWideWeb project 1990-1992. See Copyright.html for details */
282
***************
283
*** 162,167 ****
284
--- 163,173 ----
285
  #include <sys/param.h>
286
  #include <errno.h>
287
  
288
+ #if !defined(__osf__) && !defined(AIX) && !defined(_HPUX_SOURCE) && \
289
+     !defined(BSDI) && !defined(__linux)
290
+ #include <sys/filio.h>
291
+ #endif
292
+ 
293
  #ifndef SIGCLD
294
  #ifdef SIGCHLD
295
  #define SIGCLD SIGCHLD
296
***************
297
*** 376,381 ****
298
--- 382,602 ----
299
  
300
  
301
  
302
+ /*
303
+  * SSL tunneling support by Ari Luotonen <ari@netscape.com>, May 1995
304
+  */
305
+ 
306
+ 
307
+ #define SSL_PROXY_BUFSIZE 4096
308
+ 
309
+ 
310
+ int shove_buffer ARGS4(int,	sd,
311
+ 		       char *,	b,
312
+ 		       int *,	i,
313
+ 		       int *,	c)
314
+ {
315
+     int n = write(sd, &b[*i], *c);
316
+ 
317
+     if (n > 0)
318
+       {
319
+ 	  *i += n;
320
+ 	  *c -= n;
321
+       }
322
+     else if (n == -1 && (errno == EWOULDBLOCK || errno == EINTR))
323
+       {
324
+ 	  n = 0;
325
+       }
326
+ 
327
+     return n;
328
+ }
329
+ 
330
+ int drag_buffer ARGS4(int,	sd,
331
+ 		      char *,	b,
332
+ 		      int *,	i,
333
+ 		      int *,	c)
334
+ {
335
+     int n = read(sd, b, SSL_PROXY_BUFSIZE);
336
+ 
337
+     *i = *c = 0;
338
+ 
339
+     if (n > 0)
340
+       {
341
+ 	  *c = n;
342
+       }
343
+     else if (n == -1 && errno != EWOULDBLOCK && errno != EINTR)
344
+       {
345
+ 	  return 0;
346
+       }
347
+     return n;
348
+ }
349
+ 
350
+ 
351
+ int ssl_proxy_pump ARGS3(int,		sd1,
352
+ 			 int,		sd2,
353
+ 			 char *,	initial)
354
+ {
355
+     char b1[SSL_PROXY_BUFSIZE];
356
+     char b2[SSL_PROXY_BUFSIZE];
357
+     int i1=0, i2=0;		/* Buffer start index */
358
+     int c1=0, c2=0;		/* Buffer data counter */
359
+     int r1=0, r2=0;		/* Socket read ready */
360
+     int w1=0, w2=0;		/* Socket write ready */
361
+     int closed1=0, closed2=0;	/* Socket close */
362
+     int n_fds = ((sd1 > sd2) ? sd1 : sd2) + 1;
363
+     fd_set rd_fds, wr_fds;
364
+     int status;
365
+ 
366
+     memset(&rd_fds, 0, sizeof(rd_fds));
367
+     memset(&wr_fds, 0, sizeof(wr_fds));
368
+ 
369
+     if (initial && *initial) {
370
+ 	strcpy(b1, initial);
371
+ 	c1 = strlen(initial);
372
+     }
373
+ 
374
+     while (1) {
375
+ 	FD_SET(sd1, &rd_fds);
376
+ 	FD_SET(sd2, &rd_fds);
377
+ 	FD_SET(sd1, &wr_fds);
378
+ 	FD_SET(sd2, &wr_fds);
379
+ 
380
+ 	if (!(status = select(n_fds, &rd_fds, &wr_fds, NULL, NULL)))
381
+ 	  {
382
+ 	      break;
383
+ 	  }
384
+ 	else if (status == -1)
385
+ 	  {
386
+ 	      if (errno == EINTR)
387
+ 		  continue;
388
+ 	      else
389
+ 		  break;
390
+ 	  }
391
+ 
392
+ 	r1 = FD_ISSET(sd1, &rd_fds);
393
+ 	r2 = FD_ISSET(sd2, &rd_fds);
394
+ 	w1 = FD_ISSET(sd1, &wr_fds);
395
+ 	w2 = FD_ISSET(sd2, &wr_fds);
396
+ 
397
+ 	if (w1 && c1 > 0)
398
+ 	  {
399
+ 	      if (shove_buffer(sd1, b1, &i1, &c1) == -1)
400
+ 		  closed1 = 1;
401
+ 	  }
402
+ 	if (w2 && c2 > 0)
403
+ 	  {
404
+ 	      if (shove_buffer(sd2, b2, &i2, &c2) == -1)
405
+ 		    closed2 = 1;
406
+ 	  }
407
+ 	if (r1 && !c2)
408
+ 	  {
409
+ 	      if (!drag_buffer(sd1, b2, &i2, &c2))
410
+ 		  closed1 = 1;
411
+ 	  }
412
+ 	if (r2 && !c1)
413
+ 	  {
414
+ 	      if (!drag_buffer(sd2, b1, &i1, &c1))
415
+ 		  closed2 = 1;
416
+ 	  }
417
+ 
418
+ 	if (closed1 || closed2)
419
+ 	  {
420
+ 	      break;
421
+ 	  }
422
+     }
423
+ 
424
+     NETCLOSE(sd1);
425
+     NETCLOSE(sd2);
426
+ 
427
+     return 1;
428
+ }
429
+ 
430
+ 
431
+ BOOL ssl_proxy_get_addr ARGS3(char *,	arg,
432
+ 			      char **,	host,
433
+ 			      int *,	port)
434
+ {
435
+     char *p;
436
+ 
437
+     if (arg && host && port && !strncmp(arg, "connect://", 10)) {
438
+ 
439
+ 	*host = NULL;
440
+ 	StrAllocCopy(*host, arg + 10);
441
+ 
442
+ 	if ((p = strchr(*host, ':'))) {
443
+ 	    *p++ = '\0';
444
+ 	    if ((*port = atoi(p)) > 0)
445
+ 		return YES;
446
+ 	}
447
+     }
448
+     return NO;
449
+ }
450
+ 
451
+ 
452
+ int ssl_proxy_connect ARGS3(HTRequest *,	req,
453
+ 			    char *,		host,
454
+ 			    int,		port)
455
+ {
456
+     struct sockaddr_in sa;
457
+     struct hostent *hp;
458
+     int sd, status, one=1;
459
+ 
460
+     memset(&sa, 0, sizeof(sa));
461
+     sa.sin_family = AF_INET;
462
+     sa.sin_port = htons(port);
463
+ 
464
+     if (isdigit(*host))
465
+ 	sa.sin_addr.s_addr = inet_addr(host);
466
+     else if ((hp = gethostbyname(host)))
467
+ 	memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
468
+     else {
469
+ 	HTLoadError(req, 500, "Unable to locate host");
470
+ 	return -1;
471
+     }
472
+ 
473
+     if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
474
+ 	HTLoadError(req, 500, "Can't create socket");
475
+ 	return -1;
476
+     }
477
+ 
478
+     if ((status = connect(sd, (struct sockaddr *)&sa, sizeof(sa))) == -1) {
479
+ 	HTLoadError(req, 500, "Can't connect to host");
480
+ 	return -1;
481
+     }
482
+ 
483
+     if ((status = ioctl(sd, FIONBIO, &one)) == -1) {
484
+ 	HTLoadError(req, 500, "Can't make socket non-blocking");
485
+ 	return -1;
486
+     }
487
+ 
488
+     return sd;
489
+ }
490
+ 
491
+ 
492
+ 
493
+ BOOL ssl_proxy_request ARGS2(char *, arg, HTRequest *, req)
494
+ {
495
+     char *host = NULL;
496
+     int port = 0;
497
+     int sd, one=1;
498
+ 
499
+     CTRACE(stderr, "Handling CONNECT %s\n", arg);
500
+ 
501
+     if (!ssl_proxy_get_addr(arg, &host, &port)) {
502
+ 	HTLoadError(req, 400, "Bad CONNECT request address");
503
+ 	return NO;
504
+     }
505
+ 
506
+     if ((sd = ssl_proxy_connect(req, host, port)) < 0)
507
+ 	return NO;
508
+ 
509
+     if (ioctl(HTSoc, FIONBIO, &one) < -1) {
510
+ 	HTLoadError(req, 500, "Can't make client socket non-blocking");
511
+ 	return NO;
512
+     }
513
+ 
514
+     ssl_proxy_pump(HTSoc, sd, "HTTP/1.0 200 Connection established\r\n\r\n");
515
+     return YES;
516
+ }
517
  
518
  
519
  #if defined(Mips)
520
***************
521
*** 1832,1837 ****
522
--- 2053,2062 ----
523
              }
524
              FREE(cfn);
525
          }
526
+ 	else if (req->method==METHOD_CONNECT) {
527
+ 	    /* SSL tunneling by Ari Luotonen <ari@netscape.com>, May 1995 */
528
+ 	    ssl_proxy_request(HTReqArg, req);
529
+ 	}
530
          else {
531
              /* Normal retrieve with no caching */
532
              CTRACE(stderr, "No caching.. %s\n",

Return to bug 6935