##                      _             _ 
##  _ __ ___   ___   __| |    ___ ___| |  
## | '_ ` _ \ / _ \ / _` |   / __/ __| |  
## | | | | | | (_) | (_| |   \__ \__ \ | mod_ssl - Apache Interface to SSLeay  
## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
##                      |_____|         
## ____________________________________________________________________________
##
## apache.patch -- Annotated Apache SSL Patches
## Copyright (c) 1998 Ralf S. Engelschall, All Rights Reserved. 
## Created on: 08-Aug-1998
##
## This file assembles all changes to existing Apache source files between the
## original Apache and the SSL-patched variant. It can be automatically applied
## to a vanilla Apache source tree with the 'patch' tool to upgrade those files
## to be SSL-aware. Each patch snippet is annotated with a short description.
##

#  Now first we have to patch APACI's configuration script to make sure
#  mod_ssl is not implicitly configured as a DSO (which doesn't work) on
#  --enable-shared options. Additionally a flag is passed to Makefile.tmpl
#  which indicated whether mod_ssl is activated or not and support for the
#  SSL_BASE variable is added. Finally we also provide adjustments of
#  the HTTPS port (443) similar to the HTTP port (80).

Index: configure
===================================================================
*** configure	1998/07/21 18:46:16	1.1.1.2
--- configure	1998/08/14 21:12:28	1.5
***************
*** 173,178 ****
--- 173,181 ----
  suexec_gidmin=100
  suexec_safepath="/usr/local/bin:/usr/bin:/bin"
  
+ #   ssl defaults
+ ssl=0
+ 
  #   with support tools
  support=1
  
***************
*** 254,260 ****
  echo "##" >>$configstatus
  echo "" >>$configstatus
  for var in CC OPTIM CFLAGS CFLAGS_SHLIB LDFLAGS LD_SHLIB LDFLAGS_SHLIB \
!            LDFLAGS_SHLIB_EXPORT LIBS INCLUDES RANLIB; do
      eval "val=\"\$$var\""
      if [ ".$val" != . ]; then
          echo "$var=$val" |\
--- 257,263 ----
  echo "##" >>$configstatus
  echo "" >>$configstatus
  for var in CC OPTIM CFLAGS CFLAGS_SHLIB LDFLAGS LD_SHLIB LDFLAGS_SHLIB \
!            LDFLAGS_SHLIB_EXPORT LIBS INCLUDES RANLIB SSL_BASE; do
      eval "val=\"\$$var\""
      if [ ".$val" != . ]; then
          echo "$var=$val" |\
***************
*** 581,586 ****
--- 584,590 ----
                             done
                             IFS="$OIFS"
                             shared_so=no        # because of bootstrapping
+                            shared_ssl=no       # only static per design
                             ;;
                         remain ) 
                             OIFS="$IFS" IFS=':'
***************
*** 593,598 ****
--- 597,603 ----
                             done
                             IFS="$OIFS"
                             shared_so=no
+                            shared_ssl=no       # only static per design
                             ;;
                         * ) 
                             eval "exists=\$module_${apc_optarg}" 
***************
*** 739,744 ****
--- 744,756 ----
  fi
  
  ##
+ ##  SSL support
+ ##
+ if [ ".$module_ssl" = .yes ]; then
+     ssl=1
+ fi
+ 
+ ##
  ##  expand path variables and make sure
  ##  they do not end with a backslash
  ##
***************
*** 786,791 ****
--- 798,804 ----
  ##
  conf_group="#-1"
  conf_port="80"
+ conf_port_ssl="443"
  conf_serveradmin="you@your.address"
  conf_servername="new.host.name"
  if [ ".$confadjust" = .1 ]; then
***************
*** 797,802 ****
--- 810,816 ----
      fi
      if [ ".`id | grep root`" = . ]; then
          conf_port="8080"
+         conf_port_ssl="8443"
      fi
      username="$LOGNAME"
      if [ ".$username" = . ]; then
***************
*** 919,926 ****
--- 933,942 ----
  -e "s%@suexec_uidmin@%$suexec_uidmin%g" \
  -e "s%@suexec_gidmin@%$suexec_gidmin%g" \
  -e "s%@suexec_safepath@%$suexec_safepath%g" \
+ -e "s%@ssl@%$ssl%g" \
  -e "s%@conf_group@%$conf_group%g" \
  -e "s%@conf_port@%$conf_port%g" \
+ -e "s%@conf_port_ssl@%$conf_port_ssl%g" \
  -e "s%@conf_serveradmin@%$conf_serveradmin%g" \
  -e "s%@conf_servername@%$conf_servername%g" \
  -e "s%@build_support@%$build_support%g" \
***************
*** 963,969 ****
  #   generate settings from imported environment variables
  OIFS="$IFS" IFS="$DIFS"
  for var in CC OPTIM CFLAGS CFLAGS_SHLIB LDFLAGS LD_SHLIB LDFLAGS_SHLIB \
!            LDFLAGS_SHLIB_EXPORT LIBS INCLUDES RANLIB DEPS; do
      eval "val=\"\$$var\"";
      if [ ".$val" != . ]; then
          case $var in 
--- 979,985 ----
  #   generate settings from imported environment variables
  OIFS="$IFS" IFS="$DIFS"
  for var in CC OPTIM CFLAGS CFLAGS_SHLIB LDFLAGS LD_SHLIB LDFLAGS_SHLIB \
!            LDFLAGS_SHLIB_EXPORT LIBS INCLUDES RANLIB DEPS SSL_BASE; do
      eval "val=\"\$$var\"";
      if [ ".$val" != . ]; then
          case $var in 

#  Now we incorporate support for the `make certificate' procedure and
#  second support for the `make install' procedure where the configuration
#  now is also adjusted for SSL directives and SSL certs and support programs
#  are now additionally installed.

Index: Makefile.tmpl
===================================================================
*** Makefile.tmpl	1998/07/21 18:46:13	1.1.1.2
--- Makefile.tmpl	1998/08/16 12:28:55	1.13
***************
*** 118,126 ****
--- 118,130 ----
  suexec_gidmin   = @suexec_gidmin@
  suexec_safepath = @suexec_safepath@
  
+ #  SSL (optional)
+ ssl = @ssl@
+ 
  #   some substituted configuration parameters
  conf_group       = @conf_group@
  conf_port        = @conf_port@
+ conf_port_ssl    = @conf_port_ssl@
  conf_serveradmin = @conf_serveradmin@
  conf_servername  = @conf_servername@
  
***************
*** 147,153 ****
  #   build the package
  build:
  	@echo "===> $(SRC)"
! 	@$(MAKE) -f $(MKF) $(MFLAGS) $(MFWD) build-std $(build-support)
  	@touch $(TOP)/$(SRC)/.apaci.build.ok
  	@echo "<=== $(SRC)"
  
--- 151,157 ----
  #   build the package
  build:
  	@echo "===> $(SRC)"
! 	@$(MAKE) -f $(MKF) $(MFLAGS) $(MFWD) build-std $(build-support) build-certificate
  	@touch $(TOP)/$(SRC)/.apaci.build.ok
  	@echo "<=== $(SRC)"
  
***************
*** 174,179 ****
--- 178,200 ----
  	fi; \
  	echo "<=== $(SRC)/support"
  
+ #   SSL certificate generation
+ build-certificate:
+ 	-@if [ ".$(ssl)" = .1 ]; then \
+ 		if [ ".`grep 'HAS TO BE REPLACED' $(TOP)/conf/sslcerts/server.pem`" != . ]; then \
+ 			echo ""; \
+ 			echo "++ You should now generate a SSL server certificate"; \
+ 			echo "++ before installing by running 'make certificate'"; \
+ 			echo "++ and answering the questions manually. Alternatively'"; \
+ 			echo "++ you can now override the $(TOP)/conf/sslcerts/server.pem'"; \
+ 			echo "++ file with your official server certificate.'"; \
+ 			echo ""; \
+ 		fi \
+ 	fi
+ 
+ certificate:
+ 	@cd $(TOP)/$(SRC); $(MAKE) $(MFLAGS) certificate
+ 
  ## ------------------------------------------------------------------
  ##                       Installation Targets
  ## ------------------------------------------------------------------
***************
*** 224,229 ****
--- 245,252 ----
  	$(MKDIR) $(root)$(mandir)/man1
  	$(MKDIR) $(root)$(mandir)/man8
  	$(MKDIR) $(root)$(sysconfdir)
+ 	$(MKDIR) $(root)$(sysconfdir)/sslcerts
+ 	$(MKDIR) $(root)$(sysconfdir)/sslkeys
  	$(MKDIR) $(root)$(datadir)/htdocs
  	$(MKDIR) $(root)$(datadir)/icons
  	$(MKDIR) $(root)$(datadir)/cgi-bin
***************
*** 303,308 ****
--- 326,335 ----
  	$(INSTALL_DATA) $(TOP)/$(SRC)/support/logresolve.8 $(root)$(mandir)/man8/logresolve.8
  	$(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/rotatelogs $(root)$(sbindir)/rotatelogs
  	$(INSTALL_DATA) $(TOP)/$(SRC)/support/rotatelogs.8 $(root)$(mandir)/man8/rotatelogs.8
+ 	-@if [ ".$(ssl)" = .1 ]; then \
+ 	    echo "$(INSTALL_PROGRAM) $(TOP)/$(SRC)/modules/ssl/ssl_gcache $(root)$(sbindir)/ssl_gcache"; \
+ 	    $(INSTALL_PROGRAM) $(TOP)/$(SRC)/modules/ssl/ssl_gcache $(root)$(sbindir)/ssl_gcache; \
+ 	fi
  	@echo "$(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/apxs[*] $(root)$(sbindir)/apxs"; \
  	sed -e 's;^#!/.*;#!$(PERL);' \
  		-e 's;\@prefix\@;$(prefix);' \
***************
*** 374,379 ****
--- 401,411 ----
  		 echo ""; \
  		 cat $(TOP)/conf/$${conf}-dist ) |\
  		 sed -e '/# LoadModule/r $(TOP)/$(SRC)/.apaci.install.conf' \
+ 			-e 's;/usr/local/apache/sbin/ssl_gcache;$(sbindir)/ssl_gcache;' \
+ 			-e 's;logs/ssl_log;$(logfiledir)/ssl_log;' \
+ 			-e 's;@@ServerRoot@@/logs/ssl_misc_log;$(logfiledir)/ssl_misc_log;' \
+ 			-e 's;@@ServerRoot@@/conf/sslcerts;$(sysconfdir)/sslcerts;' \
+ 			-e 's;@@ServerRoot@@/conf/sslkeys;$(sysconfdir)/sslkeys;' \
  			-e 's;@@ServerRoot@@/htdocs;$(datadir)/htdocs;' \
  			-e 's;@@ServerRoot@@/htdocs;$(datadir)/htdocs;' \
  			-e 's;@@ServerRoot@@/icons;$(datadir)/icons;' \
***************
*** 391,398 ****
--- 423,433 ----
  			-e 's;conf/mime.types;$(sysconfdir)/mime.types;' \
  			-e 's;Group #-1;Group $(conf_group);' \
  			-e 's;Port 80;Port $(conf_port);' \
+ 			-e 's;Listen 80;Listen $(conf_port);' \
+ 			-e 's;Listen 443;Listen $(conf_port_ssl);' \
  			-e 's;ServerAdmin you@your.address;ServerAdmin $(conf_serveradmin);' \
  			-e 's;ServerName new.host.name;ServerName $(conf_servername);' \
+ 			-e 's;VirtualHost new.host.name:443;VirtualHost $(conf_servername):$(conf_port_ssl);' \
          	> $(TOP)/$(SRC)/.apaci.install.tmp && \
  		echo "$(INSTALL_DATA) $(TOP)/conf/$${conf}-dist[*] $(root)$(sysconfdir)/$${conf}.default"; \
  		$(INSTALL_DATA) $(TOP)/$(SRC)/.apaci.install.tmp $(root)$(sysconfdir)/$${conf}.default; \
***************
*** 413,418 ****
--- 448,465 ----
  			echo "[PRESERVING EXISTING CONFIG FILE: $(root)$(sysconfdir)/$${conf}]"; \
  		fi; \
  	done
+ 	-@if [ ".$(ssl)" = .1 ]; then \
+ 	    echo "chmod 755 $(root)$(sysconfdir)/sslcerts"; \
+ 	    chmod 755 $(root)$(sysconfdir)/sslcerts; \
+ 	    echo "chmod 700 $(root)$(sysconfdir)/sslkeys"; \
+ 	    chmod 700 $(root)$(sysconfdir)/sslkeys; \
+ 	    echo "$(INSTALL_DATA) $(TOP)/conf/sslcerts/Makefile $(root)$(sysconfdir)/sslcerts/Makefile"; \
+ 	    $(INSTALL) $(TOP)/conf/sslcerts/Makefile $(root)$(sysconfdir)/sslcerts/Makefile; \
+ 	    echo "$(INSTALL_DATA) -m 400 $(TOP)/conf/sslcerts/server.pem $(root)$(sysconfdir)/sslcerts/server.pem"; \
+ 	    $(INSTALL) -m 400 $(TOP)/conf/sslcerts/server.pem $(root)$(sysconfdir)/sslcerts/server.pem; \
+ 	    echo "Updating hash symlinks in $(root)$(sysconfdir)/sslcerts/:"; \
+ 	    (cd $(root)$(sysconfdir)/sslcerts/; $(MAKE)); \
+ 	fi
  	@echo "<=== [config]"
  
  

#  Now we just add the SSL_BASE variable and the AddModule entry for mod_ssl
#  (libssl.a). This way an SSL-aware Apache can still be built with the old
#  Apache 1.2 configuration procedure.

Index: src/Configuration.tmpl
===================================================================
*** src/Configuration.tmpl	1998/07/21 18:46:20	1.1.1.2
--- src/Configuration.tmpl	1998/07/21 19:02:52	1.2
***************
*** 26,31 ****
--- 26,36 ----
  # not enabled).  The AddModule directive can be used to enable such a
  # module.  By default no such modules are defined.
  
+ ################################################################
+ # SSL support:
+ # Set SSL_BASE to the directory of your SSLeay 
+ # source tree or (alternatively) the installation tree.
+ #SSL_BASE=/usr/local/ssl
  
  ################################################################
  # Makefile configuration
***************
*** 378,381 ****
--- 383,392 ----
  ## should be the last (highest priority) module.
  
  AddModule modules/standard/mod_setenvif.o
+ 
+ ## mod_ssl incorporates SSL into Apache.
+ ## It must stay last here to be first in execution to 
+ ## fake basic authorization.
+ 
+ # AddModule modules/ssl/libssl.a
  

#  Now we add the `certificate' Make target which can be used to
#  create a self-signed dummy server certificate for testing.

Index: src/Makefile.tmpl
===================================================================
*** src/Makefile.tmpl	1998/07/21 18:46:22	1.1.1.2
--- src/Makefile.tmpl	1998/08/11 14:43:41	1.4
***************
*** 51,56 ****
--- 51,70 ----
  		done; \
  	fi
  
+ #   create a dummy SSL server certificate for testing: this is a self-signed
+ #   SSL certificate which expires after 30 days and isn't encrypted (which
+ #   means you don't have to enter a pass-phrase on Apache startup time)
+ certificate:   
+ 	@echo "[Creation of a SSL test server certificate (expires in 30 days)]"
+ 	@$(SSL_BINDIR)/ssleay req \
+ 	    -config $(SSL_CNFDIR)/ssleay.cnf \
+ 	    -new -x509 -nodes \
+ 		-out    ../conf/sslcerts/server.pem \
+ 	    -keyout ../conf/sslcerts/server.pem \
+ 		-days 30
+ 	@cd ../conf/sslcerts && ln -sf server.pem \
+ 	     `$(SSL_BINDIR)/ssleay x509 -noout -hash <server.pem`.0
+ 
  subdirs:
  	@for i in $(SUBDIRS); do \
  		echo "===> $(SDP)$$i"; \

#  Now we have to add additional structure variables which
#  hold the SSL context information under run-time.

Index: src/include/buff.h
===================================================================
*** src/include/buff.h	1998/07/21 18:46:42	1.1.1.2
--- src/include/buff.h	1998/07/21 19:02:56	1.2
***************
*** 68,73 ****
--- 68,78 ----
  
  #include <stdarg.h>
  
+ #ifdef MOD_SSL
+ #include <stdio.h>
+ #include <ssl.h>
+ #endif
+ 
  /* Reading is buffered */
  #define B_RD     (1)
  /* Writing is buffered */
***************
*** 123,128 ****
--- 128,140 ----
  
      /* transport handle, for RPC binding handle or some such */
      void *t_handle;
+ 
+ #ifdef MOD_SSL
+     /* Add some context for SSL */
+     SSL *ssl;
+     char *szClientX509;
+     int nVerifyError;
+ #endif
  
  #ifdef B_SFIO
      Sfio_t *sf_in;

#  Now we just force some configuration defines which are globally required
#  for mod_ssl.

Index: src/include/ap_config.h
===================================================================
*** src/include/ap_config.h	1998/07/21 18:46:41	1.1.1.1
--- src/include/ap_config.h	1998/07/31 17:36:39	1.3
***************
*** 1168,1173 ****
--- 1168,1180 ----
  #define ap_wait_t int
  #endif
  
+ /*
+ **  SSL stuff
+ */
+ #ifdef MOD_SSL
+ #define NO_WRITEV
+ #endif
+ 
  #ifdef __cplusplus
  }
  #endif

#  Now we just have to add support for the HTTPS protocol scheme.

Index: src/include/httpd.h
===================================================================
*** src/include/httpd.h	1998/07/21 18:46:59	1.1.1.2
--- src/include/httpd.h	1998/08/11 09:41:56	1.4
***************
*** 129,136 ****
--- 129,141 ----
  #define DEFAULT_HTTP_PORT	80
  #define DEFAULT_HTTPS_PORT	443
  #define ap_is_default_port(port,r)	((port) == ap_default_port(r))
+ #ifdef MOD_SSL
+ #define ap_http_method(r)          ((r)->connection->client->ssl ? "https" : "http")
+ #define ap_default_port(r)         ((r)->connection->client->ssl ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT)
+ #else
  #define ap_http_method(r)	"http"
  #define ap_default_port(r)	DEFAULT_HTTP_PORT
+ #endif
  
  /* --------- Default user name and group name running standalone ---------- */
  /* --- These may be specified as numbers by placing a # before a number --- */

#  Now we have to patch the output routines to make sure that SSLeay's
#  output functions are used instead of the standard Unix functions when SSL
#  is enabled.

Index: src/main/buff.c
===================================================================
*** src/main/buff.c	1998/07/21 18:47:10	1.1.1.2
--- src/main/buff.c	1998/07/21 19:02:58	1.2
***************
*** 242,247 ****
--- 242,252 ----
      }
      else
  #endif
+ #ifdef MOD_SSL
+         if (fb->ssl)
+             rv = SSL_read(fb->ssl, buf, nbyte);
+         else
+ #endif
  	rv = read(fb->fd_in, buf, nbyte);
      
      return rv;
***************
*** 277,282 ****
--- 282,292 ----
      }
      else
  #endif
+ #ifdef MOD_SSL
+         if (fb->ssl)
+             rv = SSL_write(fb->ssl, (char *)buf, nbyte);
+         else
+ #endif
  #if defined (B_SFIO)
  	rv = sfwrite(fb->sf_out, buf, nbyte);
  #else
***************
*** 367,372 ****
--- 377,387 ----
  		       (size_t) SF_UNBOUND, 1, SF_WRITE);
  #endif
  
+ #ifdef MOD_SSL
+     fb->ssl = NULL;
+     fb->szClientX509 = NULL;
+ #endif
+ 
      return fb;
  }
  
***************
*** 1426,1431 ****
--- 1441,1453 ----
      fb->flags |= B_EOF | B_EOUT;
      fb->fd = -1;
      fb->fd_in = -1;
+ #ifdef MOD_SSL
+     if (fb->ssl) {
+         SSL_free(fb->ssl);
+         fb->ssl = NULL;
+     }
+ #endif
+ 
  
  #ifdef B_SFIO
      sfclose(fb->sf_in);

#  Now we have to apply the only really ugly patch for SSL support: Because
#  Apache's API lacks a hook for the socket connection phase we directly have
#  to call a pseudo-API function inside mod_ssl right after a new connection
#  was established to be able to do the initial SSL handshake.

Index: src/main/http_main.c
===================================================================
*** src/main/http_main.c	1998/07/21 18:47:27	1.1.1.2
--- src/main/http_main.c	1998/08/15 09:48:37	1.5
***************
*** 119,124 ****
--- 119,132 ----
  #include <netinet/tcp.h>
  #endif
  
+ /*  
+  *  needed for direct call inside main() 
+  *  because of missing API hook...
+  */
+ #ifdef MOD_SSL
+ int SSL_HOOK_SetupConnection(conn_rec *);
+ #endif
+ 
  #ifdef HAVE_BSTRING_H
  #include <bstring.h>		/* for IRIX, FD_SET calls bzero() */
  #endif
***************
*** 3248,3253 ****
--- 3256,3270 ----
  #endif
  }
  
+ #ifdef MOD_SSL
+ static void add_config_define(char *define)
+ {
+     char **var;
+     var = (char **)ap_push_array(ap_server_config_defines);
+     *var = ap_pstrdup(pcommands, define);
+     return;
+ }
+ #endif MOD_SSL
  
  /* Some init code that's common between win32 and unix... well actually
   * some of it is #ifdef'd but was duplicated before anyhow.  This stuff
***************
*** 3622,3627 ****
--- 3639,3654 ----
  				          (struct sockaddr_in *) &sa_server,
  				          my_child_num);
  
+ #ifdef MOD_SSL
+     /*
+      * This returns false if the connection cannot be setup,
+      * so maybe we should do something with this here...
+      * however it also blocks the BUFF connections
+      * so the next bit should fall out anyway!
+      */
+     SSL_HOOK_SetupConnection(current_conn);
+ #endif
+   
  	/*
  	 * Read and process each request found on our connection
  	 * until no requests are left or we decide to close.
***************
*** 4242,4247 ****
--- 4269,4278 ----
      MONCONTROL(0);
  
      common_init();
+ 
+ #ifdef MOD_SSL
+     add_config_define("MOD_SSL");
+ #endif
      
      ap_server_argv0 = argv[0];
      ap_cpystrn(ap_server_root, HTTPD_ROOT, sizeof(ap_server_root));
***************
*** 4402,4407 ****
--- 4433,4449 ----
  	conn = new_connection(ptrans, server_conf, cio,
  			          (struct sockaddr_in *) &sa_client,
  			          (struct sockaddr_in *) &sa_server, -1);
+ 
+ #ifdef MOD_SSL
+     /*
+      * This returns false if the connection cannot be setup,
+      * so maybe we should do something with this here...
+      * however it also blocks the BUFF connections
+      * so the next bit should fall out anyway!
+      */
+     SSL_HOOK_SetupConnection(conn);
+ #endif
+ 
  	r = ap_read_request(conn);
  	if (r)
  	    ap_process_request(r);	/* else premature EOF (ignore) */
***************
*** 4706,4711 ****
--- 4748,4763 ----
  				          (struct sockaddr_in *) &sa_client,
  				          (struct sockaddr_in *) &sa_server,
  				          child_num);
+ 
+ #ifdef MOD_SSL
+ 	/* 
+ 	 * This returns false if the connection cannot be setup,
+ 	 * so maybe we should do something with this here...
+ 	 * however it also blocks the BUFF connections
+ 	 * so the next bit should fall out anyway!
+ 	 */
+ 	SSL_HOOK_SetupConnection(current_conn);
+ #endif
  
  	/*
  	 * Read and process each request found on our connection

#  Now we have to make sure that a des_encrypt() function prototype inside
#  the vendor <crypt.h> header file doesn't conflict with the one from
#  SSLeay. Because des_encrypt() is not used inside Apache we just move the
#  prototype away overriding the name with a define.

Index: src/modules/standard/mod_auth.c
===================================================================
*** src/modules/standard/mod_auth.c	1998/07/21 18:48:07	1.1.1.2
--- src/modules/standard/mod_auth.c	1998/08/11 09:42:11	1.3
***************
*** 75,81 ****
--- 75,87 ----
  #include "http_log.h"
  #include "http_protocol.h"
  #if defined(HAVE_CRYPT_H)
+ #if defined(MOD_SSL)
+ #define des_encrypt MOVE_AWAY_des_encrypt
  #include <crypt.h>
+ #undef des_encrypt
+ #else
+ #include <crypt.h>
+ #endif /* MOD_SSL */
  #endif
  
  typedef struct auth_config_struct {

#  Now we add additional %{xxx}c tags to the CustomLog directive which can
#  be used to create an own SSL logfile. That's just for convenience.

Index: src/modules/standard/mod_log_config.c
===================================================================
*** src/modules/standard/mod_log_config.c	1998/07/21 18:48:29	1.1.1.2
--- src/modules/standard/mod_log_config.c	1998/08/16 12:16:18	1.6
***************
*** 127,132 ****
--- 127,142 ----
   * %...l:  remote logname (from identd, if supplied)
   * %...{Foobar}n:  The contents of note "Foobar" from another module.
   * %...{Foobar}o:  The contents of Foobar: header line(s) in the reply.
+  *
+  * Additional SSL directives:
+  *
+  * %...{version}c:    SSL protocol version
+  * %...{cipher}c:     SSL cipher used for encryption
+  * %...{subjectdn}c:  client certificate subject distinguished name
+  * %...{issuerdn}c:   client certificate issuer  distinguished name
+  * %...{errcode}c:    X509 verify error code
+  * %...{errstr}c:     X509 verify error string
+  *
   * %...p:  the port the request was served to
   * %...P:  the process ID of the child that serviced the request.
   * %...r:  first line of request
***************
*** 173,178 ****
--- 183,193 ----
  #include "http_log.h"
  #include <limits.h>
  
+ #ifdef MOD_SSL
+ #include <ssl.h>
+ #include <crypto.h>
+ #endif
+ 
  module MODULE_VAR_EXPORT config_log_module;
  
  static int xfer_flags = (O_WRONLY | O_APPEND | O_CREAT);
***************
*** 421,426 ****
--- 436,445 ----
      return ap_psprintf(r->pool, "%ld", (long) getpid());
  }
  
+ #ifdef MOD_SSL
+ static const char *log_ssl_info(request_rec *r, char *a);
+ #endif
+ 
  /*****************************************************************
   *
   * Parsing the log format string
***************
*** 486,492 ****
--- 505,516 ----
      {
          'P', log_child_pid, 0
      },
+ #ifdef MOD_SSL
      {
+         'c', log_ssl_info, 0
+     },
+ #endif
+     {
          '\0'
      }
  };
***************
*** 631,636 ****
--- 655,733 ----
      parse_log_item(p, (log_format_item *) ap_push_array(a), &s);
      return a;
  }
+ 
+ #ifdef MOD_SSL
+ static const char *log_ssl_info(request_rec *r, char *a)
+ {
+     char str[MAX_STRING_LEN];
+ 	char *result = NULL;
+ 	char *s;
+     X509 *xs;
+ 
+     if (!r->connection->client->ssl)
+         return NULL;
+ 
+     if (strcmp(a, "version") == 0) {
+ #if SSLEAY_VERSION_NUMBER >= 0x0900
+         switch(r->connection->client->ssl->session->ssl_version) {
+             case TLS1_VERSION:
+                 result = "TLS1";
+                 break;
+             case SSL3_VERSION:
+                 result = "SSL3";
+                 break;
+             case SSL2_VERSION:
+                 result = "SSL2";
+                 break;
+             default:
+                 result = "SSL?";
+         }
+ #else
+         static char v[5];
+         strcpy(v, "SSL");
+         v[3] = '0' + r->connection->client->ssl->session->ssl_version;
+         v[4] = '\0';
+         result = v;
+ #endif
+     }
+     else if (strcmp(a, "cipher") == 0) {
+         result = SSL_get_cipher(r->connection->client->ssl);
+     }
+     else if (strcmp(a, "subjectdn") == 0 || strcmp(a, "clientcert") == 0) {
+ #if 0
+         /* the expensive way */
+         if ((xs = SSL_get_peer_certificate(r->connection->client->ssl)) != NULL) {
+             s = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0);
+             result = ap_pstrdup(r->pool, s);
+             free(s);
+         }
+ #else
+         /* the cheap way */
+         result = r->connection->client->szClientX509;
+ #endif
+     }
+     else if (strcmp(a, "issuerdn") == 0 || strcmp(a, "cacert") == 0) {
+         if ((xs = SSL_get_peer_certificate(r->connection->client->ssl)) != NULL) {
+             s = X509_NAME_oneline(X509_get_issuer_name(xs), NULL, 0);
+             result = ap_pstrdup(r->pool, s);
+             free(s);
+         }
+     }
+     else if (strcmp(a, "errcode") == 0) {
+         if(r->connection->client->nVerifyError) {
+             sprintf(str, "%d", r->connection->client->nVerifyError);
+             result = ap_pstrdup(r->pool,str);
+         }
+     }
+     else if (strcmp(a, "errstr") == 0) {
+         if (r->connection->client->nVerifyError) {
+             result = X509_verify_cert_error_string(
+                      r->connection->client->nVerifyError);
+         }
+     }
+     return result;
+ }
+ #endif
  
  /*****************************************************************
   *

#  Now we provide an additional `startssl' command to supplement the
#  standard `start' command. The difference is just that `startssl' adds a
#  -DSSL define when starting httpd.

Index: src/support/apachectl
===================================================================
*** src/support/apachectl	1998/07/21 18:50:07	1.1.1.2
--- src/support/apachectl	1998/07/21 19:03:05	1.2
***************
*** 75,80 ****
--- 75,92 ----
  	    ERROR=3
  	fi
  	;;
+     startssl)
+ 	if [ $RUNNING -eq 1 ]; then
+ 	    echo "$0 $ARG: httpd (pid $PID) already running"
+ 	    continue
+ 	fi
+ 	if $HTTPD -DSSL; then
+ 	    echo "$0 $ARG: httpd started"
+ 	else
+ 	    echo "$0 $ARG: httpd could not be started"
+ 	    ERROR=3
+ 	fi
+ 	;;
      stop)
  	if [ $RUNNING -eq 0 ]; then
  	    echo "$0 $ARG: $STATUS"
***************
*** 153,158 ****
--- 165,171 ----
  	cat <<EOF
  
  start      - start httpd
+ startssl   - start httpd with SSL enabled
  stop       - stop httpd
  restart    - restart httpd if running by sending a SIGHUP or start if 
               not running

#  Now we have to add support for the HTTPS scheme and the additional
#  SSL_XXXX environment variables mod_ssl provides to the CGI scripts.

Index: src/support/suexec.c
===================================================================
*** src/support/suexec.c	1998/07/21 18:50:27	1.1.1.2
--- src/support/suexec.c	1998/07/21 19:03:06	1.2
***************
*** 210,216 ****
--- 210,222 ----
      }
  
      for (ep = environ; *ep && cidx < AP_ENVBUF; ep++) {
+ #ifdef MOD_SSL
+     if (!strncmp(*ep, "HTTP_", 5) || 
+         !strncmp(*ep, "HTTPS", 5) ||
+         !strncmp(*ep, "SSL_", 4)) {
+ #else
  	if (!strncmp(*ep, "HTTP_", 5)) {
+ #endif
  	    cleanenv[cidx] = *ep;
  	    cidx++;
  	}

#  Now we add additional SSL configuration directives. Actually
#  a virtual server is configured for Port 443 which speaks SSL.

Index: conf/httpd.conf-dist
===================================================================
*** conf/httpd.conf-dist	1998/07/21 18:45:50	1.1.1.1
--- conf/httpd.conf-dist	1998/08/16 12:26:49	1.8
***************
*** 31,36 ****
--- 31,47 ----
  
  Port 80
  
+ ##
+ ##  SSL Support
+ ##
+ ##  When we also provide SSL we have to listen to the 
+ ##  standard HTTP port (see above) and to the HTTPS port
+ ##
+ <IfDefine SSL>
+ Listen 80
+ Listen 443
+ </IfDefine>
+ 
  # HostnameLookups: Log the names of clients or just their IP numbers
  #   e.g.   www.apache.org (on) or 204.62.129.132 (off)
  # The default is off because it'd be overall better for the net if people
***************
*** 243,246 ****
--- 254,360 ----
  #TransferLog logs/host.some_domain.com-access_log
  #</VirtualHost>
  
+ 
+ ##
+ ##  SSL Support
+ ##
+ ##  Note that all SSL options can apply to virtual hosts, which
+ ##  is where we are going to put them now. We disable SSL globally 
+ ##  and enable only inside a virtual host only.
+ ##
+ 
+ <IfModule mod_ssl.c>
+ 
+ #   we disable SSL globally
+ SSLDisable                                                               
+ 
+ #   configure the path/port for the SSL session cache server [RECOMMENDED].
+ #   Additionally sets the session cache timeout, in seconds (set to 15 for
+ #   testing, use a higher value in real life) [RECOMMENDED]
+ SSLCacheServerPath     /usr/local/apache/sbin/ssl_gcache
+ SSLCacheServerPort     12345
+ SSLSessionCacheTimeout 300
+ 
+ <IfDefine SSL>
+ <VirtualHost new.host.name:443>
+ 
+ #   setup the general virtual server configuration
+ DocumentRoot @@ServerRoot@@/htdocs
+ ServerName new.host.name
+ ServerAdmin you@your.address
+ ErrorLog logs/error_log-ssl
+ TransferLog logs/access_log-ssl
+ 
+ #   enable SSL for this virtual host
+ SSLEnable
+ 
+ #   this forbids access except when SSL is in use. Very handy for defending
+ #   against configuration errors that expose stuff that should be protected
+ SSLRequireSSL
+ 
+ #   point SSLCertificateFile at a PEM encoded certificate.  If
+ #   the certificate is encrypted, then you will be prompted for a
+ #   pass phrase.  Note that a kill -HUP will prompt again. A test
+ #   certificate can be generated with `make certificate' under
+ #   built time. [RECOMMENDED]
+ SSLCertificateFile @@ServerRoot@@/conf/sslcerts/server.pem
+ 
+ #   if the key is not combined with the certificate, use this
+ #   directive to point at the key file. [OPTIONAL]
+ #SSLCertificateKeyFile @@ServerRoot@@/conf/sslkeys/server.pem
+ 
+ #   set the CA certificate verification path where
+ #   to find CA certificates for client authentication or
+ #   alternatively one huge file containing all of them
+ #   (file must be PEM encoded) [OPTIONAL]
+ #   Note: Inside SSLCACertificatePath you need hash symlinks
+ #         to point to the certificate files. Use the provided
+ #         Makefile to update the hash symlinks after changes.
+ #SSLCACertificatePath @@ServerRoot@@/conf/sslcerts
+ #SSLCACertificateFile @@ServerRoot@@/conf/sslcerts/ca.pem
+ 
+ #   set client verification level: [RECOMMENDED]
+ #   0|none:           no certificate is required
+ #   1|optional:       the client may  present a valid certificate
+ #   2|require:        the client must present a valid certificate
+ #   3|optional_no_ca: the client may  present a valid certificate 
+ #                     but it is not required to have a valid CA
+ SSLVerifyClient none
+ 
+ #   set how deeply to verify the certificate issuer chain 
+ #   before deciding the certificate is not valid. [OPTIONAL]
+ #SSLVerifyDepth 10
+ 
+ #   list the ciphers that the client is permitted to negotiate.
+ #   See the mod_ssl documentation for a complete list. [OPTIONAL]
+ #SSLRequiredCiphers RC4-MD5:RC4-SHA:IDEA-CBC-MD5:DES-CBC3-SHA
+ 
+ #   these two can be used on a per-directory basis to require or
+ #   ban specific ciphers. Note that (at least in the current version)
+ #   SSL will not attempt to renegotiate if a cipher is banned
+ #   (or not required). [OPTIONAL]
+ #SSLRequireCipher RC4-MD5
+ #SSLBanCipher RC4-MD5
+ 
+ #   translate the client X.509 into a Basic Authorisation. 
+ #   This means that the standard Auth/DBMAuth methods can be used for
+ #   access control. The user name is the `one line' version of
+ #   the client's X.509 certificate. Note that no password is
+ #   obtained from the user. Every entry in the user file needs
+ #   this password: `xxj31ZMTZzkVA'. [OPTIONAL]
+ #SSLFakeBasicAuth
+ 
+ #   a home for miscellaneous rubbish generated by SSL. Much of it
+ #   is duplicated in the error log file. Put this somewhere where
+ #   it cannot be used for symlink attacks on a real server (i.e.
+ #   somewhere where only root can write). [RECOMMENDED]
+ SSLLogFile @@ServerRoot@@/logs/ssl_misc_log
+ 
+ #   define custom SSL logging [RECOMMENDED]
+ CustomLog logs/ssl_log "%t %h %{version}c %{cipher}c %{subjectdn}c %{issuerdn}c \"%r\" %b"
+ 
+ </VirtualHost>                                  
+ </IfDefine>
+ 
+ </IfModule>
  

#  Now we just add a hyperlink to the mod_ssl.html document.

Index: htdocs/manual/mod/index.html
===================================================================
*** htdocs/manual/mod/index.html	1998/07/21 18:45:52	1.1.1.1
--- htdocs/manual/mod/index.html	1998/07/21 19:02:51	1.2
***************
*** 111,116 ****
--- 111,118 ----
  <DD>Experimental support for loading modules (DLLs on Windows) at runtime
  <DT><A HREF="mod_speling.html">mod_speling</A> Apache 1.3 and up
  <DD>Automatically correct minor typos in URLs
+ <DT><A HREF="mod_ssl.html">mod_ssl</A> Apache 1.3 with mod_ssl applied
+ <DD>Apache SSL interface to SSLeay
  <DT><A HREF="mod_status.html">mod_status</A>
  <DD>Server status display
  <DT><A HREF="mod_userdir.html">mod_userdir</A>

#  Now we just add hyperlinks for all directives which are
#  documented inside the mod_ssl.html document.

Index: htdocs/manual/mod/directives.html
===================================================================
*** htdocs/manual/mod/directives.html	1998/07/21 18:50:49	1.1.1.2
--- htdocs/manual/mod/directives.html	1998/07/21 19:02:50	1.2
***************
*** 201,206 ****
--- 201,223 ----
  <LI><A HREF="mod_setenvif.html#setenvif">SetEnvIf</A>
  <LI><A HREF="mod_setenvif.html#SetEnvIfNoCase">SetEnvIfNoCase</A>
  <LI><A HREF="mod_mime.html#sethandler">SetHandler</A>
+ <LI><A HREF="mod_ssl.html#SSLDisable">SSLDisable</A>
+ <LI><A HREF="mod_ssl.html#SSLEnable">SSLEnable</A>
+ <LI><A HREF="mod_ssl.html#SSLRequireSSL">SSLRequireSSL</A>
+ <LI><A HREF="mod_ssl.html#SSLCertificateFile">SSLCertificateFile</A>
+ <LI><A HREF="mod_ssl.html#SSLCertificateKeyFile">SSLCertificateKeyFile</A>
+ <LI><A HREF="mod_ssl.html#SSLCACertificatePath">SSLCACertificatePath</A>
+ <LI><A HREF="mod_ssl.html#SSLCACertificateFile">SSLCACertificateFile</A>
+ <LI><A HREF="mod_ssl.html#SSLVerifyClient">SSLVerifyClient</A>
+ <LI><A HREF="mod_ssl.html#SSLVerifyDepth">SSLVerifyDepth</A>
+ <LI><A HREF="mod_ssl.html#SSLRequiredCiphers">SSLRequiredCiphers</A>
+ <LI><A HREF="mod_ssl.html#SSLRequireCipher">SSLRequireCipher</A>
+ <LI><A HREF="mod_ssl.html#SSLBanCipher">SSLBanCipher</A>
+ <LI><A HREF="mod_ssl.html#SSLFakeBasicAuth">SSLFakeBasicAuth</A>
+ <LI><A HREF="mod_ssl.html#SSLCacheServerPort">SSLCacheServerPort</A>
+ <LI><A HREF="mod_ssl.html#SSLCacheServerPath">SSLCacheServerPath</A>
+ <LI><A HREF="mod_ssl.html#SSLSessionCacheTimeout">SSLSessionCacheTimeout</A>
+ <LI><A HREF="mod_ssl.html#SSLLogFile">SSLLogFile</A>
  <LI><A HREF="core.html#startservers">StartServers</A>
  <LI><A HREF="core.html#threadsperchild">ThreadsPerChild</A>
  <LI><A HREF="core.html#timeout">TimeOut</A>
