summaryrefslogtreecommitdiffstats
path: root/usr.sbin/httpd/src
diff options
context:
space:
mode:
authorbeck <beck@openbsd.org>1999-03-01 04:27:46 +0000
committerbeck <beck@openbsd.org>1999-03-01 04:27:46 +0000
commitda4e2a805b85b1e03ee77f85b14e50055c16e437 (patch)
tree1b45eae4a3a05003ba7cf157f7388b789dfae8bc /usr.sbin/httpd/src
parenttweak for 2.5 (diff)
downloadwireguard-openbsd-da4e2a805b85b1e03ee77f85b14e50055c16e437.tar.xz
wireguard-openbsd-da4e2a805b85b1e03ee77f85b14e50055c16e437.zip
mod_ssl-2.2.3-1.3.4 (will require libssl-1.1 for https to work, but
mostly harmless otherwise).
Diffstat (limited to 'usr.sbin/httpd/src')
-rw-r--r--usr.sbin/httpd/src/ApacheCore.def13
-rw-r--r--usr.sbin/httpd/src/CHANGES.SSL2225
-rw-r--r--usr.sbin/httpd/src/Configuration59
-rw-r--r--usr.sbin/httpd/src/Configuration.tmpl54
-rw-r--r--usr.sbin/httpd/src/Configure14
-rw-r--r--usr.sbin/httpd/src/Makefile.tmpl11
-rw-r--r--usr.sbin/httpd/src/ap/Makefile.tmpl2
-rw-r--r--usr.sbin/httpd/src/ap/ap.mak8
-rw-r--r--usr.sbin/httpd/src/ap/ap_ctx.c128
-rw-r--r--usr.sbin/httpd/src/ap/ap_hook.c873
-rw-r--r--usr.sbin/httpd/src/include/ap_config_auto.h59
-rw-r--r--usr.sbin/httpd/src/include/ap_ctx.h97
-rw-r--r--usr.sbin/httpd/src/include/ap_hook.h545
-rw-r--r--usr.sbin/httpd/src/include/ap_mmn.h16
-rw-r--r--usr.sbin/httpd/src/include/buff.h4
-rw-r--r--usr.sbin/httpd/src/include/http_conf_globals.h3
-rw-r--r--usr.sbin/httpd/src/include/http_config.h49
-rw-r--r--usr.sbin/httpd/src/include/http_main.h4
-rw-r--r--usr.sbin/httpd/src/include/httpd.h29
-rw-r--r--usr.sbin/httpd/src/main/buff.c28
-rw-r--r--usr.sbin/httpd/src/main/http_config.c58
-rw-r--r--usr.sbin/httpd/src/main/http_main.c54
-rw-r--r--usr.sbin/httpd/src/main/http_protocol.c9
-rw-r--r--usr.sbin/httpd/src/main/http_request.c3
-rw-r--r--usr.sbin/httpd/src/modules/proxy/mod_proxy.c67
-rw-r--r--usr.sbin/httpd/src/modules/proxy/proxy_http.c34
-rw-r--r--usr.sbin/httpd/src/modules/ssl/Makefile471
-rw-r--r--usr.sbin/httpd/src/modules/ssl/Makefile.libdir15
-rw-r--r--usr.sbin/httpd/src/modules/ssl/Makefile.tmpl413
-rw-r--r--usr.sbin/httpd/src/modules/ssl/Makefile.win32128
-rw-r--r--usr.sbin/httpd/src/modules/ssl/README92
-rw-r--r--usr.sbin/httpd/src/modules/ssl/README.dsov.fig346
-rw-r--r--usr.sbin/httpd/src/modules/ssl/README.dsov.ps1138
-rw-r--r--usr.sbin/httpd/src/modules/ssl/libssl.module513
-rw-r--r--usr.sbin/httpd/src/modules/ssl/libssl.version1
-rw-r--r--usr.sbin/httpd/src/modules/ssl/mod_ssl.c204
-rw-r--r--usr.sbin/httpd/src/modules/ssl/mod_ssl.h659
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c430
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c722
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c195
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c346
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c550
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c486
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c1268
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c292
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c340
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c464
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c189
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c408
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c626
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr.c119
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr.h139
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c257
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c550
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.h25
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y186
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c2002
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l261
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_util.c348
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c926
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h191
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c94
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h96
-rw-r--r--usr.sbin/httpd/src/modules/standard/mod_log_config.c40
-rw-r--r--usr.sbin/httpd/src/modules/standard/mod_rewrite.c9
-rw-r--r--usr.sbin/httpd/src/modules/standard/mod_so.c5
-rw-r--r--usr.sbin/httpd/src/support/Makefile.tmpl6
-rw-r--r--usr.sbin/httpd/src/support/apachectl13
-rw-r--r--usr.sbin/httpd/src/support/apxs.pl6
-rw-r--r--usr.sbin/httpd/src/support/ca-fix.c609
-rw-r--r--usr.sbin/httpd/src/support/httpd.exp13
-rw-r--r--usr.sbin/httpd/src/support/mkcert.sh659
-rw-r--r--usr.sbin/httpd/src/support/suexec.c6
73 files changed, 21298 insertions, 4 deletions
diff --git a/usr.sbin/httpd/src/ApacheCore.def b/usr.sbin/httpd/src/ApacheCore.def
index d6c8d8837d2..ce7044e12f7 100644
--- a/usr.sbin/httpd/src/ApacheCore.def
+++ b/usr.sbin/httpd/src/ApacheCore.def
@@ -324,4 +324,17 @@ EXPORTS
ap_make_etag @317
ap_array_pstrcat @318
ap_os_is_filename_valid @319
+ ap_add_config_define @320
+ ap_global_ctx @321
+ ap_ctx_new @322
+ ap_ctx_get @323
+ ap_ctx_set @324
+ ap_hook_init @325
+ ap_hook_kill @326
+ ap_hook_configure @327
+ ap_hook_register_I @328
+ ap_hook_unregister_I @329
+ ap_hook_status @330
+ ap_hook_use @331
+ ap_hook_call @332
diff --git a/usr.sbin/httpd/src/CHANGES.SSL b/usr.sbin/httpd/src/CHANGES.SSL
new file mode 100644
index 00000000000..16304281a32
--- /dev/null
+++ b/usr.sbin/httpd/src/CHANGES.SSL
@@ -0,0 +1,2225 @@
+ _ _
+ _ __ ___ ___ __| | ___ ___| |
+ | '_ ` _ \ / _ \ / _` | / __/ __| |
+ | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+ |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+ |_____|
+ _____________________________________________________________________________
+
+ ``The difference between a career
+ and a job is about 20 hours a week.''
+ CHANGES
+
+ This file summarizes *all* types of changes to the mod_ssl package, i.e.
+ changes between each betalevel and patchlevel, i.e. changes between
+ 2.x.y->2.x.(y+1) and 2.x.y->2.(x+1).0. Take this list as a reference for
+ concrete and detailed information about every single change.
+
+ ____ ____
+ |___ \ |___ \
+ __) | __) |
+ / __/ _ / __/
+ __ |_____(_)_____| _________________________________________
+
+ Changes with mod_ssl 2.2.3 (05-Feb-1999 to 21-Feb-1999)
+
+ *) Cleaned up the namespace of mod_ssl structures:
+ All helper structures are now named ssl_xxxx_t.
+
+ *) Fixed hyperlinks to mod_log_config.html in mod_ssl's User Manual
+
+ *) Let mod_log_config's %{XXXX}x functions (provided by mod_ssl) correctly
+ expand to "-" instead of "" in case XXXX is not available as it's the
+ case for other mod_log_config functions.
+
+ *) Unbreak `SSLOptions +CompatEnvVar' by fixing two nasty bugs
+ and adding a missing variable.
+
+ *) Fixed a confusing "not"-typo in the FAQ.
+
+ *) Another round to get rid of the core dumps under the DSO situation when
+ DSOs are loaded to different memory addresses. We now no longer try to
+ preserve `RSA *' and `X509 *' structures of the SSL library between
+ Apache's init rounds. Because as we discovered, SSLeay/OpenSSL uses
+ various static variables inside these structures which is a big NO-NO
+ for the nasty Apache double-init round situation. Instead we now convert
+ the internal structures to DER/ASN.1 byte-streams allocated inside
+ mod_ssl's global memory pool. This now at least fixed the core dumps
+ under the Solaris/DSO situation for me.
+
+ *) Incorporated a few cleanups for the SDBM code Gred Stein sent me
+ while he was adding SDBM to his mod_dav package.
+
+ Changes with mod_ssl 2.2.2 (04-Feb-1999 to 05-Feb-1999)
+
+ *) Fixed `SSLOptions +FakeBasicAuth' and related stuff which
+ was broken because of a typo in a context variable name.
+
+ *) Fixed ToC in chapter 1 of the user manual.
+
+ *) Fixed export lists src/ApacheCore.def (Win32) and
+ src/support/httpd.exp (AIX).
+
+ Changes with mod_ssl 2.2.1 (27-Jan-1999 to 04-Feb-1999)
+
+ *) Now the configure script uses bold mode to mark some
+ error messages under xterm, vt100 and vt220 terminals.
+
+ *) Added a new chapter 5 (`HowTo') to the User Manual where solutions for
+ typical situations are presented.
+
+ *) Now mod_ssl identifies itself to the SCCS `what' and RCS `ident'
+ commands with a string `mod_ssl/2.2.x'. This allows one for instance to
+ quickly check what version a libssl.so by typing `what libssl.so' or
+ `ident libssl.so'.
+
+ *) Added a new directive `SSLProtocol' which is compatible to Stronghold
+ 2.x's directive of the same name. It provides a handy way to control the
+ SSL protocol flavors (SSLv2, SSLv3, TLSv1) mod_ssl should provide on the
+ server side. It's use is a little bit similar to special cases of
+ SSLCipherSuite, but it actually directly affects internal behaviour of
+ the SSL library. So, saying `SSLProtocol all -SSLv3 -TLSv1' to get a
+ SSLv2 only server is not really equal to an `SSLCipherSuite' where just
+ all SSLv3 and TLSv1 ciphers are dropped.
+
+ *) EAPI functions are now also added to src/ApacheCore.def.
+
+ *) Output a warning when `SSLVerifyClient require' is used but no CAs are
+ configured for verification. Additionally the `peer didn't return a
+ certificate' message is annotated with a similar hint.
+
+ *) Updated the README.dsov.{fig,ps} files to reflect the
+ additional internal data structure link from SSL* to request_rec*.
+
+ Changes with mod_ssl 2.2.0 (21-Jan-1999 to 27-Jan-1999)
+
+ *) Commit the long-prepared and long-awaited feature of
+ per-directory SSL configuration parameters.
+
+ The background is this: SSL parameters like the Cipher Suite or the
+ certificate chain verification parameters up to now could only be
+ configured on a per-(virtual)server basis and this way apply to all URLs
+ under https://this-virtual-server/. The drawback is obvious: You've to
+ find a common denominator for the whole website which isn't usually
+ possible. For instance just because you need client authentication
+ (``SSLVerifyClient require'') for https://this-virtual-server/foo/bar/,
+ this shouldn't mean you have to force client authentication for the
+ whole server. Same for ciphers: Just because a subarea needs to enforce
+ a stronger cipher (e.g. no export, no null cipher, etc.) shouldn't mean
+ that the whole website can only be visited with those requirements. So
+ the idea is to enforce those (usually stronger) requirements on a
+ per-directory basis.
+
+ The problem is: It's a chicken and egg situation. To decide which
+ parameters should be enforced in the SSL handshake mod_ssl has first to
+ find out the requested directory. For this the HTTP request has to be
+ read. But for this the SSL handshake first has to be performed. Bingo!
+
+ The nifty solution known from Netscape Commerce servers now is: We
+ simply do the standard SSL handshake, then we read the HTTP response,
+ then we perhaps reconfigure the parameters and enforce a second SSL
+ handshake (this is called "SSL renegotiation") with it. And only when
+ this handshake is also successful, the HTTP response is send.
+
+ How is this configured? You just put additional SSLVerifyClient,
+ SSLVerifyDepth and/or SSLCipherSuite directives in <Directory> or
+ <Location> containers or even .htaccess files. When Apache reaches those
+ directories, those directives reconfigure the SSL parameters and the SSL
+ renegotation is automatically enforced by mod_ssl. The only drawback is
+ that although an optimization is done to reduce unnecessary
+ renegotiations (when the parameters were not actually changed), you
+ usually increase the overhead for a request because a SSL renegotiation
+ is expensive. So, use the per-directory reconfiguration feature
+ economically.
+
+ Under SSL_EXPERIMENTAL additionally the directives SSLCACertificatePath
+ and SSLCACertificateFile can be used in per-directory context for
+ reconfiguration. But it's tagged experimental because SSLeay/OpenSSL
+ still lacks real support for this. So an ugly kludge has to be done to
+ support these two directives, too.
+
+ *) Give out more information on "Certificate Chain too long" error message.
+
+ *) Moved SSLeay/OpenSSL specific stuff to the new source files
+ ssl_util_ssl.[ch]. !! ATTENTION: NOW SSLeay 0.9.0 or OpenSSL IS NEEDED
+ !! Because the new internal structures need at least SSL_get_ex_data()
+ and SSL_set_ex_data() and those are not supported in SSLeay 0.8.x. So
+ we removed all remaining support for SSLeay 0.8.0. OTOH that's no
+ problem, because SSLeay 0.8.x is known to be unstable, so it's
+ reasonable to remove support for it also for other reasons.
+
+ *) Added a second SSL context variable which holds (with a delay) a pointer
+ back to the request_rec structure in Apache. This is needed to reach
+ the per-directory configuration parameters.
+
+ *) Updated the User Manual for mod_ssl 2.2
+
+ *) Added SSL_EXPERIMENTAL rule to Configuration.tmpl which
+ can be used to enable (APACI: ``--enable-rule=SSL_EXPERIMENTAL'')
+ experimental code inside mod_ssl. Code is declared experimental unless
+ it is proofed to be stable by the users.
+
+ *) Replaced the GNU Bison generated ssl_expr_parse.[ch] files with variants
+ generated by BSD Yacc. This way we have more portable source because BSD
+ Yacc doesn't used alloca() and other tricks. This especially should
+ solve the problems under HP/UX.
+
+ *) Updated INSTALL file for recent changes and fixed a few typos there.
+
+ *) Add a SSL_SDBM rule to Apache's Configuration.tmpl which can be used
+ (APACI: ``--enable-rule=SSL_SDBM'') to force mod_ssl to built with the
+ built-in SDBM instead of the custom defined (DBM_LIB) or vendor supplied
+ DBM library. This is especially useful when the vendor DBM library is
+ buggy or restricts the data size too dramatically (BTW, Berkeley-DB/1.x,
+ Berkely-DB/2.x and GDBM based DBM libraries are ok, because they allow
+ unlimited data size).
+
+ *) Enlarge the SDBM pag/dir blocksize from 1KB/4KB to 8KB/32KB to make sure
+ SDBM really can deal with SSL sessions containing long certificate
+ chains. !! ATTENTION: THIS MEANS THAT YOU'VE TO ONCE REMOVE THE FILE YOU
+ CONFIGURED WITH SSLSessioCache WHEN SDBM WAS USED AND YOU UPGRADE TO
+ THIS OR A LATER mod_ssl VERSION, BECAUSE THE INTERNAL LAYOUT CHANGED. SO
+ THE FILE HAS TO BE RECREATED WITH THE NEW LAYOUT !!
+
+ *) Make the DBM based session cache more robust by using additional error
+ situations. This should fix some observed core dumps on Linux boxes
+ where the vendor DBM library returned strange values.
+
+ *) Fixed configuration handling for global directives: Now the correct
+ memory pools are used and after the first configuration round the global
+ configuration structure is locked.
+
+ *) Added a new `SSLRandomSeed' directive for explicit seeding the Pseudo
+ Random Number Generator (PRNG) of the SSL library on server startup
+ and/or connection establishment time. The intent is that this way the
+ PRNG is better initialized and this way the security of the generated
+ SSL protocol ingredients are more secure (because less predictable). For
+ maximum flexibility you can use three seed sources: an internal source,
+ an external file or an an external program. And you can specify one or
+ more such sources, of course. For instance under a FreeBSD box you can
+ now use the following:
+
+ SSLRandomSeed startup builtin
+ SSLRandomSeed startup exec:bin/truerand 16
+ SSLRandomSeed startup file:/dev/random 512
+ SSLRandomSeed startup file:/dev/urandom 512
+ SSLRandomSeed connect builtin
+ SSLRandomSeed connect file:/dev/random 512
+ SSLRandomSeed connect file:/dev/urandom 512
+
+ This would at server startup-time seed the PRNG first with a few bytes
+ from the internal source, plus 16 bytes read from stdout of the
+ `truerand' utility (which is based on the AT&T truerand library and can
+ be found in the mod_ssl distribution under pkg.contrib/), plus up to 512
+ bytes from the /dev/random device (it usually only returns a maximum
+ number of bits of randomness currently contained in the device entropy
+ pool) plus 512 bytes from the /dev/urandom device (which usually returns
+ as many bytes as requested, but of low random-quality). Additionally
+ before any new SSL connection is established the PRNG is again seed from
+ the internal source plus up to 512 bytes from /dev/random and plus 512
+ bytes from /dev/urandom. This should give an adequate seed for the PRNG
+ used for generating the SSL protocol ingredients.
+
+ *) Removed some unneccessary defines for `index' and `rindex'
+ in etc/patch/config.h which caused problems under AIX.
+
+ *) Changed a misleading sentence about RSAref in INSTALL
+
+ *) Overtake the idea of Apache-SSL 1.30 to log SSL errors also directly
+ after SSL_read/SSL_write. This way those error messages should no longer
+ be missed.
+
+ ____ _
+ |___ \ / |
+ __) | | |
+ / __/ _| |
+ __ |_____(_)_| _____________________________________________
+
+ Changes with mod_ssl 2.1.8 (11-Jan-1999 to 21-Jan-1999)
+
+ *) Added an additional variable REQUEST_SCHEME which can be used for in
+ SSLRequire, RewriteCond, RewriteRule, etc. to forward or redirect
+ HTTP/HTTPS requests with the incoming URL scheme.
+
+ *) Surrounded ap_hook_[un]register() calls with wrapper macros to
+ implicitly cast the function pointers to void pointers, because strict
+ ANSI C requires this.
+
+ *) Added AP_HOOK_ALL support which can be used to call all registered
+ callback-functions for a hooks, independent of any decline value.
+ This will be used in the future by forthcoming features.
+
+ *) Fixed a potential security hole: Both the SSLMutex and SSLSessionCache
+ files are now created without read access for the group and others.
+
+ *) Fixed a typo in the SSL logfile hints and in the terminal
+ message displayed for the `make certificate' step.
+
+ *) Under Extended API situations we now replace the module magic cookie
+ "AP13" with "EAPI" to let us later distinguish between the EAPI-aware
+ module structures (which contain additional pointers at the end) and
+ standard module structures (which lack at least NULL's for the pointers
+ at the end of the structure). This is important because standard
+ ("AP13") modules would dump core when we dispatch over the additional
+ hooks because NULL's are missing at the end of the module structure.
+
+ But we now to the following: We allow _both_ types of modules to be
+ loaded by mod_so, but dispatch over the EAPI hooks only when the module
+ magic cookie indicates "EAPI". This way an Apache+EAPI server can load
+ module DSOs built with a plain Apache. That's important to allow people
+ for instance use mod_coldfusion (which is available only as a pre-built
+ DSO!) or allow the Debian package maintainers to finally build their
+ Apache package with EAPI without the need to upgrade all other module
+ packages at the same time.
+
+ *) The SSLMutex filename now is internally extended to contain the PID of
+ the Apache parent process to make the file unique across different
+ server instances. That's the same approach Apache already uses for the
+ accept mutex lockfile.
+
+ *) We now replace the MODULE_MAGIC_COOKIE ("AP13") with "EAPI" under -DEAPI
+ to make sure that mod_so only loads modules which were really compiled
+ with -DEAPI. Because else NULL's at the end of the module structure are
+ missing, which always will leads to core dumps when the Apache core
+ dispatches over it.
+
+ *) Removed hints to the test suite in INSTALL.Win32 because under this
+ platform there are more test suite problems before the tests can be
+ really reasonable.
+
+ *) Now mod_rewrite's %{XXXX} construct can also "magically" expand all
+ variables known to mod_ssl, i.e. especially the SSL_XXXX variables.
+ This way you can use the same variables in a RewriteRule or RewriteCond
+ you're used to use in a SSLRequire directive.
+
+ *) Fixed a few type problems in ca-fix.c which caused strict ANSI C
+ compilers (not GCC) to complain and fail. This especially fixed the
+ problems under AIX 4.2
+
+ *) Fixed a syntax problem GCC and VC++ never complained about: A trailing
+ comma on the last element of an enumeration declaration is not allowed,
+ of course.
+
+ *) Changed the EAPI usage inside mod_log_config.c to no longer store a
+ foreign function pointer (which belongs to mod_ssl) into internal
+ structures (because when mod_ssl is unloaded during restarts they evolve
+ into dangling references).
+
+ *) Cleaned up the verbose output of configure & configure.bat
+ and added also support for -v to configure.bat.
+
+ *) Make sure mod_ssl's configure script stops with an error
+ when Apache's configure (APACI) script stopped with an error.
+
+ *) Overtake the important idea from Khimenko Victor's EAPI variant to
+ _un_register EAPI hooks for the various modules when the module is
+ unloaded (DSO!). Without this dangling references occur inside the EAPI
+ hook lists which can cause core-dumps.
+
+ *) Fixed the %{errstr}c function provided for mod_log_config
+ and let %{errcode}c always expand to "-".
+
+ *) Fixed the self-referencing hyperlink in ssl_overview.html
+
+ Changes with mod_ssl 2.1.7 (06-Jan-1999 to 11-Jan-1999)
+
+ *) Fixed APXS support for configure script: The --with-apxs was broken when
+ `apxs' wasn't in the PATH.
+
+ *) Added hint for DSO/PIC-situation to the INSTALL file.
+
+ *) Changed the "you're speaking HTTP to the HTTPS port" error message from
+ HTTP_INTERNAL_SERVER_ERROR to BAD_REQUEST, because first BAD_REQUEST is
+ more correct and HTTP_INTERNAL_SERVER_ERROR from Apache 1.3.4 on no
+ longer displayed the "error-note".
+
+ *) Now finally use LIBS_SHLIB for APXS support (because Apache 1.3.4's apxs
+ is fixed) and also query the target name and no longer hard-code
+ "httpd".
+
+ *) Upgraded to Apache 1.3.4
+
+ *) Now the client IP and server virtual host id are displayed
+ in addition to the general handshake failure logfile message to make it
+ more meaningful inside the Apache error_log (where no SSL context is
+ given).
+
+ *) Remove the ca-fix "-pathlen 0" option in mkcert.sh when creating the
+ server cert. It's only useful for the CA certs.
+
+ Changes with mod_ssl 2.1.6 (02-Jan-1999 to 06-Jan-1999)
+
+ *) Be even more conservative and correct when aborting a connection: We now
+ set the conn_rec->aborted flag in addition to blocking the
+ connection/socket buffer.
+
+ *) Added some sort of downgrading support to the logging function to no
+ longer create messages like "(SSLeay error follows)" although no such
+ message follows (because SSLeay has no one). The same is done for the
+ System/errno related messages.
+
+ *) Removed direct fiddling with the BUFF->flags stuff. Instead we now use
+ the API conforming way via ap_bsetflag().
+
+ *) Added timeout support for the SSL handshake phase. The timeout in
+ seconds is the same as configured with the standard Apache "Timeout"
+ directive for the HTTP request phase. This way one can defend against
+ special DoS attacks (where the attacker just establishes a lot of
+ parallel connections but doesn't send data) to the HTTPS port the same
+ way one can already do it for the HTTP ports.
+
+ *) Fixed a display error in the `debug' dump messages and made
+ the debug dumping more robust by explicitly checking for the case where
+ SSLeay gives us either a NULL memory pointer or a memory length of -1.
+
+ *) Fixed the "Exit: ..." trace messages: They wrote out an (unnecessary)
+ additional newline which optically broke the tracing messages.
+
+ *) Fixed the "you're speaking HTTP to the HTTPS port" error handling.
+ mod_ssl caused a core dump of the Apache child because the request
+ processing functions were not aware that a dynamically downgraded (from
+ HTTPS to HTTP) request can exists for error sitiations.
+
+ *) Added the EAPI functions to src/support/httpd.exp which is needed to
+ compile mod_ssl as a DSO under the most non-smart linker: AIX' ld.
+
+ *) Fixed internal `host:port' based identification of virtual servers which
+ caused problems under specific Listen/<VirtualHost> configuration
+ variants where an implicit port was used. Additionally we now no longer
+ patch the server_rec->port variable of Apache. Instead we leave it as is
+ and on-the-fly make our decisions.
+
+ *) Fixed APXS/EAPI-related error message in the configure script.
+
+ *) More OpenSSL support: Recognize the forthcoming `openssl' program in
+ addition to `ssleay' when searching for the command line tool.
+
+ Changes with mod_ssl 2.1.5 (23-Dec-1998 to 02-Jan-1999)
+
+ *) Fixed virtual host configuration merging by removing
+ the default value for SSLCertificateFile.
+
+ *) Replaced index() (non-POSIX) with strchr() (POSIX) function
+ because it doesn't exists under the Win32 environment.
+
+ *) Fixed SSLPassPhraseDialog argument processing: exec:/path/to/program
+ argument variant was not parsed correctly.
+
+ *) Let EAPI hooks also be added to the APXS generated
+ sample module (`apxs -g -n foo').
+
+ Changes with mod_ssl 2.1.4 (05-Nov-1998 to 23-Dec-1998)
+
+ *) Added the support for OpenSSL (see http://www.openssl.org/),
+ the Open Source sucessor of SSLeay. The package name is no longer
+ hard-wired and so both the HTTP Server field and the logfile entries
+ correctly reflect the name OpenSSL, too.
+
+ *) Changed the EAPI hook `rewrite_command' from
+ ``char *(*rewrite_command) (cmd_parms *, const char *)'' to
+ ``char *(*rewrite_command) (cmd_parms *, void *config, const char *)''
+ to allow modules to also access the config structure.
+
+ *) Added two AddType directives to httpd.conf-dist for
+ loading .crt and .crl files into Netscape Communicator.
+
+ *) Added an entry about the Wassenaar Agreement to the mod_ssl FAQ. In
+ short: both mod_ssl and SSLeay are not affected by the Wassenaar
+ Agreement.
+
+ *) Added a few more backslashes to the INSTALL step-by-step lists
+ to make it more clear which commands are on the same command
+ line and which are separate commands.
+
+ *) Added `Year 2000' and `Netscape Lock Icon' entries to the FAQ and fixed
+ a few layouting bugs in the FAQ.
+
+ *) Lot's of cleanups to make the source more accurate and to remove
+ thread-unsafe stuff. Especially all global mc->rCtx.pConn and
+ mc->rCtx.pServ references are now gone. Additionally the SSLeay app_data
+ facility is used whereever possible to walk from SSLeay data structures
+ to Apache data structures without the need of global variables.
+
+ *) Cleaned up and enhanced the README.GlobalID document with more
+ information about the Global ID stuff with the help of
+ additional hints from Dr Stephen N. Henson.
+
+ Changes with mod_ssl 2.1.3 (03-Nov-1998 to 05-Dec-1998)
+
+ *) Added APXS support: By using the --with-apxs option you can now easily
+ upgrade the libssl.so file through a stand-alone build process as long
+ as you actually use DSO and EAPI doesn't change. In other words, a
+ simple `./configure --with-apxs=/path/to/apache/sbin/apxs
+ --with-ssleay=/path/to/your/ssleay; make install' can be used to upgrade
+ the /path/to/apache/libexec/libssl.so.
+
+ *) Added support documenation, programs and scripts for the `Global Server
+ ID' facility as README.GlobalID, pkg.contrib/gid-mkcert.sh,
+ pkg.contrib/gid-tagcert.c and pkg.contrib/loadcacert.cgi. This way
+ people can setup their own private `Global Server ID' stuff :)
+
+ *) Allowed SSL renegotiations initiated by the client.
+ This especially adds support for Verisign's `Global Server ID' facility
+ where Netscape Communicator does a renegotiation to upgrade the SSL
+ connection parameters (the cipher) from 40-bit to 128-bit encryption.
+
+ *) Fix typo in httpd.conf-dist: `</Location />' -> `</Location>'
+
+ *) Added new README.dsov.{fig,ps} files: They are intended for those people
+ who want to hack theirself inside the mod_ssl source. The figure
+ provides two diagrams which show the lifetime and chaining of the
+ various Apache, mod_ssl and SSLeay data structures which are used inside
+ mod_ssl.
+
+ *) Cleaned up some documents.
+
+ *) Cleaned up ssl_engine_compat.c a little bit more...
+
+ Changes with mod_ssl 2.1.2 (30-Nov-1998 to 03-Dec-1998)
+
+ *) Let `httpd -V' show `-D EAPI', too.
+
+ *) Fixed again the DBM library determination inside libssl.module: A syntax
+ error caused the fallback (SDBM) to be never used which leaded to
+ problems on systems where no DBM library exists.
+
+ *) Added a check to libssl.module: It now complains with
+ a warning when SSLeay 0.8 is used because of the known problems (core
+ dumps on large files, etc.) with these versions.
+
+ *) Slightly changed mod_ssl's configure hints displayed as the last step.
+
+ *) Removed internal OPTIONAL_SSL stuff which was inherited from Apache-SSL.
+ I currently cannot see a good reason for allowing subrequests to disable
+ SSL, so kick out this stuff.
+
+ *) Extended Chapter 5 (FAQ List) of the User Manual.
+
+ *) Added the Website META Language (WML) sources for the User Manual to the
+ distribution: This way all sources are available to the user community.
+
+ *) Removed one last reference to SSLCACertificateReqFile inside the
+ httpd.conf-dist file.
+
+ Changes with mod_ssl 2.1.1 (17-Nov-1998 to 30-Nov-1998)
+
+ *) Fixed typos in pass phrase dialog.
+
+ *) Added support to APACI for overriding the conf/ssl.crt/server.crt
+ default certificate path.
+
+ *) Added another logging level `trace' (between `info' and `debug')
+ and converted all existing `debug' messages to this level. Additionally
+ the internal SSLeay processing is now logged to this level, too. The
+ `debug' level now consists of deepest-level I/O dumps where you can even
+ see every read/write byte on the BIO (the buffer above the SSL record
+ layer).
+
+ *) Changed buffer I/O: Previously NO_WRITEV was forced
+ because there is no real SSL_writev() available. But the drawback of
+ this was that writev() (which nevertheless is available on mostly all
+ platforms) wasn't used for non-SSL requests. The result was bad network
+ I/O performance when Apache was built with EAPI/mod_ssl. This is now
+ changed: When writev() is available it is used for non-SSL requests
+ (this way we gain maximum performance) while for SSL requests the output
+ is still done via SSL_write().
+
+ *) Fixed DBM library determination and build. This especially fixed the
+ problems with DSO support under Linux platforms where libdbm was
+ previously not linked against libssl.
+
+ *) Added a README.Patents document to the distribution
+ which tries to explain some RSA patent issues.
+
+ *) Fixed Thawte sxnet stuff to work with recent EAPI changes.
+
+ *) Fixed documentation: X.509 field was incorrect: SP -> ST.
+
+ *) Fixed SSL support for mod_proxy: It was broken because
+ the "ssl_enable" ctx-flag was set too late.
+
+ *) Ported a recent change in Apache-SSL 1.29 to mod_ssl:
+ ``Send CA list to client when SSLCACertificatePath is used (this was
+ only done for SSLCACertificateFile up to now)''. I've implemented it
+ with a new ssl_init_FindCAList() function in ssl_engine_init.c where the
+ main difference is that it _merges_ the list entries from both
+ directives together while in Apache-SSL the SSLCACertificatePath would
+ override the SSLCACertificateFile for this list generation. I use them
+ in parallel for the list generation (by merging their entries) because
+ they are used in parallel by SSLeay under the verification process, too.
+ Additionally I've now removed SSLCACertifiateReqFile because it was
+ oversize.
+
+ *) Added a similar SSL_accept() check as was recently added to Apache-SSL
+ 1.29, but in a different way: Under the SSL_ERROR_ZERO_RETURN error
+ don't log it as an error. A "info"-level log entry is enough.
+
+ *) Extended the Compatibility chapter of the User Manual to now also
+ contain information about environment variable derivation.
+
+ *) Overhauled the SSL part in the http.conf-dist file.
+
+ *) Fixed pkg.sslcfg/ssl.key/server.key: It contained a dummy key
+ instead of the intended dummy text "THIS FILE SHOULD ...".
+
+ *) Fixed httpd.conf-dist: The SSLRequire is only allowed in
+ <Location> or <Directory> sections there.
+
+ *) Fixed documentation: sign.sh instead of ca.sign, SSLRequire uses
+ braces and not parenthesis for word groups, etc.
+
+ *) Use the commonly used .crt extension also in the sign.sh script
+
+ *) Fixed backward compatibility code: half-way matching could occur (Sioux'
+ "RequireSSL" matched the correct "SSLRequireSSL" and leaded to
+ "SSLSSLRequireSSL") and the SSLRequireCipher/SSLBanCipher directives
+ were not matched correctly.
+
+ *) Don't do I/O read-aheads in SSLeay under Win32 because it's not safe
+ for this platform (we use select() there).
+
+ *) Fixed two memory leaks in ssl_engine_var.c by copying over
+ malloc-allocated buffers from X509_NAME_oneline() to Apache
+ pool-allocated buffers.
+
+ *) Fixed RSAref handling: the -L path to the librsaref.a library
+ file was configured incorrectly (a bogus "/lib" was there)
+
+ *) Fixed some ANSI C portability issues which popped up with IRIX vendor
+ compiler while good-old GCC was happy. This way other compilers should
+ be quiet now, too.
+
+ *) Added notice and workarounds for RSAref portability problem to the
+ INSTALL document. This is especially important to people using platforms
+ with non-Intel CPUs (like the Alpha-boxes of DEC).
+
+ Changes with mod_ssl 2.1.0 (15-Nov-1998 to 17-Nov-1998)
+
+ *) Updated all distribution documents for the final release.
+
+ *) Fixed configure.bat script: It failed for version strings like 2.1.0 (no
+ "b" for beta contained), failed to patch Apache's src/Makefile.nt file
+ correctly and used not necessary options in nmake calls. Additionally
+ it now creates .orig files for the patched DevStudio Makefiles, too.
+
+ Changes with mod_ssl 2.1b9 (04-Nov-1998 to 15-Nov-1998)
+
+ *) Replaced the pkg.ssldoc/* stuff with the new mod_ssl 2.1 User Manual.
+
+ *) Fixed patching of Makefile.nt under Win32.
+
+ *) Changed test `-e' option to more portable `-r' option.
+
+ *) Fixed again the init round handling: The SSLeay initialization
+ has to be done _every_ time under DSO/DLL situation because
+ there SSLeay is part of the mod_ssl DSO/DLL which is re-loaded.
+
+ *) Under DSO situation the LoadModule directive for libssl.so
+ is now surrounded by <IfDefine SSL>, too. This way when
+ -DSSL is not used not even the module is loaded.
+
+ *) Replaced the last global var (ssl_ModConfig) with an ap_global_ctx
+ based approach. This way thread-safety for Win32 and Apache 2.0
+ can be made more easily.
+
+ *) Added compile time check for EAPI:
+ mod_ssl now can only be compiled when EAPI is active.
+
+ *) Forward port from 2.0 branch:
+ Now SSLVerifyDepth defaults to 1 and this means the client certificate
+ has to be signed directly by the root CA. The verify depth now is the
+ max number of CAs which are checked: 0 = self-signed only, 1 =
+ self-signed or signed by root-CA, 2 = signed by root-CA or signed by a
+ CA which is signed by the root-CA, etc.
+
+ *) Forward port from 2.0 branch:
+ Now SSLSessionCacheTime defaults to 300s.
+
+ *) Forward port from 2.0 branch:
+ Fixed RSAref instructions in INSTALL file and added more support for
+ implicitly finding the RSA_BASE to the libssl.module script.
+
+ *) Added a SSL_COMPAT configuration rule which is enabled per
+ default. But when you disable it via --disable-rule=SSL_COMPAT the
+ backward compatibility code is not build into mod_ssl. This provides a
+ little bit better performance for those people who don't need the compat
+ stuff.
+
+ *) Removed the patch from mod_auth.c by not spreading the -I option for
+ SSLeay. Because with the EAPI only the mod_ssl needs to include SSLeay
+ headers. So we no longer have a conflict with the vendors
+ crypt.h stuff ;-)
+
+ *) Moved the patch from ap_config.h into libssl.module.
+
+ *) Overhauled the mod_ssl distribution tree: Now four packages exists
+ (eapi, sslmod, ssldoc, sslcfg, sslsup) and each contains the patches and
+ corresponding files. Especially the EAPI stuff is now stand-alone and
+ doesn't contain any crypto-related stuff.
+
+ *) Fixed version parsing in configure.bat script (Win32)
+
+ *) Fixed default value for SSLCertificateFile directive.
+
+ *) Added real contents for the environment variable mapping. Now all
+ Apache-SSL 1.x and mod_ssl 2.0.x and the most important Stronghold 2.0.x
+ variables (the ones corresponding to certificate DN fields) are mapped
+ to mod_ssl 2.1 variables.
+
+ *) Added on-the-fly mapping for the Apache-SSL 1.x and mod_ssl
+ 2.0.x SSLRequireCipher and SSLBanCipher directives.
+
+ *) Added a useful SSL_CIPHER_EXPORT variable.
+
+ *) Fixed compatibility on-the-fly directive mapping: Now comment and blank
+ lines are correctly recognized by the mapping mechanism so the user no
+ longer gets confusing warnings about obsolete directives when they still
+ occured in comments.
+
+ *) Fixed complex situation where the SSL logfile cannot be opened but the
+ error message should be still logged: to the Apache general error log.
+
+ *) Forward port from 2.0 branch:
+ Make sure the mkcert.sh can only be used by `make certificate' _inside_
+ the Apache source tree.
+
+ Changes with mod_ssl 2.1b8 (30-Oct-1998 to 04-Nov-1998)
+
+ *) Replaced the per-server context Fake-Basic-Authentication stuff with a
+ per-directory mechanism which can be now enabled on-demand and on a
+ per-directory basis with `SSLOptions +FakeBasicAuth'. This way the
+ `Cert-Subject-DN to Basic-Auth-Username' mapping is more useful to the
+ users. The SSLFakeBasicAuth directive was removed. But the mod_ssl
+ compatibility code automatically maps Apache-SSL's `SSLFakeBasicAuth'
+ directive to `SSLOptions +FakeBasicAuth' on-the-fly.
+
+ *) Added support for exporting the client and server certificates
+ (not the CA chain; currently only the end certificates) via `SSLOptions
+ +ExportCertData' in PEM format through the environment variables
+ SSL_SERVER_CERT and SSL_CLIENT_CERT. This way we bloat up the
+ environment with certificate stuff only on demand. Additionally the
+ mod_ssl compatibility code automatically maps Apache-SSL's new
+ `SSLExportClientCertificates' directive to `SSLOptions +ExportCertData'
+ on-the-fly.
+
+ *) Added backward compatibility mappings for environment variables
+ of Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.0 and Stronghold 2.x (where
+ possible). This can be now enabled by the user on-demand via `SSLOptions
+ +CompatEnvVars' - typically inside the .htaccess context of a CGI
+ script. This way we bloat up the environment with compat stuff only on
+ demand.
+
+ *) Added a generic `SSLOptions [+-]option [...]' directive which can be
+ used in the `Options' context, i.e. _everywhere_. It is intended to
+ control various SSL engine parameters.
+
+ *) Enhanced the `make depend' author Makefile target: Now dependencies are
+ also generated for .lo files (DSO object files). This way Make recogizes
+ the dependencies also under the DSO situation.
+
+ *) Now under `make certificate' an interactive prompt is given which asks
+ whether the private key should be encrypted (the default) or not. This
+ way it's a little bit easier to setup test servers, at least for me ;-)
+
+ *) Make sure all filenames can be ServerRoot relative _and_ get checked for
+ existence directly inside the directive handlers (and not under
+ request-time).
+
+ *) Changed per-directory directives SSLRequireSSL and SSLRequire from
+ `FileInfo' to `AuthConfig' context (see AllowOverride), because they are
+ really authentication directives.
+
+ *) Replaced hard-coded r->server->is_virtual and similar checks with more
+ API-like ap_check_cmd_context()-based checks. Also added some more
+ configuration checks to make sure directives cannot be placed into the
+ wrong context.
+
+ *) Added a special kludge for the GCC+DSO situation to libssl.module: Under
+ some platforms (like Solaris) libssl.so has to be explicitly linked
+ against the libgcc.a in order to resolve internal symbols.
+
+ *) Made a lot of coding style cleanups in the ssl_expr_*.c sources.
+
+ *) Fixed a nasty bug in ap_hook_use() and ap_hook_call().
+
+ *) Backport from 2.0 branch:
+ Upgraded to included Thawte Strong Extranet sources (ssl.contrib/sxnet/)
+ from version 1.2.2 to the current 1.2.3.
+
+ *) Backport from Apache-SSL:
+ Incorporation of recent Base64 (uuencode) encoding bugfixes.
+
+ *) Added more hints about EAPI and upgrade problems with DSO/DDLs
+ to the INSTALL and INSTALL.W32 files.
+
+ *) Changed the building of mod_ssl under Win32 from static (.LIB)
+ to dynamic (.DLL), i.e. mod_ssl is now build as a stand-alone Win32 DSO
+ (DLL in Windows terms) containing SSLeay instead of statically linked
+ into the apache.exe binary.
+
+ Changes with mod_ssl 2.1b7 (09-Oct-1998 to 30-Oct-1998)
+
+ *) Fixed DBM access stuff: An invalid argument was given by the
+ NDBM emulation layer of DB under FreeBSD 2.2.6.
+
+ *) Moved all Crypto/SSL stuff from mod_log_config.c, mod_proxy.c and
+ proxy_http.c to the new ssl_engine_ext.c file. Now SSLeay is _ONLY_
+ needed for linking the mod_ssl code itself. There is no more any SSLeay
+ symbol reference outside mod_ssl.
+
+ *) Rewrote the ap_hook mechanism to provide support for loosly coupling
+ modules together, too. Also support is now provided for up to 8
+ arguments in function signatures.
+
+ *) Added support for a SSL Product ID. To the mod_ssl/x.x.x-y.y.y
+ string inside libssl.version you now can append a string <product>/x.x.x
+ and then you get -DSSL_PRODUCT=<hex-value-of-x.x.x>,
+ -DSSL_PRODUCT_NAME="<product>", -DSSL_PRODUCT_VERSION="x.x.x" and a HTTP
+ Server field similar to this one: ``Server: Apache/1.3.3 (Unix)
+ MyStuff/1.0.0 mod_ssl/2.1b7 SSLeay/0.9.0b''. This can be used by RH SWS
+ or the other forthcoming mod_ssl based SSL product to add the version
+ string without patching ;-)
+
+ *) The ca-fix tool is now generated at the `make certificate' step
+ on-demand only because it's only needed here. And when mod_ssl is not
+ enabled this tool cannot be build at all (no SSLeay stuff known).
+
+ *) Created a new ssl_engine_io.c source file which now contains
+ all I/O and buffer related code, i.e. the new EAPI-based stuff plus
+ the Win32/SSLeay functions for buffer I/O.
+
+ *) Because with the help of the EAPI we were now able to add Dynamic Shared
+ Object (DSO) support for mod_ssl. For this the
+ src/modules/ssl/Makefile.tmpl, src/modules/ssl/libssl.module and
+ top-level configure files were adjusted.
+
+ *) Replaced SSL code inside mod_log_config.c with EAPI based
+ code which mainly tries to lookup mod_ssl variables. For this the
+ ssl_engine_vars.c stuff now exports the ssl_var_lookup() function as the
+ "ssl::var::lookup" hook.
+
+ *) Replaced all hard r->connection->client->ssl references with the
+ now loosely based ap_ctx_get(r->connection->client->ctx, "ssl").
+
+ *) SSL patches -> Generic Extended API patches:
+ Completely rewrote the Apache code patches: Instead of patching in SSL
+ specific hooks we now patch in an Extended API which provides mainly the
+ following new features:
+
+ - generic low-level hooks mechanism:
+ ap_hook_{init,kill},
+ ap_hook_{configure,register,unregister},
+ ap_hook_{configured,registered,call}
+
+ - buffer hooks:
+ ap::buff::{read,write,recvwithtimeout,sendwithtimeout}
+
+ - generic context mechanism:
+ ap_ctx_{new,set,get}
+
+ - structure context variables:
+ BUFF->ctx, conn_rec->ctx, request_rec->ctx, server->ctx
+ ap_global_ctx
+
+ - four new high-level module hooks:
+ add_module, remove_module,
+ rewrite_command, new_connection
+
+ - a new function ap_add_config_define() which does what
+ option -D does on the command line.
+
+ *) Added new backward compatibility stuff to ssl_engine_compat.c:
+ We use wildcard configuration directive handlers which are used by us to
+ provide backward compatibility to old obsolete directives via on-the-fly
+ mapping. Those wildcard handlers are an additional (patched in)
+ functionality inside the Apache core, of course ;-)
+
+ *) Renamed snakeoil.{crt,key} to snakeoil-ca.{crt,key} and created a real
+ dummy server certificate/key pair as snakeoil.{crt,key} which is now
+ used under `make certificate TYPE=dummy'. This fixes the recently
+ occured problem where Netscape rejected the dummy certificates because
+ they had the CA flag set.
+
+ *) Fixed CRYPTO_malloc_init() call for Win32 environment.
+
+ *) Added a small stand-alone patch.exe (v2.1) to etc/patch/ for the Win32
+ port. This is now used per default by configure.bat, but the user can
+ override it with --with-patch=FILE as under Unix. This way the patching
+ problems caused by incompatible patch utils should be solved.
+
+ *) Fix pathname seperators (slashes) in Win32's configure.bat script
+ and make configure.bat script accept also Perl 5.003 because 5.004 is
+ not really needed.
+
+ *) Fix `uchar' redefinition problem under AIX.
+
+ *) Now a warning is done when HTTPS is configured on a HTTP port.
+
+ *) Added configuration parameter checks for various the directives.
+
+ Changes with mod_ssl 2.1b6 (01-Oct-1998 to 09-Oct-1998)
+
+ *) Added a --expert option which disables the user hint messages.
+ This can be used by package maintainers to get rid of the final
+ configure messages.
+
+ *) Forward port from 2.0 branch:
+ Recreated the Snake Oil CA certificate: it's now a X.509 v3
+ certificate with the CA flag set and pathlen 0.
+
+ *) Forward port from 2.0 branch:
+ With special permission from Dr Stephen N. Henson his excellent ca-fix
+ program was now added to src/support/ and is used by
+ src/support/mkcert.sh (`make certificate') to fixup the generated
+ certificates. Especially X.509 v3 certificates can be now generated
+ where nsCertType and CA pathlen is correctly set. Additionally `ssleay
+ verify' and `ssleay ... -modulus' checks are performed to make sure the
+ generated certificates are valid.
+
+ *) Forward port from 2.0 branch:
+ Fixed portability problems with prop.sh aux script.
+
+ *) Fixed SSLeay memory setup for Win32 environment.
+
+ *) Upgraded to Apache 1.3.3.
+
+ *) Added a --force option to mod_ssl's configure script to let developers
+ apply mod_ssl also to different Apache versions (especially 1.3.x-dev
+ versions).
+
+ Changes with mod_ssl 2.1b5 (17-Sep-1998 to 01-Oct-1998)
+
+ *) Created a configure.bat script which tries to resemble the
+ Unix configure script. Enhanced the INSTALL.W32 document.
+
+ *) Incorporated the third feeback for the Win32 port from
+ Trung Tran-Duc <trung.tranduc@prague.ixos.cz>.
+
+ *) Incorporated the second cut of the Win32 port from
+ Trung Tran-Duc <trung.tranduc@prague.ixos.cz>. Now the buffer code is
+ finally SSL-aware and a Makefile.nt is provided to build the mod_ssl
+ sources into a DLL.
+
+ *) Replaced some ugly hacking for SSL_CLIENT_CERT_SERIAL
+ by a more safe and straight-foreward BIO based approach.
+ Additionally replaced BIO_ctrl stuff with BIO_pending.
+
+ *) Use a more graceful shutdown approach when the SSL handshake
+ or re-negotiation fails instead of immediately dropping the socket
+ communication.
+
+ *) Cleaned up the log messages and levels.
+
+ *) Fixed the "SSLVerifyType optional_no_ca" situation: The situation
+ has to be checked against more SSLeay errors, because under SSLv3
+ certificate chain loading leads to the presentation of the client CA
+ certs, too. Here SSLeay gives different errors.
+
+ *) Replaced the first cut of the `Recognize HTTP to HTTPS port' stuff with
+ the real (=clean) variant which doesn't use SSLeay internal hex values,
+ etc.
+
+ *) Upgrade from Apache 1.3.1 to Apache 1.3.2
+
+ *) Forward-port from 2.0 branch:
+ Changed HTTPS support in mod_proxy: the ap_proxy_http_handler() function
+ is (illegally because of DSO, of course) called used by third-party
+ modules (like Apache::Proxy). So make make sure we don't change the
+ signature of this function.
+
+ *) Forward-port from 2.0 branch:
+ Added answer to FAQ `Why is client auth broken after upgrading from
+ SSLeay 0.8 to 0.9'. Because of the changed hash algorithm used for the
+ symlinks.
+
+ *) Forward-port from 2.0 branch:
+ Now when `make certificate TYPE=custom' is used the generated
+ ca.crt/ca.key files are installed, too.
+
+ *) Forward-port from 2.0 branch:
+ Make sure mkcert.sh removes temporary files after work.
+
+ *) Enhanced the ssl.crt/Makefile: now <hash>.N extensions are
+ created when conflicts occur and not only <hash>.0
+
+ *) Included a first cut of a port to the Win32 platform by
+ courtesy of Trung Tran-Duc <trung.tranduc@prague.ixos.cz>. Up to know
+ these are only source changes to make it compile under Win32. No support
+ for the build process itself (Makefiles, etc.). But the port already
+ runs on Trung's Windows NT box.
+
+ *) Forward port from 2.0 branch:
+ Enhanced the INSTALL file: Now an example section describes the
+ installation with mod_perl and PHP3. Beside this some bugs were fixed
+ and some more NOTEs were added.
+
+ Changes with mod_ssl 2.1b4 (08-Sep-1998 to 17-Sep-1998)
+
+ *) Now mod_ssl is more friendly to the typical user error: Using HTTP
+ instead of HTTPS to access an SSL-server. In the past the client has
+ just seen an I/O error which often confused a lot of people (including
+ the author of mod_ssl ;-). Now when the SSL_accept of SSLeay fails
+ mod_ssl recognizes the fact that SSLeay already recognized the HTTP
+ protocol. Then mod_ssl does a trick: It does some sort of a request
+ roll-back: It reads the remaining bytes of the request, fakes it with an
+ own error-request, lets Apache process this error-request and finally
+ puts out a HTML error page with a clear description of the problem plus
+ a hyperlink to the HTTPS URL. Currently this check works only with
+ SSLeay 0.9 until the error code determination can be made more general.
+
+ *) Fixed session cache timeout calculation.
+
+ *) Fixed session cache DBM file initialization.
+
+ *) Forward port from 2.0 branch:
+ Make the SSL_HOOK_SetupConnection more robust.
+
+ *) Forward port from 2.0 branch:
+ Added checks to APACI to automatically disable DSO for mod_proxy and
+ mod_log_config when SSL is used (because they have to be built against
+ SSLeay which is not supported in Apache 1.3.1). But we allow the user to
+ explicitly use --enable-shared=.., but then at least he gets a warning.
+ This way we protect the average user but don't hurt the experts.
+ Especially with Apache 1.3.2 the experts want to use
+ --enable-rule=SHARED_CHAIN for linking the DSO's against SSLeay.
+
+ *) Forward port from 2.0 branch:
+ Renamed `aux' directory to `etc' because `aux' is a special name under
+ Windows filesystems (and people at least wanted to extract the stuff
+ under windows).
+
+ *) Forward port from 2.0 branch:
+ Added Thawte's Strong Extranet module (mod_sxnet.c) to
+ the ssl.contrib area. This module can be used together
+ with mod_ssl.
+
+ *) Forward port from 2.0 branch:
+ In order to
+ - reduce the confusion with sslcerts/server.pem and sslkeys/server.pem
+ - provide less-problematic non-self-signed certificates on `make certificate'
+ - prepare for mod_ssl 2.1 and the forthcoming client auth & CA scripts
+ the following cleanups were done:
+
+ 1. The files for the SSL certificate system are now stored in the
+ following thee subdirs of the configuration directory:
+ ssl.crt/ ...... contains the X.509 certificate(s)
+ ssl.csr/ ...... contains the X.509 certificate signing requests(s)
+ ssl.key/ ...... contains the RSA private key(s)
+ Each directory contains a README file which describes the purpose and
+ the contents.
+
+ 2. A ssl.crt/snakeoil.crt and ssl.key/snakeoil.key demo CA certificate
+ and key is distributed with mod_ssl which is used to sign the test
+ certificates the `make certificate' target creates. This avoids the
+ problems with MSIE users because MSIE doesn't like self-signed
+ server-certificates very well.
+
+ 3. A ssl.crt/ca-bundle.crt is now installed (but not enabled!) which
+ contains all 33 CA root certificates of known public CAs. They were
+ extracted from Netscape Communicator 4.06 with my certbundle stuff.
+
+ 4. The `make certificate' command now can create four types
+ of certificate setups:
+ $ make certificate TYPE=dummy (dummy self-signed Snake Oil cert)
+ $ make certificate TYPE=test (test cert signed by Snake Oil CA)
+ $ make certificate TYPE=custom (custom cert signed by own CA)
+ $ make certificate TYPE=official (existing official cert)
+ CRT=/path/to/your.crt
+ [KEY=/path/to/your.key]
+ The default is TYPE=test which is equivalent to the old `make
+ certificate' with the exception that now the generated certificate is
+ no longer a self-signed one. This overview text is also now
+ displayed under built-time. When KEY is missing it is assumed that
+ it's present in the file from CRT and is extracted from there.
+
+ 5. For consistency with 4.) the mod_ssl configure script now
+ uses --with-crt=FILE and --with-key=FILE options. When
+ --with-key is missing it is assumed that it's present in
+ the file from --with-crt and is extracted from there.
+
+ *) Forward port from 2.0 branch:
+ Changed the <VirtualHost> example in the conf/httpd.conf-dist file so it
+ now uses _default_ instead of the server name. This is more portable and
+ totally sufficient for our default configuration where only one virtual
+ host is present.
+
+ *) Fixed INSTALL document: rsaref.a has to be copied to librsaref.a
+
+ *) Totally revised my mod_sslcompat idea because it's not really
+ practical to have the backward compatibility stuff outside the standard
+ mod_ssl code. Another reason is that by including it again into the
+ mod_ssl stuff the code gets easier.
+
+ *) Fixed pass phrase dialog: The server name was always displayed
+ for a new pass phrase.
+
+ *) Added support for the idea of SSL_CLIENT_CERT_CHAIN<N> variables (Mark
+ Shuttleworth, Thawte Consulting) which enables CGI scripts to verify the
+ client certificate chain up to the root:
+ SSL_CLIENT_CERT_CHAIN_0 = end entity cert
+ SSL_CLIENT_CERT_CHAIN_1 = issuer cert
+ SSL_CLIENT_CERT_CHAIN_2 = issuer's issuer cert ...
+ But because of problems with system resource limits this is currently
+ disabled.
+
+ *) Added support for automatically determining the DBM library.
+ When a vendor DBM library is available we now use this one (because
+ typically this is a better and faster one than SDBM). Only when no
+ vendor DBM library could be found we fallback to our built-in SDBM
+ library (which is slow, but portable).
+
+ *) Splitted the mod_ssl.html document into smaller parts for easier
+ reading and maintaining. Same for the CHANGES file. The entries for
+ mod_ssl 2.0.x are now stores in CHANGES.20 while mod_ssl 2.1bx entries
+ are staying in the CHANGES file.
+
+ *) Fixed some pre-processor and variable declaration inconsitencies
+ which forced portability problems under some non-GCC compilers.
+
+ Changes with mod_ssl 2.1b3 (06-Sep-1998 to 08-Sep-1998)
+
+ *) Removed a few unneccessary local buffer usages in the mod_ssl-related
+ code in mod_log_config.c.
+
+ *) Updated the documentation for the recent changes, especially for the new
+ SSLRequire directive and the new provided CGI/SSI variables. I've now
+ also added a new FAQ which tries to explain why SSL cannot be used
+ together with name-based virtual hosts (IP-based virtual hosts have to
+ be used).
+
+ *) Fixed ssl_log() (the function which is used produce all kinds of
+ SSL logfile messages): It failed for messages with "%" because
+ it insecurely used fprintf at some points.
+
+ *) Added --quiet|-q, --verbose|-v and --help|-h options to mod_ssl's
+ `configure' script for controlling the verbosity and for more user
+ friendlyness.
+
+ *) Now the mod_ssl `configure' script creates a `config.status' script as
+ APACI does. This can be used for re-configuring mod_ssl the same way one
+ does it for Apache.
+
+ *) The top-level APACI Makefile now gives a hint for `apachectl start-SSL'
+ (which internally uses the `httpd -DSSL' command).
+
+ *) Now on `make certificate' the hash symlinks in conf/sslcerts/ are
+ generated via the provided Makefile instead of directly linking (which
+ fails under some platforms).
+
+ *) Added boolean expression scanning/parsing/evaluation as ssl_expr_*
+ sources and a new SSLRequire directive which now uses this
+ functionality. This directive can be used in both per-server and
+ per-directory context and has the syntax ``SSLRequire <expr>'' where
+ <expr> is defined as:
+
+ expr ::= "true" | "false"
+ | "!" expr
+ | expr "&&" expr
+ | expr "||" expr
+ | "(" expr ")"
+ | comp
+ comp ::= word "==" word | word "eq" word
+ | word "!=" word | word "ne" word
+ | word "<" word | word "lt" word
+ | word "<=" word | word "le" word
+ | word ">" word | word "gt" word
+ | word ">=" word | word "ge" word
+ | word "in" "{" wordlist "}"
+ | word "=~" regex
+ | word "!~" regex
+ wordlist ::= word
+ | wordlist "," word
+ word ::= digit
+ | cstring
+ | variable
+ | function
+ digit ::= [0-9]+
+ cstring ::= "..."
+ variable ::= "%{" [a-zA-Z][a-zA-Z0-9_-]* "}"
+ function ::= funcname "(" funcargs ")"
+
+ Here for %{XXXX} mostly _all_ possible server variables can be looked
+ up: the standard CGI variables, the SSL CGI variables, the internal
+ variables known from mod_rewrite, etc. pp. The intent is the following:
+ With <expr> one can specifiy an arbitrary complex boolean expression
+ which is evaluated under runtime. When it evaluates to "true" access for
+ the current request is granted. If it evaluates to "false" access for
+ the current request is denied. The main use for this is for flexible
+ certificate screening (because one can lookup all certificate X.509
+ fields via %{SSL_CLIENT_xxx}). But it can be used for other
+ authentication schemes, too.
+
+ This is now the general authentication workhorse. With it we were able
+ to remove the too special SSLRequireCipher and SSLBanCipher directives
+ because their functionalities are just special cases of a boolean
+ expressions:
+
+ SSLRequireCipher C1 C2 ... => SSLRequire %{SSL_CIPHER} in ("C1", "C2", ...)
+ SSLBanCipher C1 C2 ... => SSLRequire not %{SSL_CIPHER} in ("C1", "C2", ...)
+
+ For mod_ssl 2.1.0 (the release version) the above mapping will be done
+ automatically on the fly by the backward-compatibility code.
+
+ *) Removed the __SSLeay prefix inside the source now that the function
+ prefixes are documented in the README file.
+
+ Changes with mod_ssl 2.1b2 (02-Sep-1998 to 06-Sep-1998)
+
+ *) Added the first cut of HTTPS support for the proxy module. This is
+ currently done by making the generic HTTP handler SSL-aware. But it
+ still doesn't provide support for client or server authentication nor
+ does it provide a way to configure it. Later we'll add perhaps
+ SSLProxyXXXXX directives to allow the users to configure the SSL client
+ inside the proxy. But beside this it's full functional. One can use it
+ for proxying https://xxx URLs and also use `ProxyPass https://xxxx'.
+ (the sources of SSLeay's s_client and cURL were my friends ;-)
+
+ *) Replaced old kludges in mod_log_config.c and mod_ssl sources to
+ determine SSL protocol name with the clean SSL_get_version() which
+ already exists in SSLeay 0.8 and 0.9.
+
+ *) As a of the new ssl_var_lookup() the function ssl_ExpandCert() with the
+ old less-portable and unclean parsing stuff (parsed the DN into the
+ fields on a string basis instead of correctly determining the fields
+ from SSLeay structures) was kicked out and the environment annotation is
+ now done with generic variable lookups.
+
+ *) Added a new source file named ssl_engine_vars.c which contains
+ a waterfall approach to expanding arbitrary server+SSL variables. The
+ main function is ssl_var_lookup() which can operate in different
+ contexts. The idea is to resolve information mainly through this
+ function when it's required. Currently the usage is: logfile entries,
+ environment annotation. In the future this will be also used for the
+ SSLRequire directive.
+
+ *) Cleaned up the API command configuration and shortened the code by using
+ #defines. Additionally removed the polymorphic command handling
+ functions with real ones (less pointer arithmetic and preparation for
+ more config-time syntax checks).
+
+ Changes with mod_ssl 2.1b1 (26-Aug-1998 to 02-Sep-1998)
+
+ *) Again completely rewrote the pass phrase handling. This time because the
+ recent dicussions on the sw-mod-ssl mailing lists showed that the direct
+ caching of pass phrases under run-time and the forcing of the
+ administrator to use a single pass phrase for all private key files is
+ not really reasonable. Now the pass phrase handling looks this way:
+
+ 1. A directive `SSLPassPhraseDialog builtin|exec:/path/to/program'
+ is used for configuring the pass phrase dialog. The `builtin' is a
+ terminal based dialog while `exec:/path/to/program' runs an external
+ program (which gets `servername:port' as the argument for which the
+ pass phrase has to be given on stdout).
+
+ 2. The `builtin' terminal dialog is now a lot different:
+ First it detacts wrong pass phrases and gives reasonable error
+ messages and second it uses Holger Reif's maximum-reuse idea for the
+ pass phrase query:
+
+ When a private key file is encrypted, all known pass phrases (at the
+ beginner there are none, of course) are tried. If one of those known
+ pass phrases succeeds no dialog pops up for this file. If none
+ succeeded, another pass phrase is queried and remembered for the next
+ round (where it perhaps can be reused). This scheme allows mod_ssl
+ to be maximum flexible (because for N encrypted private key files you
+ _can_ use N different pass phrases - but then you have to enter all
+ of them, of course) while minimizing the dialog (i.e. when you use a
+ single pass phrase for all N private key files this pass phrase is
+ queried only once).
+
+ 3. After the pass phrase dialog the temporarily remembered pass phrases
+ are immediately wiped out from memory. Instead only the
+ SSLeay-internal representation of the RSA private key and the X.509
+ certificate are stored (as SSLeay already does itself). For this a
+ per-module global configuration pool is used which survives Apache
+ server restarts. This means that Apache will again no longer fall
+ down on restarts.
+
+ *) Beside the per-directory and per-server context configurations
+ we now use a per-module global configuration pool which survives both
+ the Apache API 2nd init round and server restarts. This is done by using
+ an own permanent memory sub-pool. The idea for this tricky approach
+ which came from Philip Gwyn. This global configuration pool now holds
+ _all_ previous global variables (ssl_g_xxx). This way mod_ssl now uses
+ only a single global variable.
+
+ *) Added ssl_engine_ds.c source which contains new data structures (array
+ and table) which are based on Apache's API arrays but can contain
+ arbitrary data (important especially for the tables).
+
+ *) Removed all explicit ap_clear_pool() calls which are no longer
+ necessary because we already got rid of the gcache stuff
+ which required it.
+
+ *) Moved all pass phrase handling stuff into own file ssl_engine_pphrase.c
+ source file
+
+ *) Now the error messages which are duplicated to the general
+ Apache error logfile are prefixed with "mod_ssl:" there to
+ indicate from where they come.
+
+ *) Forward-port from 2.0.6: Added RSAref support for the US-citizens:
+ mod_ssl now automatically recognizes an SSLeay compiled with -DRSAref,
+ automatically finds libRSAglue and librsaref.a or rsaref.a.
+ Additionally beside SSL_BASE now the variable RSA_BASE can be used to
+ select a particular RSAref source tree (if not installed under system
+ locations). This way mod_ssl provides out-of-the-box support for
+ SSLeay+RSAref.
+
+ *) Changed SSLSessionCacheDefault from 0 (none) to a reasonable
+ 300s default.
+
+ *) The socket connection message in the SSL Engine logfile now
+ also displays the Cipher keysizes for even more information
+ about the connection.
+
+ Changes with mod_ssl 2.1b0 (17-Aug-1998 to 26-Aug-1998)
+
+ *) Added a few files to the distribution: First my PGP public key as
+ ssl.contrib/rse.pgp to the distribution so people can use it on
+ forthcoming releases to verify the tarballs signature. Second the files
+ WISHES and TODO which contain the mod_ssl wishlist and the ToDo-list for
+ 2.1.0.
+
+ *) Finally fixed the SSL connection deallocation and removed the old
+ FREE_SESSION stuff.
+
+ *) Added support for annotating SSLeay error messages. Now some
+ of the raw-level SSLeay error messages are automatically annotated with
+ high-level hints. For instance the unmeaningly message
+ ``error:06065064:digital envelope routines:EVP_DecryptFinal:bad
+ decrypt'' now reads ``...routines:EVP_DecryptFinal:bad decrypt [Hint:
+ wrong pass phrase!?]'' etc.
+
+ *) Removed ERR_load_crypto_strings() call because it's already contained in
+ SSL_load_error_string() from SSLeay 0.8 and 0.9. Additionally now a
+ ERR_clear_error() is done after each logfile entry was written to make
+ sure no unread SSLeay errors are kept and occur with later messages
+ (where they would confuse people).
+
+ *) Renamed `SSLLogFile' to `SSLLog' because it isn't always a file,
+ it also can have an argument "|/path/to/filter" and act as
+ a reliable pipe to a logging filter program.
+
+ *) Renamed `SSLRequiredCiphers' directive to `SSLCipherSuite'
+ because the Apache-SSL directivename `SSLRequiredCiphers' was a full
+ accident. Because first it always got intermixed with the per-directory
+ context directive `SSLRequireCipher'. And second this sets not Ciphers
+ which are all `required'. It just sets the Ciphers the clients is
+ permitted to negotiate (the client actually chooses only _one_ Cipher).
+
+ *) Added SSLMutex for mutal expclusion of server process operations.
+ This is currently used only for synchronizing access to the new Session
+ Cache stuff. Three variants can be configured: `SSLMutex none' (no mutex
+ at all - works but risky), `SSLMutex file:/path/to/lockfile' (portable)
+ and `SSLMutex ipcsem' (elegant but not portable).
+
+ *) Moved the backward compatibility stuff into its own module:
+ mod_sslcompat. This module now already provides configuration directive
+ compatibility for both Apache-SSL and Sioux. More (Stronghold?) can be
+ add later, too. Additionally a mod_sslcompat.html document was written
+ which described the provided configuration directive mapping.
+
+ *) Split the mod_ssl sources from its large 70KB file into smaller chunks,
+ which are now mainly named accoring to the logical modules they contain.
+ This way the source inside src/modules/ssl/ is easier to overview. Just
+ one minor drawback: We lose a lot of nice `static' and have to prefix
+ really _all_ functions with `ssl_' now.
+
+ *) Replaced the gcache stuff from Apache-SSL days and replaced it
+ by a more simple but even more flexible approach. Now the new
+ `SSLSessionCache' directive replaces `SSLCacheServerPath' and
+ `SSLCacheServerPort'. The SSLSessionCacheTimeout remains and has the
+ old semantics. So, where is the difference? The old gcache stuff was
+ like this: An extra process (ssl_gcache) was running in parallel to the
+ httpd server processes and listening to a socket. Through SSLeay
+ callbacks the internal SSLeay caches of all server processes were synced
+ with this global cache. For this socket connections were established.
+ The drawback of this approach were:
+
+ 1. The nasty fiddling with the extra child process was totally buggy
+
+ 2. The gcache program itself used another local memory cache. This
+ was totally unnecessary because SSLeay already caches the stuff in a
+ local memory cache. So, under Apache-SSL three cache layers were used
+ (1: SSLeay internal, 2: gcache internal, 3: gcache external) while
+ layer 2 is not needed.
+
+ So the intent now was to replace this with a better solution. The idea
+ came from Stronghold: We either cache the information never (the
+ default), in a hashfile on the local disk (the portable variant -
+ already implemented) or even in a hash structure inside a shared memory
+ segment ( (non-portable, but fast and elegant - still not implemented,
+ only stubs were created to plug this in later).
+
+ *) CORRECTLY SOLVE THE PASS PHRASE DIALOG PROBLEM (the problem is that
+ Apache detaches from the terminal before the SSLeay pass phrase dialog
+ pops up). First I got rid of the ugly and unsuccessful filedescriptor
+ hacks Ben added recently to Apache-SSL because they do not work under
+ all platforms as expected. Second I re-ordered the control flow to allow
+ the following processing:
+
+ Now at the 1st round of the Apache API init cycle the servers are
+ scanned for certificate and key files and the first one which uses an
+ encrypted key forces the pass phrase dialog to pop up. This dialog is
+ either an interactive builtin terminal dialog (`SSLPassPhraseDialog
+ builtin' - which is similar to SSLeay default dialog) or can be driven
+ in batch by a filtering program which is run once and has to provide the
+ pass phrase on stdout (`SSLPassPhraseDialog /path/to/program'). After
+ this the pass phrase is _temporarily_ stored in memory for use later in
+ the 2nd round of the Apache API init cycle. Now additionally this pass
+ phrase can be kept in memory (`SSLPassPhraseCaching on') for forthcoming
+ server restarts (`kill -HUP') or is explicitly wiped out from memory
+ (`SSLPassPhraseCaching off' - for the paranoid users).
+
+ The following combinations are possible:
+
+ 1. THE SMART DEFAULT VARIANT:
+ `SSLPassPhraseDialog builtin' + `SSLPassPhraseCaching on':
+ This is the default which is reasonable for most of the users. This
+ way on Apache startup time the pass phrase is requested on the
+ terminal but kept in memory for all forthcoming restarts.
+
+ 2. THE THEORY VARIANT:
+ `SSLPassPhraseDialog builtin' + `SSLPassPhraseCaching off':
+ This combination leads to a server fall-down on any occuring restarts
+ because the terminal dialog _cannot_ be done at restart time (Apache
+ is already detached). So, this combination is only interesting in
+ theory but should be avoided because its not really useful in
+ practice.
+
+ 3. THE BATCH VARIANT:
+ `SSLPassPhraseDialog /path/to/program' + `SSLPassPhraseCaching on':
+ This is for users who want to remote control the Apache startup or
+ make it automatic by controlling the dialog from within a program.
+ This program is run only once at startup. Then the pass phrase is
+ kept in memory for forthcoming restarts.
+
+ 4. THE PARANOIA VARIANT:
+ `SSLPassPhraseDialog /path/to/program' + `SSLPassPhraseCaching off':
+ This is for the really paranoid users who want avoid any pass phrase
+ caching. Instead both on startup and restart time the pass phrase has
+ to be provided by an external program.
+
+ *) The SSL logfile is now placed in the main server instead of the virtual
+ host because its actually a global logfile, even when it could be used
+ only inside a virtual server.
+
+ *) The expensive operation of generating the temporary RSA key is now done
+ before Apache forks the server processes. This speeds up the startup
+ phase a little bit.
+
+ *) Added new SSLCACertificateReqFile directive which defaults to the value
+ of SSLCACertificateFile. It sets the all-in-one file where one can
+ assemble the Certificates of Certification Authorities (CA) whose
+ servers you deal with. These are optionally used by the clients for
+ SSLv3 Server Authentication to speedup processing. The file is requested
+ by the client via the "SSLv3 write certificate request A" for loading
+ intermediate CA certificates in the certificate chain (only SSLv3). It
+ is simply the concatenation of the various PEM-encoded certification
+ files, in order of preference.
+
+ *) Inlined some functions like init_SSLeay() and init_VerifyType() because
+ they were really small functions and only used once in mod_ssl. These
+ were stand-alone functions in Apache-SSL without real need.
+
+ *) Made `SSLEnable'/`SSLDisable' directives obsolete by adding the simpler
+ `SSEngine on|off'. The old directives are now deprecated but still can
+ be used for backward-compatibility with Apache-SSL. Additionally the
+ default is now `SSLEngine off' (formerly `SSLDisable') instead of the
+ Apache-SSL default of `SSLEngine on'. This breaks a little bit with
+ Apache-SSL semantics, but doesn't hurt as much as it sounds. Because
+ people run SSL inside a virtual hosts and thus already have a SSLDisable
+ in their main (non-SSL) server. The difference is just that with mod_ssl
+ one no longer has to add SSLDisable to all non-SSL virtual hosts (which
+ is nasty). OTOH SSL is an additional feature, so the logic of "disabled
+ per default and have to be enabled explicity" is more useful and what is
+ expected.
+
+ *) The "SSL rubbish logfile" of Apache-SSL was now replaced by real
+ dedicated SSL logfile which contains no longer "rubbish". For this the
+ logging mechanism in mod_ssl was completely re-written from scratch and
+ now looks like this:
+
+ 1. `SSLogFile <file>' is optional
+ 2. `SSLogFile /dev/null' disables the logging _without_ overheads
+ 3. `SSLLogLevel <level>' controls the degree of verbosity in SSLLogFile
+ 4. `SSLogLevel none' disables the logging _without_ overheads and is the
+ default.
+ 5. Log messages of type `error' are _always_ duplicated to
+ the Apache general error logfile, even under `SSLLogLevel none'.
+ 6. The maximum logging can be now achieved by using `SSLLogLevel debug'.
+
+ Additionally obsolete logging stuff from Apache-SSL was removed from the
+ source code. Finally the logfiles in the provided default config were
+ changed: ssl_log is now the dedicated SSL protocol logfile (SSLLogFile)
+ while the custom logfile (CustomLog) containing only one line per
+ request is now named ssl_req_log.
+
+ ____ ___
+ |___ \ / _ \
+ __) || | | |
+ / __/ | |_| |
+ ___ |_____(_)___/ __________________________________________
+
+ Changes with mod_ssl 2.0.16 (07-Nov-1998 to 09-Nov-1998)
+
+ *) Fixed documenation: SSLRequireSSL can be used in .htaccess
+ files when the `FileInfo' context is enabled for it.
+
+ *) Revised my recent RSAref fix to INSTALL file a little bit.
+
+ *) Backport of an Apache-SSL bugfix:
+ Fix file-descriptor leak for stderr.
+
+ Changes with mod_ssl 2.0.15 (01-Nov-1998 to 07-Nov-1998)
+
+ *) Fixed some long-standing inconsistencies in mod_ssl.html
+
+ *) Now SSLVerifyDepth defaults to 1 and this means the client certificate
+ has to be signed directly by the root CA. The verify depth now is the
+ max number of CAs which are checked: 0 = self-signed only, 1 =
+ self-signed or signed by root-CA, 2 = signed by root-CA or signed by a
+ CA which is signed by the root-CA, etc.
+
+ *) Now SSLSessionCacheTime defaults to 300s.
+
+ *) Fixed RSAref instructions in INSTALL file and added more support for
+ implicitly finding the RSA_BASE to the libssl.module script.
+
+ *) Backport from 2.1 branch:
+ Now under `make certificate' an interactive prompt is given which asks
+ whether the private key should be encrypted (the default) or not. This
+ way it's a little bit easier to setup test servers, at least for me ;-)
+
+ *) Fixed SSLRequiredCiphers: The server configuration entry wasn't
+ correctly merged internally which lead to the effect that it got
+ ignored.
+
+ Changes with mod_ssl 2.0.14 (09-Oct-1998 to 01-Nov-1998)
+
+ *) Backport from 2.1 branch:
+ Renamed snakeoil.{crt,key} to snakeoil-ca.{crt,key} and created a real
+ dummy server certificate/key pair as snakeoil.{crt,key} which is now
+ used under `make certificate TYPE=dummy'. This fixes the recently
+ occured problem where Netscape rejected the dummy certificates because
+ they had the CA flag set.
+
+ *) Upgraded to included Thawte Strong Extranet sources (ssl.contrib/sxnet/)
+ from version 1.2.2 to the current 1.2.3.
+
+ *) Backport from Apache-SSL:
+ Incorporation of recent Base64 (uuencode) encoding bugfixes.
+
+ *) Backport from 2.1 branch:
+ Fixed the "SSLVerifyType optional_no_ca" situation: The situation
+ has to be checked against more SSLeay errors, because under SSLv3
+ certificate chain loading leads to the presentation of the client CA
+ certs, too. Here SSLeay gives different errors.
+
+ *) Fixed documentation of SSL_CLIENT_I<x509> and SSL_SERVER_I<x509>
+ environment variables.
+
+ *) Fixed mod_proxy source for the situation where
+ no --enable-module=ssl is used.
+
+ *) Make sure the stand-alone ssl_gcache program compiles
+ correctly even under SunOS where no strerror() exists.
+
+ *) Backport from 2.1 branch:
+ Fix "uchar" redefinition problem under AIX.
+
+ Changes with mod_ssl 2.0.13 (02-Oct-1998 to 09-Oct-1998)
+
+ *) Fixed some more race conditions in ssl_gcache, cleaned
+ up the error logging and namespace in ssl_gcache.
+
+ *) Overtaken the SIGPIPE handling patch from Apache-SSL 1.27
+
+ *) Recreated the Snake Oil CA certificate: it's now a X.509 v3
+ certificate with the CA flag set and pathlen 0.
+
+ *) With special permission from Dr Stephen N. Henson his excellent ca-fix
+ program was now added to src/support/ and is used by
+ src/support/mkcert.sh (`make certificate') to fixup the generated
+ certificates. Especially X.509 v3 certificates can be now generated
+ where nsCertType and CA pathlen is correctly set. Additionally `ssleay
+ verify' and `ssleay ... -modulus' checks are performed to make sure the
+ generated certificates are valid.
+
+ *) Upgraded to Apache 1.3.3.
+
+ *) Fixed again some RSAref hints in the INSTALL file.
+
+ *) Fixed `SSLLogFile /dev/null' situation: it now works as expected: No
+ logging is done. But not by writing to /dev/null. Instead no logging at
+ all is done, of course.
+
+ Changes with mod_ssl 2.0.12 (23-Sep-1998 to 02-Oct-1998)
+
+ *) Cleaned up gcache stuff again and fixed a few problematic things
+ by adding extra runtime checks. Now gcache should no longer dump core.
+ At least I've now found no more bug...
+
+ *) Changed gcache communication from TCP-sockets to Unix domain
+ sockets in default configuration (httpd.conf-dist), because
+ this is more reliable and safe.
+
+ *) Incorporated reasonable change from Apache-SSL 1.25:
+ Allow up to three retries at the pass phrase prompt.
+
+ [The other main change in Apache-SSL 1.25 (the client cert export via
+ env variables) is intentionally not overtaken for mod_ssl because of
+ three reasons: 1. it's a too large patch which is not acceptable for the
+ stable mod_ssl 2.0 branch; 2. it still has some flaws Ben is still
+ fixing for 1.26; 3. I'm still not convinced that providing complete
+ Base64 encoded certs (greated than 1KB) via a set of environment
+ variables is really reasonable (because of performance and system
+ resource limits). Instead I'm still seeking for a real on-demand
+ solution, but for mod_ssl 2.1, of course.]
+
+ *) Backport from 2.1 branch:
+ Added a --force option to mod_ssl's configure script to let developers
+ apply mod_ssl also to different Apache versions (especially 1.3.x-dev
+ versions).
+
+ *) Fixed portability problems with prop.sh aux script.
+
+ *) Fixed gcache expiring: A static variable was not initialized.
+
+ *) Fixed a few inconsistencies in the mod_ssl.html document.
+
+ *) Fixed RSAref installation instructions in INSTALL file and a little big
+ in libssl.module which caused problems for RSAref installations, too.
+
+ *) Fixed mod_perl part in INSTALL file.
+
+ *) Changed some Apache-SSL wordings in mod_ssl.html on request
+ by Ben Laurie.
+
+ Changes with mod_ssl 2.0.11 (17-Sep-1998 to 23-Sep-1998)
+
+ *) Upgrade from Apache 1.3.1 to Apache 1.3.2
+
+ *) Back-port from 2.1:
+ Enhanced the ssl.crt/Makefile: now <hash>.N extensions are
+ created when conflicts occur and not only <hash>.0
+
+ *) Changed HTTPS support in mod_proxy: the ap_proxy_http_handler() function
+ is (illegally because of DSO, of course) called used by third-party
+ modules (like Apache::Proxy). So make make sure we don't change the
+ signature of this function.
+
+ *) Added answer to FAQ `Why is client auth broken after upgrading from
+ SSLeay 0.8 to 0.9'. Because of the changed hash algorithm used for the
+ symlinks.
+
+ *) Now when `make certificate TYPE=custom' is used the generated
+ ca.crt/ca.key files are installed, too.
+
+ *) Make sure mkcert.sh removes temporary files after work.
+
+ *) Enhanced the INSTALL file: Now an example section describes the
+ installation with mod_perl and PHP3. Beside this some bugs were fixed
+ and some more NOTEs were added.
+
+ Changes with mod_ssl 2.0.10 (13-Sep-1998 to 17-Sep-1998)
+
+ *) Temporarily added a fix from 1.3.2-dev for APACI's configure script to
+ allow the `Group' directive to be adjusted correctly even under Linux
+ boxes. Without this Linux users always have to fix the `Group' directive
+ manually which is nasty.
+
+ *) Added checks to APACI to automatically disable DSO for mod_proxy and
+ mod_log_config when SSL is used (because they have to be built against
+ SSLeay which is not supported in Apache 1.3.1). But we allow the user to
+ explicitly use --enable-shared=.., but then at least he gets a warning.
+ This way we protect the average user but don't hurt the experts.
+ Especially with Apache 1.3.2 the experts want to use
+ --enable-rule=SHARED_CHAIN for linking the DSO's against SSLeay.
+
+ *) Make the SSL_HOOK_SetupConnection a little bit more robust.
+
+ *) Avoid confusing "unable to load 'random state'" messages
+ from `ssleay genrsa' command.
+
+ *) Renamed `aux' directory to `etc' because `aux' is a special name under
+ Windows filesystems (and people at least wanted to extract the stuff
+ under windows).
+
+ *) Fix top-level Makefile.tmpl: replace `make' with `$(MAKE)'
+ and grep out SSL_PROGRAM variable from src/Makefile.config directly
+ (instead of running a subtarget) to avoid problems with Make output
+ messages. This especially fixed the `make install' problems under Linux
+ platforms (where GNU Make is used which gives nasty messages).
+
+ *) Update INSTALL file: Use apachectl and add hint to
+ the Apache general error logfile.
+
+ *) Allow ServerRoot relative path for SSLCertificateFile.
+
+ Changes with mod_ssl 2.0.9 (12-Sep-1998 to 13-Sep-1998)
+
+ *) Portability fixes: The ssl.crt/Makefile didn't work on
+ all platforms because of braindead shells and the mkcert.sh script
+ failed to use /dev/random because this device doesn't work as expected
+ on some platforms.
+
+ Changes with mod_ssl 2.0.8 (09-Sep-1998 to 12-Sep-1998)
+
+ *) Make the whole build process (including `make certificate')
+ independent of any installed ssleay.cnf file (some systems have it in
+ non-standard locations and we don't need it any longer at all).
+
+ *) Added Thawte's Strong Extranet module (mod_sxnet.c) to
+ the ssl.contrib area. This module can be used together
+ with mod_ssl.
+
+ *) Fixed hash symlink generation under `make certificate'
+ and `make install' for the cases where `ssleay' is not in $PATH.
+
+ *) Fixed INSTALL document: rsaref.a has to be copied to librsaref.a
+
+ *) Added more information to the mod_ssl.html file about the
+ SSLCACertificateFile: It's also used implicitly for the "SSLv3 write
+ certificate request A" where it's contents is sent to the client to
+ enable him to verify a possible issuer chain on the server certificate.
+
+ *) Fixed a few bugs in the new mkcert.sh script, enhanced it's
+ dialogs and added a lot error checks.
+
+ Changes with mod_ssl 2.0.7 (29-Aug-1998 to 09-Sep-1998)
+
+ *) Changed the <VirtualHost> example in the conf/httpd.conf-dist
+ file so it now uses _default_ instead of the server name. This is more
+ portable and totally sufficient for our default configuration where
+ only one virtual host is present.
+
+ *) Backport from 2.1b branch: Now the mod_ssl `configure' script creates a
+ `config.status' script as APACI does. This can be used for
+ re-configuring mod_ssl the same way one does it for Apache.
+
+ *) Backport from 2.1b branch: Added the first cut of HTTPS support for the
+ proxy module. This is currently done by making the generic HTTP handler
+ SSL-aware. But it still doesn't provide support for client or server
+ authentication nor does it provide a way to configure it. Later we'll
+ add perhaps SSLProxyXXXXX directives to allow the users to configure the
+ SSL client inside the proxy. But beside this it's full functional. One
+ can use it for proxying https://xxx URLs and also use `ProxyPass
+ https://xxxx'. (the sources of SSLeay's s_client and cURL were my
+ friends ;-)
+
+ *) In order to
+ - reduce the confusion with sslcerts/server.pem and sslkeys/server.pem
+ - provide less-problematic non-self-signed certificates on `make certificate'
+ - prepare for mod_ssl 2.1 and the forthcoming client auth & CA scripts
+ the following cleanups were done:
+
+ 1. The files for the SSL certificate system are now stored in the
+ following thee subdirs of the configuration directory:
+ ssl.crt/ ...... contains the X.509 certificate(s)
+ ssl.csr/ ...... contains the X.509 certificate signing requests(s)
+ ssl.key/ ...... contains the RSA private key(s)
+ Each directory contains a README file which describes the purpose and
+ the contents.
+
+ 2. A ssl.crt/snakeoil.crt and ssl.key/snakeoil.key demo CA certificate
+ and key is distributed with mod_ssl which is used to sign the test
+ certificates the `make certificate' target creates. This avoids the
+ problems with MSIE users because MSIE doesn't like self-signed
+ server-certificates very well.
+
+ 3. A ssl.crt/ca-bundle.crt is now installed (but not enabled!) which
+ contains all 33 CA root certificates of known public CAs. They were
+ extracted from Netscape Communicator 4.06 with my certbundle stuff.
+
+ 4. The `make certificate' command now can create four types
+ of certificate setups:
+ $ make certificate TYPE=dummy (dummy self-signed Snake Oil cert)
+ $ make certificate TYPE=test (test cert signed by Snake Oil CA)
+ $ make certificate TYPE=custom (custom cert signed by own CA)
+ $ make certificate TYPE=official (existing official cert)
+ CRT=/path/to/your.crt
+ [KEY=/path/to/your.key]
+ The default is TYPE=test which is equivalent to the old `make
+ certificate' with the exception that now the generated certificate is
+ no longer a self-signed one. This overview text is also now
+ displayed under built-time. When KEY is missing it is assumed that
+ it's present in the file from CRT and is extracted from there.
+
+ 5. For consistency with 4.) the mod_ssl configure script now
+ uses --with-crt=FILE and --with-key=FILE options. When
+ --with-key is missing it is assumed that it's present in
+ the file from --with-crt and is extracted from there.
+
+ *) Removed unnecessary DEBUG_XXXX stuff which gets replaced in
+ mod_ssl 2.1b with ssl_log().
+
+ *) Backport from 2.1b branch: Now on `make certificate' the hash symlinks
+ in conf/sslcerts/ are generated via the provided Makefile instead of
+ directly linking (which fails under some platforms).
+
+ *) Backport from 2.1b branch: The top-level APACI Makefile now gives a hint
+ for `apachectl start-SSL' (which internally uses the `httpd -DSSL'
+ command).
+
+ *) Backport from 2.1b branch: Replaced old kludges in mod_log_config.c
+ to determine SSL protocol name with the clean SSL_get_version() which
+ already exists in SSLeay 0.8 and 0.9. And removed a few unneccessary
+ local buffer usages in the mod_ssl-related code in mod_log_config.c.
+
+ *) Merge in changes from Apache-SSL 1.23 to 1.24: Cache private keys over
+ init rounds and restarts. This means you now can use enrypted private
+ key files (where pass phrases are needed to read them in) and both
+ survive the terminal detachment and the restart rounds of Apache. This
+ is achieved by using an own permanent memory pool which survives server
+ restarts and holds the private key files. Remember that this is _not_ a
+ backported full-featured pass phrase handling from mod_ssl 2.1b.
+ Instead it's exactly the easier handling from Apache-SSL 1.24. Because
+ the mod_ssl 2.1b pass phrase handling is too complex to be backported to
+ the 2.0 branch. At least it could lead to side-effects in 2.0 which I
+ want to avoid.
+
+ *) Fixed some pre-processor and variable declaration inconsitencies
+ which forced portability problems under some non-GCC compilers.
+
+ *) Minor correction to the README, SUPPORT, etc. files.
+
+ Changes with mod_ssl 2.0.6 (25-Aug-1998 to 29-Aug-1998)
+
+ *) Added RSAref support for the US-citizens: mod_ssl now automatically
+ recognizes an SSLeay compiled with -DRSAref, automatically finds
+ libRSAglue and librsaref.a or rsaref.a. Additionally beside SSL_BASE
+ now the variable RSA_BASE can be used to select a particular RSAref
+ source tree (if not installed under system locations). This way mod_ssl
+ provides out-of-the-box support for SSLeay+RSAref.
+
+ *) Back-port from 2.1: Replaced assert()ions with non-process-terminating
+ runtime checks and removed some unnecessary debugging stuff.
+
+ *) Back-port from 2.1: Finally fixed the SSL connection deallocation and
+ removed the old FREE_SESSION stuff by back-porting the change from the
+ 2.1 track.
+
+ *) Added PGP public key as ssl.contrib/rse.pgp to the distribution
+ so people can use it on forthcoming releases to verify the tarballs
+ signature.
+
+ *) Taken over a change between Apache-SSL 1.22 and 1.23: Move the call for
+ launching the gcache program to a later point in processing.
+
+ *) Back-port from 2.1: Removed ERR_load_crypto_strings() call because it's
+ already contained in SSL_load_error_string() from SSLeay 0.8 and 0.9.
+
+ Changes with mod_ssl 2.0.5
+
+ *) Fix per-server configuration structure merging.
+
+ *) Added support for reliable piped logs to SSLLogFile directive which can
+ be used to plug-in a filter program which receives the logfile entries.
+
+ *) Removed per-server check for valid SSLVerifyClient argument because in
+ mod_ssl it's no longer possible that an invalid argument can exit under
+ run-time because the argument is already validated under config-time.
+
+ *) Removed DEBUG_SSLEAY stuff from Apache-SSL because SSL_debug() does no
+ longer exist in SSLeay 0.9.x.
+
+ *) Added one more digit at the MOD_SSL define value to indicate beta or
+ release versions. The scheme now is the following (only important when
+ one has to check against the version of an SSL-aware Apache from within
+ an own module): <version>.<revision><type><level> where <version>,
+ <revision> and <level> are numbers between 0 and 99 while <type> is
+ either `b' (for beta versions) or `.' (for release versions). From
+ this the MOD_SSL define is created similar to this command:
+
+ sprintf("%d%02d%c%02d", <version>, <revision>,
+ <type> == `b' ? 0 : 1, <level>);
+
+ As an example: the beta version 2.1b3 has MOD_SSL=201003 while
+ the release version 2.1.4 has MOD_SSL=201104.
+
+ *) Fixed typos in mod_ssl.html document.
+
+ *) Fixed typos in mod_ssl.c source.
+
+ *) Created two buttons similar to the existing "Includes SSLeay
+ encryption software" button: One for Apache ("Powered by Apache
+ Webserver Software") and one for mod_ssl ("Secured by mod_ssl
+ Interface"). These are now put on the default frontdoor webpage at
+ install time.
+
+ *) Removed half done DSO-related stuff from Apache-SSL because it's
+ useless. Why? Because mod_ssl currently _cannot_ be build as a DSO,
+ because:
+
+ 1. Because SSLeay is directly called from within Apache's buffer code
+ (SSL_write/SSL_read) because the Apache API lacks a hook for this.
+ But direct calls from the core to modules and libraries is tabu under
+ DSO situation.
+
+ 2. Because mod_ssl is directly called from within Apache's main loop
+ for setting up the SSL protocol after the socket connection was
+ established because the Apache API lacks a hook for this. But
+ direct calls from the core to modules and libraries is tabu under
+ DSO situation.
+
+ 3. Because the pass-phrase dialog can be done only before Apache
+ detaches from the terminal. But the general order is this:
+
+ a) ap_read_config (where LoadModule is done)
+ b) ap_init_modules (where mod_ssl can do the pass-phrase dialog)
+ c) detaching
+ d) ap_read_config (where DSOs are unloaded and reloaded)
+ e) ap_init_modules (where mod_ssl no longer can do the dialog)
+
+ When mod_ssl is not a DSO it can do the pass-phrase dialog in step
+ b), but when it's a DSO (assuming 1. and 2. are already solved) then
+ it cannot preserve information between b) and e) because it is
+ unloaded in the meantime.
+
+ So, for DSO the Apache kernel has to be bloated up with some more
+ features. Currently I want to avoid this because DSO is still not not
+ really worth the effort (there are other things which can be improved in
+ mod_ssl first).
+
+ Changes with mod_ssl 2.0.4
+
+ *) Added VERSIONS file to the distribution which contains the
+ release date and version numbers for reference.
+
+ *) Make sure the server.pem certificate files in sysconfdir/sslcerts/ is
+ not overridden on APACI re-installs. Now a message simular to other
+ existing APACI messages informs the user that his certificates are
+ preserved.
+
+ *) Added support for SSL_BASE=SYSTEM which means that SSLeay header files,
+ libraries, configuration and binary files were not searched under a
+ single SSL_BASE root. Instead they are searched inside the common system
+ directories like /etc/, /usr/etc, /lib, /usr/lib, /usr/local/lib,
+ /usr/include, etc. pp.
+
+ *) Replaced even more old Apache-SSL relicts to make mod_ssl really secure,
+ stable and robust: sprintf -> ap_snprinf, srcpy -> ap_cpystrn, fopen ->
+ ap_pfopen.
+
+ *) Added U.S. export law information to SUPPORT file to make sure
+ mailing list users inside the United States remember the U.S. export law.
+
+ Changes with mod_ssl 2.0.3
+
+ *) Fixed a view ap_log_error() calls where APLOG_NOERRNO was missing.
+
+ *) For better compatibility with Stronghold and because it is really more
+ intuitive we now also provide the CustomLog directives %{subjectdn}c and
+ %{issuerdn}c: The (more intuitive) %{subjectdn}c replaced the (confusing)
+ %{clientcert}c directive (although %{clientcert}c is still accepted as an
+ alias). And the %{issuerdn}c was added (with the alias %{cacert}c :-( ).
+ This way custom logfiles now can contain the certificate issuer as well.
+
+ *) For better configuration sharing with Stronghold (which uses
+ the name mod_ssl.c for its module, too) mod_ssl now defines not only the
+ C Pre-Processor define MOD_SSL, it now also pre-defines the Apache
+ configuration define MOD_SSL. This now can be used with <IfDefine
+ MOD_SSL>..</IfDefine> sections without the need to startup Apache
+ explicitly with an -DSSL or -DMOD_SSL option.
+
+ *) ANSI C doesn't allow one to forward declare an array variable without
+ specifying the actual array size. GCC didn't complain, but other vendor
+ compilers (like /bin/cc under IRIX) do. This is now fixed by re-ordering
+ the definitions in the code to make the forward declaration not
+ necessary.
+
+ *) Let APACI adjust the port 443 to 8443 when installing under a non-root
+ UID similar to what Apache already does with adjusting port 80 to 8080.
+
+ *) Fix patch tool location for the situation where the user
+ has to compile manually the stuff because of platforms errors.
+
+ *) Incorporated changes from Apache-SSL 1.20 to 1.21:
+ Was only a single register_cleanup -> ap_register_cleanup rename,
+ because all other changes were either already in mod_ssl or will be done
+ totally different with the next mod_ssl changes (for instance the
+ logging stuff which gets replaced by a more improved version the next
+ days - because Ben's idea to now log anything to Apache's error_log
+ sounds not reasonable to me).
+
+ *) Fixed variable arg usage in logging functions: va_end was missing.
+
+ Changes with mod_ssl 2.0.2
+
+ *) Make egrep arguments more safe because they failed under
+ Solaris and other platforms.
+
+ *) Replaced basename() and dirname() functions in aux/patch/backupfile.c
+ to avoid conflicts with glibc2's versions of these functions.
+
+ *) Removed ssl.contrib/ssleay.diff because it was only needed
+ for the temporary broken SSLeay 0.9.0b which was staying around on the
+ net.
+
+ *) Now the sslcerts dir is created with permissions 755 and sslkeys
+ with 700 for security reasons.
+
+ *) Now the FAQ inside the mod_ssl.html document has corresponding ToC
+ entries. Additionally now the question "What is different between mod_ssl
+ and Apache-SSL" is tried to be answered. And a few hints were added on how
+ to check HTTPS manually.
+
+ *) Make the building of the 'patch' tool more robust by checking for
+ success and providing a log of the failure. Additionally in case of
+ problems the user now can use a --with-patch option to force the usage
+ of a vendor patch program.
+
+ *) Cleaned up the gcache stuff even more: reduced #includes
+ to minimum and moved some stuff to the header file.
+
+ *) Cleaned up the httpd.conf-dist entries for SSL.
+
+ *) Cleanup mod_log_config.c patch and fixed %{version}c construct:
+ It now says "SSLX" even under SSLeay 0.8.0.
+
+ *) Misc. doc ajdustments: Fixed a few comment typos in apache.patch file;
+ Added Announcement text as ANNOUNCE file to distribution; Fixed
+ hyperlinks in mod_ssl.html document and added more useful hyperlinks to
+ the README file.
+
+ *) Replaced a lot of C constructs into shorthand defines to
+ make the code even more readable and reviewable:
+ o ``strcmp ... == 0'' -> ``strEQ''
+ o ``\0'' -> ``NUL''
+ o ``ap_get_module_config(...)'' -> ``myXXConfig''
+ o ``ap_overlay_tables'' -> ``cfgMergeTable''
+
+ *) Fixed dependencies in src/modules/ssl/Makefile.tmpl
+
+ *) Add Ben Laurie's copyright message to gcache sources, even when Ben
+ missed it here. It's from Ben, so his copyright applies and credit has
+ to be given.
+
+ Changes with mod_ssl 2.0.1
+
+ *) Minor documentation updates.
+
+ *) Now the ssl.patch/apache.diff file is named ssl.patch/apache.patch
+ and contains descriptive annotations for each patches file. This way
+ even the patches are easier reviewable.
+
+ *) The configure patch was not 100% correct: The SSL has not to be
+ disabled for --enable-module=most (where it should be enabled, of
+ course). Instead it has to be disabled automatically for
+ --enable-shared=max.
+
+ Changes with mod_ssl 2.0.0
+
+ *) Added "SSL library type" message to the configuration process
+ to inform the user how we recognized the SSLeay location.
+
+ *) Added support for conf/sslkeys/ directory both to configure
+ script, Makefile.tmpl and default config files. Additionally now on
+ "make install" the hash symlinks are created and a dummy server cert
+ file is skipped.
+
+ *) Fixed prop.sh script.
+
+ *) Cleaned up mod_ssl.html document for release.
+
+ *) Cleaned up the README file and added a situation report
+ about the author conflict with Ben.
+
+ *) Incorporated changes from Apache-SSL 1.19 to 1.20:
+ - Do a cleanup before starting gcache.
+ - Make gcache die when httpd dies.
+ This failing in previous versions appears to be a bug in Apache.
+ - Document the biz with passphrases and sleep.
+ - Do Apache-SSL on inetd connections.
+ ALL OTHER CHANGES BETWEEN APACHE-SSL 1.19 AND 1.20 WERE ALREADY DONE
+ FOR MOD_SSL IN THE PAST BY Ralf S. Engelschall. Because it seems Ben
+ just has drawn level Apache-SSL with the mod_ssl pre-release I sent to
+ him last week. Hmmmm...
+
+ *) Minor cleanups to README and mod_ssl.html file.
+
+ *) Now create the CHANGES.SSL in <apache>/src/ instead in <apache>/.
+
+ *) Moved patch to a subdir aux/patch/ and added prop.sh for
+ a visual process indicator while building the aux tools.
+
+ *) Slightly fixed the configure scripts messages
+
+ *) Added support for checking the Apache version: Now mod_ssl can
+ only be applied to the correct matching Apache source tree.
+
+ *) Added configurable support for mod_ssl version strings: Now
+ a libssl.version file is created inside src/modules/ssl/ which holds
+ the mod_ssl version. From this the libssl.module script creates a
+ MOD_SSL_VERSION define holding the value as a string ("X.Y.Z") and a
+ MOD_SSL define holding the value with a zero-spaced numerical value
+ (XYYZZ). This way the mod_ssl received the string for the Server field
+ and other modules can check against certain mod_ssl versions via #ifdef
+ or more granular via #if MOD_SSL >= 20000 or whatever.
+
+ *) Added support for named to SSLVerifyClient directive: Now the ogly
+ numerical levels 0-2 are still valid but can be replaced by better
+ readable names: "none", "optional", "require" and "optional_no_ca".
+
+ *) Added Makefile for conf/sslcerts/ directory to keep <hash>.0
+ symlinks up-to-date.
+
+ *) Translated the FAQ into HTML format and appended it to mod_ssl.html.
+ Additionally I created a ca.sign script and a Makefile for sslcert/ in
+ relation to the FAQ.
+
+ *) Enhanced the logfile support: First I've converted nasty
+ fprintf(stderr,..) to ap_log_error() variants. Second I've moved the
+ fprintf(pConfig->fileLogfile,...) to ssl_log_own(pConfig,...) calls.
+ And third error messages are now consistently prefixed with "mod_ssl:"
+ and "SSLeay:" - dependend from which an error comes. And forth I've
+ added the word "SSL" to a lot of messages to indicate that the
+ SSL-relationship. Additionally I removed doubled ERR_print_xxx calls.
+
+ *) Cleanup up namespace by added lots of `static's, so only the
+ module structure and the SSL_HOOK_xxx symbols are now exported.
+
+ *) Fixed up Apache API structures for Apache 1.3: added MODULE_VAR_EXPORT
+ for consistency and missing module structure dispatch pointers.
+
+ *) Completely renamed the functions to use common prefixes which
+ indicate their relationship and ordered the functions according to this
+ relationship. Additionally a complete list of prototypes is now
+ provided in mod_ssl.h. The order of functions now reflects the logical
+ order when one wants to review the module: 1. API structures, 2. config
+ handing, 3. directive handling, 4. init functions, 5. API hooks, 6.
+ internals, 7. caching support, 8. logfile support and 9. utility
+ functions. Additionally I cleanup up the namespace of global data
+ symbols: They now all have the prefix "_g": bFirstTime -> g_bFirstTime,
+ szCacheServerPort -> g_szCacheServerPort, szCacheServerPath ->
+ g_szCacheServerPath, s_pServer -> g_pServer.
+
+ *) Now all stuff for SSLEay < 0.8.0 is removed because an #error was
+ already given and there is now real need to support these versions any
+ longer. As a consequence we now also could remove the CACHE_SESSIONS
+ #ifdef mess because this was enabled for >= 0.8.0 since a long time.
+
+ *) Cleaned up the mess inside ap_config.h where TRUE, FALSE and BOOL
+ where globally defined even when they were only used my mod_ssl. Now
+ all stuff mod_ssl needs is inside mod_ssl.h and not spread over the
+ Apache sources without need. I've also cleaned up the "uchar"
+ definition because this was defined only by coincidence. I've also
+ replaced ugly return 0's with return FALSE and -1 by UNSET when the
+ context was the one for UNSET (like for VerifyType). Additionally I
+ replaced some incorrect declarations (extern uid_t ap_user_id) by
+ including the correct header file (http_config_globals.h). In the same
+ spirit for cleaness I've replaced the numerical filedescriptor numbers
+ by the STDXX_FILENO aliases.
+
+ *) Fixed a nasty bug: When a startup error occured an exit() was done.
+ But an already started ssl_gcache program was not terminated because
+ the exit() doesn't give Apache a chance to cleanup the pools (where the
+ program is registered). Fixed by adding a bunch of ap_clear_pool()
+ calls before the exit() calls. Additionally some more missing exit()'s
+ were added to config checks. And last but not least a termination
+ message is now created by ssl_gcache when it is terminated so one now
+ see both the start and the termination of ssl_gcache program in the
+ logfiles.
+
+ *) Replaced various sprintf()'s by the more safe and correct ap_snprintf()
+ variants. Same for fopen() and ap_pfopen() and other such functions.
+
+ *) Prefixed all SSLeay function calls with __SSLeay to mark them
+ for reviewing. I'm still not happy with this long and ugly reading
+ prefix but need to use an initial one which doesn't conflict.
+ Additionally I've then grep'ed out all __SSLeay prefixed symbols,
+ sorted them by group and inserted them into a README which can help
+ identifiying the used SSLeay API functions. The whole intent is
+ just to make reviewing of the code more easier, because this is
+ really important for security related sources.
+
+ *) A lot of various minor cleanups and fixes: For instance I've corrected the
+ directive descriptions, added some descriptive source comments, etc.
+ Really to much of these minor cleanups to write them down, sorry.
+
+ *) Added an FAQ file, assembled from some information found
+ on www.apache-ssl.org
+
+ *) Incorporated the changes between Apache-SSL 1.18-1.19
+
+ *) Added back support for the old Apache 1.2 way of configuring and
+ building by placing the SSL_BASE into src/Configuration.tmpl and
+ providing steps in INSTALL, too.
+
+ *) Added a complete Apache-style mod_ssl.html document which describes all
+ mod_ssl directives in detail. I've also painted a nice mod_ssl logo out
+ of the old mod_rewrite logo parts and a safety lock which secures the
+ feather. The SSLeay logo is also part of the document to give credit.
+
+ *) Added a `configure' frontend script for easy applying the mod_ssl
+ source extension and patches to the Apache source tree. It also can
+ replace APACI's configure script by running it in the background.
+ Additionally a slightly changed GNU patch 2.1 tool is distributed under
+ aux/ subdir to make sure the source patching works reliable because
+ newer patches have problems with the apache.diff file and some systems
+ have no "patch" at all.
+
+ *) Split definitions from mod_ssl.c into own mod_ssl.h and converted all
+ source files to the Apache coding styles to be consistent with the
+ officially distributed Apache sources.
+
+ *) Generation of a certificate is supported via top-level "make
+ certificate" which correctly finds SSLeay both when SSLeay tree is the
+ source tree or the installed tree.
+
+ *) Added SSLNeedsSSL to config files and cleaned up the
+ SSL-related stuff at the end of httpd.conf-dist.
+
+ *) Out-of-the-box installation for a SSL-aware Apache is provided by
+ automatically installing the certificate and the ssl_gcache program.
+ Additionally the SSL-related directives in the extended httpd.conf file
+ is adjusted, so one immediately can fire up an SSL-aware httpd.
+
+ *) The name of the binary is now again "httpd" instead of the "httpsd"
+ because "httpsd" reads ugly and confuses APACI. And there is no real
+ need to distinguish between them, because one still can compile a
+ standard Apache even after mod_ssl was applied to the Apache source
+ tree. Or why isn't everybody using httppd just because mod_perl is
+ built in? Bingo!
+
+ *) Added Apache 1.3 Autoconf-style Interface (APACI) support to
+ automatically enable the SSL module via --enable-module=ssl. This also
+ triggers the MOD_PERL define, so without this APACI option you still
+ can build a standard Apache.
+
+ *) Use the official Apache 1.3 way of adding strings to the
+ HTTP Server header: via ap_add_version_component() instead of patching
+ the defines in httpd.h. Additionally it now creates a header like
+ ``Server: Apache/1.3.1-dev (Unix) mod_ssl/2.0.0 SSLeay/0.9.0a'' i.e.
+ SSLeay is part of the Server header. Because SSLeay's version is more
+ important than mod_ssl's.
+
+ *) Removed all broken parts in the original Ben-SSL patch, for instance
+ incorrectly added newlines, incorrectly moved SecureWare, etc.
+
+ *) Removed nasty terminal messages like "Skip first time initialization",
+ "Launching ....", etc. These can be enabled in the future by using the
+ ap_log_error stuff.
+
+ *) Fixed incorrect log_ssl_info prototypes in mod_log_config.c from
+ Ben-SSL patch and fixed minor other things.
+
+ *) Cleaned up mod_ssl.c (formerly apache_ssl.c): removed unused variables
+ mod_ssl.c, added prototypes, moved extern prototypes. Actually I've
+ made it run quietly through ``gcc -Wall -Wshadow -Wpointer-arith
+ -Wcast-align -Wmissing-prototypes -Wmissing-declarations
+ -Wnested-externs -Winline'', etc.
+
+ *) Renamed apache_ssl.c to mod_ssl.c for consistency and also
+ to avoid problems inside APACI. Additionally the APACHE_SSL define was
+ renamed to MOD_SSL which is also consistent which the behaviour of
+ mod_perl which uses MOD_PERL.
+
+ *) *GENESIS*: Based the complete code on Ben Laurie's latest Apache-SSL
+ patch (Ben-SSL) version "apache_1.3.0+ssl_1.18". To avoid confusion and
+ to show that its second generation stuff the mod_ssl version starts
+ with 2.0.0. I've merged in all my previous work on Apache-SSL for
+ Apache 1.3b, i.e. especially the APACI stuff.
+
diff --git a/usr.sbin/httpd/src/Configuration b/usr.sbin/httpd/src/Configuration
index ca8b55aace5..a10f798aa6e 100644
--- a/usr.sbin/httpd/src/Configuration
+++ b/usr.sbin/httpd/src/Configuration
@@ -26,6 +26,47 @@
# not enabled). The AddModule directive can be used to enable such a
# module. By default no such modules are defined.
+################################################################
+# SSL support:
+#
+# o Set SSL_BASE to either the directory of your SSLeay
+# source tree or the installation tree. Alternatively you can
+# also use the value 'SYSTEM' which then indicates that SSLeay
+# is installed under various system locations.
+#
+# o If you're a US-citizen you have to compile SSLeay with the
+# RSAref library (which replaces the RSA code of SSLeay)
+# because of patent legalities with the RSA algorithm used for
+# the SSL protocol. For this situation you already have to
+# compile SSLeay with the -DRSAref define and now you have to
+# force Apache to link against the RSAglue library (from
+# SSLeay) and the rsaref library (from RSA). So, set RSA_BASE
+# to the directory of your RSAref source tree or to 'SYSTEM'
+# (indicating that librsaref.a is installed under a system
+# location)
+#
+# o Disable SSL_COMPAT rule to build mod_ssl without backward
+# compatibility code for Apache-SSL 1.x, mod_ssl 2.0.x Sioux
+# 1.x and Stronghold 2.x.
+#
+# o The SSL_SDBM rule controls whether the built-in SDBM library should be
+# used instead of a custom defined or vendor supplied DBM library. Use the
+# value 'default' for automatic determination or use 'yes' to force the use
+# of SDBM in case the vendor DBM library is buggy or restricts the data
+# sizes too dramatically.
+#
+# o The SSL_EXPERIMENTAL rule can be used to enable still experimental code
+# inside mod_ssl. These are usually new features which need some more
+# testing before they can be considered stable. So, enabled this on your own
+# risk and only when you like to see Apache+mod_ssl dump core ;-)
+#
+
+#SSL_BASE=/usr/local/ssl
+#RSA_BASE=/usr/local/rsa
+SSL_BASE=SYSTEM
+Rule SSL_COMPAT=yes
+Rule SSL_SDBM=default
+Rule SSL_EXPERIMENTAL=no
################################################################
# Makefile configuration
@@ -160,12 +201,20 @@ Rule SHARED_CHAIN=default
# is performing this function. If PARANOID is set to yes, it will
# actually print-out the code that the modules execute
#
+# EAPI:
+# Enable the Extended API which provides more module hooks, a generic
+# low-level hook mechanism and a generic context mechanism. Please notice
+# that enabling this rule forces you to recompile (with -DEAPI) all existing
+# modules which are already built and installed as DSOs. Because under EAPI
+# the module configuration structure has a different size.
+#
Rule SOCKS4=no
Rule SOCKS5=no
Rule IRIXNIS=no
Rule IRIXN32=yes
Rule PARANOID=no
+Rule EAPI=no
# The following rules should be set automatically by Configure. However, if
# they are not set by Configure (because we don't know the correct value for
@@ -328,8 +377,8 @@ AddModule modules/standard/mod_auth.o
## "gdbm" package if not and possibly adjust EXTRA_LIBS. (This may be
## done by Configure at a later date)
-# AddModule modules/standard/mod_auth_dbm.o
-# AddModule modules/standard/mod_auth_db.o
+AddModule modules/standard/mod_auth_dbm.o
+AddModule modules/standard/mod_auth_db.o
## "digest" implements HTTP Digest Authentication rather than the less
## secure Basic Auth used by the other modules.
@@ -391,3 +440,9 @@ AddModule modules/standard/mod_auth.o
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
+
diff --git a/usr.sbin/httpd/src/Configuration.tmpl b/usr.sbin/httpd/src/Configuration.tmpl
index ca8b55aace5..351303ec0e8 100644
--- a/usr.sbin/httpd/src/Configuration.tmpl
+++ b/usr.sbin/httpd/src/Configuration.tmpl
@@ -26,6 +26,46 @@
# not enabled). The AddModule directive can be used to enable such a
# module. By default no such modules are defined.
+################################################################
+# SSL support:
+#
+# o Set SSL_BASE to either the directory of your SSLeay
+# source tree or the installation tree. Alternatively you can
+# also use the value 'SYSTEM' which then indicates that SSLeay
+# is installed under various system locations.
+#
+# o If you're a US-citizen you have to compile SSLeay with the
+# RSAref library (which replaces the RSA code of SSLeay)
+# because of patent legalities with the RSA algorithm used for
+# the SSL protocol. For this situation you already have to
+# compile SSLeay with the -DRSAref define and now you have to
+# force Apache to link against the RSAglue library (from
+# SSLeay) and the rsaref library (from RSA). So, set RSA_BASE
+# to the directory of your RSAref source tree or to 'SYSTEM'
+# (indicating that librsaref.a is installed under a system
+# location)
+#
+# o Disable SSL_COMPAT rule to build mod_ssl without backward
+# compatibility code for Apache-SSL 1.x, mod_ssl 2.0.x Sioux
+# 1.x and Stronghold 2.x.
+#
+# o The SSL_SDBM rule controls whether the built-in SDBM library should be
+# used instead of a custom defined or vendor supplied DBM library. Use the
+# value 'default' for automatic determination or use 'yes' to force the use
+# of SDBM in case the vendor DBM library is buggy or restricts the data
+# sizes too dramatically.
+#
+# o The SSL_EXPERIMENTAL rule can be used to enable still experimental code
+# inside mod_ssl. These are usually new features which need some more
+# testing before they can be considered stable. So, enabled this on your own
+# risk and only when you like to see Apache+mod_ssl dump core ;-)
+#
+
+#SSL_BASE=/usr/local/ssl
+#RSA_BASE=/usr/local/rsa
+Rule SSL_COMPAT=yes
+Rule SSL_SDBM=default
+Rule SSL_EXPERIMENTAL=no
################################################################
# Makefile configuration
@@ -160,12 +200,20 @@ Rule SHARED_CHAIN=default
# is performing this function. If PARANOID is set to yes, it will
# actually print-out the code that the modules execute
#
+# EAPI:
+# Enable the Extended API which provides more module hooks, a generic
+# low-level hook mechanism and a generic context mechanism. Please notice
+# that enabling this rule forces you to recompile (with -DEAPI) all existing
+# modules which are already built and installed as DSOs. Because under EAPI
+# the module configuration structure has a different size.
+#
Rule SOCKS4=no
Rule SOCKS5=no
Rule IRIXNIS=no
Rule IRIXN32=yes
Rule PARANOID=no
+Rule EAPI=no
# The following rules should be set automatically by Configure. However, if
# they are not set by Configure (because we don't know the correct value for
@@ -391,3 +439,9 @@ AddModule modules/standard/mod_auth.o
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
+
diff --git a/usr.sbin/httpd/src/Configure b/usr.sbin/httpd/src/Configure
index d00b0e2fed3..b3b36170a9b 100644
--- a/usr.sbin/httpd/src/Configure
+++ b/usr.sbin/httpd/src/Configure
@@ -228,6 +228,7 @@ RULE_SOCKS5=`./helpers/CutRule SOCKS5 $file`
RULE_IRIXNIS=`./helpers/CutRule IRIXNIS $file`
RULE_IRIXN32=`./helpers/CutRule IRIXN32 $file`
RULE_PARANOID=`./helpers/CutRule PARANOID $file`
+RULE_EAPI=`./helpers/CutRule EAPI $file`
RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file`
RULE_SHARED_CHAIN=`./helpers/CutRule SHARED_CHAIN $file`
@@ -1538,6 +1539,19 @@ if [ "$RULE_WANTHSREGEX" = "yes" ]; then
fi
####################################################################
+# Extended API support:
+if [ "$RULE_EAPI" = "yes" ]; then
+ echo " + enabling Extended API (EAPI)"
+ CFLAGS="$CFLAGS -DEAPI"
+ # some vendor compilers are too restrictive
+ case "$OS:$CC" in
+ *IRIX-32*:*/cc|*IRIX-32*:cc )
+ CFLAGS="$CFLAGS -woff 1048,1110,1164"
+ ;;
+ esac
+fi
+
+####################################################################
## Now the SHARED_CHAIN stuff
##
LIBS_SHLIB=''
diff --git a/usr.sbin/httpd/src/Makefile.tmpl b/usr.sbin/httpd/src/Makefile.tmpl
index bb9c9d8bc8a..b76ca00e433 100644
--- a/usr.sbin/httpd/src/Makefile.tmpl
+++ b/usr.sbin/httpd/src/Makefile.tmpl
@@ -11,6 +11,10 @@ OBJS= \
$(OSDIR)/libos.a \
ap/libap.a
+TYPE=test
+CRT=
+KEY=
+
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $<
@@ -54,6 +58,13 @@ lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o
done; \
fi
+certificate:
+ @./support/mkcert.sh \
+ "$(MAKE)" "$(MFLAGS_STATIC)" \
+ "$(SSL_PROGRAM)" ./support \
+ "$(TYPE)" "$(CRT)" "$(KEY)"
+ @cd ../conf/ssl.crt; $(MAKE) $(MFLAGS_STATIC) SSLEAY=$(SSL_PROGRAM) >/dev/null 2>&1
+
subdirs:
@for i in $(SUBDIRS); do \
echo "===> $(SDP)$$i"; \
diff --git a/usr.sbin/httpd/src/ap/Makefile.tmpl b/usr.sbin/httpd/src/ap/Makefile.tmpl
index 4c1503cb923..346b6b6df79 100644
--- a/usr.sbin/httpd/src/ap/Makefile.tmpl
+++ b/usr.sbin/httpd/src/ap/Makefile.tmpl
@@ -6,7 +6,7 @@ LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS)
LIB=libap.a
OBJS=ap_execve.o ap_cpystrn.o ap_signal.o \
- ap_slack.o ap_snprintf.o ap_fnmatch.o
+ ap_slack.o ap_snprintf.o ap_fnmatch.o ap_hook.o ap_ctx.o
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $<
diff --git a/usr.sbin/httpd/src/ap/ap.mak b/usr.sbin/httpd/src/ap/ap.mak
index af4fe5e72f7..1e7c74a81b0 100644
--- a/usr.sbin/httpd/src/ap/ap.mak
+++ b/usr.sbin/httpd/src/ap/ap.mak
@@ -48,6 +48,8 @@ ALL : "$(OUTDIR)\ap.lib"
CLEAN :
-@erase "$(INTDIR)\ap_cpystrn.obj"
-@erase "$(INTDIR)\ap_fnmatch.obj"
+ -@erase "$(INTDIR)\ap_hook.obj"
+ -@erase "$(INTDIR)\ap_ctx.obj"
-@erase "$(INTDIR)\ap_signal.obj"
-@erase "$(INTDIR)\ap_slack.obj"
-@erase "$(INTDIR)\ap_snprintf.obj"
@@ -70,6 +72,8 @@ LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ap.lib"
LIB32_OBJS= \
"$(INTDIR)\ap_cpystrn.obj" \
"$(INTDIR)\ap_fnmatch.obj" \
+ "$(INTDIR)\ap_hook.obj" \
+ "$(INTDIR)\ap_ctx.obj" \
"$(INTDIR)\ap_signal.obj" \
"$(INTDIR)\ap_slack.obj" \
"$(INTDIR)\ap_snprintf.obj"
@@ -100,6 +104,8 @@ ALL : "$(OUTDIR)\ap.lib"
CLEAN :
-@erase "$(INTDIR)\ap_cpystrn.obj"
-@erase "$(INTDIR)\ap_fnmatch.obj"
+ -@erase "$(INTDIR)\ap_hook.obj"
+ -@erase "$(INTDIR)\ap_ctx.obj"
-@erase "$(INTDIR)\ap_signal.obj"
-@erase "$(INTDIR)\ap_slack.obj"
-@erase "$(INTDIR)\ap_snprintf.obj"
@@ -122,6 +128,8 @@ LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ap.lib"
LIB32_OBJS= \
"$(INTDIR)\ap_cpystrn.obj" \
"$(INTDIR)\ap_fnmatch.obj" \
+ "$(INTDIR)\ap_hook.obj" \
+ "$(INTDIR)\ap_ctx.obj" \
"$(INTDIR)\ap_signal.obj" \
"$(INTDIR)\ap_slack.obj" \
"$(INTDIR)\ap_snprintf.obj"
diff --git a/usr.sbin/httpd/src/ap/ap_ctx.c b/usr.sbin/httpd/src/ap/ap_ctx.c
new file mode 100644
index 00000000000..db457edae0e
--- /dev/null
+++ b/usr.sbin/httpd/src/ap/ap_ctx.c
@@ -0,0 +1,128 @@
+/* ====================================================================
+ * Copyright (c) 1998 The Apache Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+** Generic Context Interface for Apache
+** Written by Ralf S. Engelschall <rse@engelschall.com>
+*/
+
+#include "httpd.h"
+#include "ap_config.h"
+#include "ap_ctx.h"
+
+API_EXPORT(ap_ctx *) ap_ctx_new(pool *p)
+{
+ ap_ctx *ctx;
+ int i;
+
+ if (p != NULL) {
+ ctx = (ap_ctx *)ap_palloc(p, sizeof(ap_ctx_rec));
+ ctx->cr_pool = p;
+ ctx->cr_entry = (ap_ctx_entry **)
+ ap_palloc(p, sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
+ }
+ else {
+ ctx = (ap_ctx *)malloc(sizeof(ap_ctx_rec));
+ ctx->cr_pool = NULL;
+ ctx->cr_entry = (ap_ctx_entry **)
+ malloc(sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1));
+ }
+ for (i = 0; i < AP_CTX_MAX_ENTRIES+1; i++)
+ ctx->cr_entry[i] = NULL;
+ return ctx;
+}
+
+API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val)
+{
+ int i;
+ ap_ctx_entry *ce;
+
+ ce = NULL;
+ for (i = 0; ctx->cr_entry[i] != NULL; i++) {
+ if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0) {
+ ce = ctx->cr_entry[i];
+ break;
+ }
+ }
+ if (ce == NULL) {
+ if (i == AP_CTX_MAX_ENTRIES)
+ return;
+ if (ctx->cr_pool != NULL) {
+ ce = (ap_ctx_entry *)ap_palloc(ctx->cr_pool, sizeof(ap_ctx_entry));
+ ce->ce_key = ap_pstrdup(ctx->cr_pool, key);
+ }
+ else {
+ ce = (ap_ctx_entry *)malloc(sizeof(ap_ctx_entry));
+ ce->ce_key = strdup(key);
+ }
+ ctx->cr_entry[i] = ce;
+ ctx->cr_entry[i+1] = NULL;
+ }
+ ce->ce_val = val;
+ return;
+}
+
+API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key)
+{
+ int i;
+
+ for (i = 0; ctx->cr_entry[i] != NULL; i++)
+ if (strcmp(ctx->cr_entry[i]->ce_key, key) == 0)
+ return ctx->cr_entry[i]->ce_val;
+ return NULL;
+}
+
diff --git a/usr.sbin/httpd/src/ap/ap_hook.c b/usr.sbin/httpd/src/ap/ap_hook.c
new file mode 100644
index 00000000000..532001bd417
--- /dev/null
+++ b/usr.sbin/httpd/src/ap/ap_hook.c
@@ -0,0 +1,873 @@
+#if 0
+=pod
+#endif
+/* ====================================================================
+ * Copyright (c) 1998 The Apache Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+** Implementation of a Generic Hook Interface for Apache
+** Written by Ralf S. Engelschall <rse@engelschall.com>
+**
+** See ap_hook.h for documentation.
+**
+** Attention: This source file is a little bit tricky.
+** It's a combination of a C source and an embedded Perl script
+** (which updates the C source). The purpose of this is to have
+** both things together at one place. So you can both pass
+** this file to the C compiler and the Perl interpreter.
+*/
+
+ /*
+ * Premature optimization is
+ * the root of all evil.
+ * -- D. E. Knuth
+ */
+
+#include "httpd.h"
+#include "http_log.h"
+#include "ap_config.h"
+#include "ap_hook.h"
+
+/*
+ * the internal hook pool
+ */
+static ap_hook_entry **ap_hook_pool = NULL;
+
+/*
+ * forward prototypes for internal functions
+ */
+static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf);
+static ap_hook_entry *ap_hook_create(char *hook);
+static ap_hook_entry *ap_hook_find(char *hook);
+static void ap_hook_destroy(ap_hook_entry *he);
+
+/*
+ * Initialize the hook mechanism
+ */
+API_EXPORT(void) ap_hook_init(void)
+{
+ int i;
+
+ if (ap_hook_pool != NULL)
+ return;
+ ap_hook_pool = (ap_hook_entry **)malloc(sizeof(ap_hook_entry *)
+ *(AP_HOOK_MAX_ENTRIES+1));
+ for (i = 0; i < AP_HOOK_MAX_ENTRIES; i++)
+ ap_hook_pool[i] = NULL;
+ return;
+}
+
+/*
+ * Kill the hook mechanism
+ */
+API_EXPORT(void) ap_hook_kill(void)
+{
+ int i;
+
+ if (ap_hook_pool == NULL)
+ return;
+ for (i = 0; ap_hook_pool[i] != NULL; i++)
+ ap_hook_destroy(ap_hook_pool[i]);
+ free(ap_hook_pool);
+ ap_hook_pool = NULL;
+ return;
+}
+
+/*
+ * Smart creation of a hook (when it exist this is the same as
+ * ap_hook_find, when it doesn't exists it is created)
+ */
+static ap_hook_entry *ap_hook_create(char *hook)
+{
+ int i;
+ ap_hook_entry *he;
+
+ for (i = 0; ap_hook_pool[i] != NULL; i++)
+ if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
+ return ap_hook_pool[i];
+
+ if (i >= AP_HOOK_MAX_ENTRIES)
+ return NULL;
+
+ if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL)
+ return NULL;
+ ap_hook_pool[i] = he;
+
+ he->he_hook = strdup(hook);
+ he->he_sig = AP_HOOK_SIG_UNKNOWN;
+ he->he_modeid = AP_HOOK_MODE_UNKNOWN;
+ he->he_modeval.v_int = 0;
+
+ he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *)
+ *(AP_HOOK_MAX_FUNCS+1));
+ if (he->he_func == NULL)
+ return FALSE;
+
+ for (i = 0; i < AP_HOOK_MAX_FUNCS; i++)
+ he->he_func[i] = NULL;
+ return he;
+}
+
+/*
+ * Find a particular hook
+ */
+static ap_hook_entry *ap_hook_find(char *hook)
+{
+ int i;
+
+ for (i = 0; ap_hook_pool[i] != NULL; i++)
+ if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
+ return ap_hook_pool[i];
+ return NULL;
+}
+
+/*
+ * Destroy a particular hook
+ */
+static void ap_hook_destroy(ap_hook_entry *he)
+{
+ int i;
+
+ if (he == NULL)
+ return;
+ free(he->he_hook);
+ for (i = 0; he->he_func[i] != NULL; i++)
+ free(he->he_func[i]);
+ free(he->he_func);
+ free(he);
+ return;
+}
+
+/*
+ * Configure a particular hook,
+ * i.e. remember its signature and return value mode
+ */
+API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
+{
+ ap_hook_entry *he;
+ va_list ap;
+ int rc;
+
+ va_start(ap, modeid);
+ if ((he = ap_hook_create(hook)) == NULL)
+ rc = FALSE;
+ else {
+ he->he_sig = sig;
+ he->he_modeid = modeid;
+ if (modeid == AP_HOOK_MODE_DECLINE) {
+ if (AP_HOOK_SIG_HAS(sig, RC, char))
+ he->he_modeval.v_char = va_arg(ap, va_type(char));
+ else if (AP_HOOK_SIG_HAS(sig, RC, int))
+ he->he_modeval.v_int = va_arg(ap, va_type(int));
+ else if (AP_HOOK_SIG_HAS(sig, RC, long))
+ he->he_modeval.v_long = va_arg(ap, va_type(long));
+ else if (AP_HOOK_SIG_HAS(sig, RC, float))
+ he->he_modeval.v_float = va_arg(ap, va_type(float));
+ else if (AP_HOOK_SIG_HAS(sig, RC, double))
+ he->he_modeval.v_double = va_arg(ap, va_type(double));
+ else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
+ he->he_modeval.v_ptr = va_arg(ap, va_type(ptr));
+ }
+ rc = TRUE;
+ }
+ va_end(ap);
+ return rc;
+}
+
+/*
+ * Register a function to call for a hook
+ */
+API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx)
+{
+ int i, j;
+ ap_hook_entry *he;
+ ap_hook_func *hf;
+
+ if ((he = ap_hook_create(hook)) == NULL)
+ return FALSE;
+
+ for (i = 0; he->he_func[i] != NULL; i++)
+ if (he->he_func[i]->hf_ptr == func)
+ return FALSE;
+
+ if (i == AP_HOOK_MAX_FUNCS)
+ return FALSE;
+
+ if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL)
+ return FALSE;
+
+ for (j = i; j >= 0; j--)
+ he->he_func[j+1] = he->he_func[j];
+ he->he_func[0] = hf;
+
+ hf->hf_ptr = func;
+ hf->hf_ctx = ctx;
+
+ return TRUE;
+}
+
+/*
+ * Unregister a function to call for a hook
+ */
+API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func)
+{
+ int i, j;
+ ap_hook_entry *he;
+
+ if ((he = ap_hook_find(hook)) == NULL)
+ return FALSE;
+ for (i = 0; he->he_func[i] != NULL; i++) {
+ if (he->he_func[i]->hf_ptr == func) {
+ free(he->he_func[i]);
+ for (j = i; he->he_func[j] != NULL; j++)
+ he->he_func[j] = he->he_func[j+1];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Retrieve the status of a particular hook
+ */
+API_EXPORT(ap_hook_state) ap_hook_status(char *hook)
+{
+ ap_hook_entry *he;
+
+ if ((he = ap_hook_find(hook)) == NULL)
+ return AP_HOOK_STATE_NOTEXISTANT;
+ if ( he->he_func[0] != NULL
+ && he->he_sig != AP_HOOK_SIG_UNKNOWN
+ && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
+ return AP_HOOK_STATE_REGISTERED;
+ if ( he->he_sig != AP_HOOK_SIG_UNKNOWN
+ && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
+ return AP_HOOK_STATE_CONFIGURED;
+ return AP_HOOK_STATE_ESTABLISHED;
+}
+
+/*
+ * Use a hook, i.e. optional on-the-fly configure it before calling it
+ */
+API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
+{
+ int i;
+ ap_hook_value modeval;
+ ap_hook_entry *he;
+ va_list ap;
+ int rc;
+
+ va_start(ap, modeid);
+
+ if (modeid == AP_HOOK_MODE_DECLINE) {
+ if (AP_HOOK_SIG_HAS(sig, RC, char))
+ modeval.v_char = va_arg(ap, va_type(char));
+ else if (AP_HOOK_SIG_HAS(sig, RC, int))
+ modeval.v_int = va_arg(ap, va_type(int));
+ else if (AP_HOOK_SIG_HAS(sig, RC, long))
+ modeval.v_long = va_arg(ap, va_type(long));
+ else if (AP_HOOK_SIG_HAS(sig, RC, float))
+ modeval.v_float = va_arg(ap, va_type(float));
+ else if (AP_HOOK_SIG_HAS(sig, RC, double))
+ modeval.v_double = va_arg(ap, va_type(double));
+ else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
+ modeval.v_ptr = va_arg(ap, va_type(ptr));
+ }
+
+ if ((he = ap_hook_create(hook)) == NULL)
+ return FALSE;
+
+ if (he->he_sig == AP_HOOK_SIG_UNKNOWN)
+ he->he_sig = sig;
+ if (he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
+ he->he_modeid = modeid;
+ he->he_modeval = modeval;
+ }
+
+ for (i = 0; he->he_func[i] != NULL; i++)
+ if (ap_hook_call_func(ap, he, he->he_func[i]))
+ break;
+
+ if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
+ rc = TRUE;
+ else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
+ rc = FALSE;
+ else
+ rc = TRUE;
+
+ va_end(ap);
+ return rc;
+}
+
+/*
+ * Call a hook
+ */
+API_EXPORT(int) ap_hook_call(char *hook, ...)
+{
+ int i;
+ ap_hook_entry *he;
+ va_list ap;
+ int rc;
+
+ va_start(ap, hook);
+
+ if ((he = ap_hook_find(hook)) == NULL) {
+ va_end(ap);
+ return FALSE;
+ }
+ if ( he->he_sig == AP_HOOK_SIG_UNKNOWN
+ || he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
+ va_end(ap);
+ return FALSE;
+ }
+
+ for (i = 0; he->he_func[i] != NULL; i++)
+ if (ap_hook_call_func(ap, he, he->he_func[i]))
+ break;
+
+ if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
+ rc = TRUE;
+ else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
+ rc = FALSE;
+ else
+ rc = TRUE;
+
+ va_end(ap);
+ return rc;
+}
+
+static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf)
+{
+ void *v_rc;
+ int rc;
+
+ /*
+ * Now we dispatch the various function calls. We support function
+ * signatures with up to 9 types (1 return type, 8 argument types) where
+ * each argument can have 7 different types (ctx, char, int, long, float,
+ * double, ptr), so theoretically there are 9^7 (=4782969) combinations
+ * possible. But because we don't need all of them, of course, we
+ * implement only the following well chosen subset (duplicates are ok):
+ *
+ * 1. `The basic hook'.
+ *
+ * void func()
+ *
+ * 2. The standard set of signatures which form all combinations of
+ * int&ptr based signatures for up to 3 arguments. We provide
+ * them per default for module authors.
+ *
+ * int func()
+ * ptr func()
+ * int func(int)
+ * int func(ptr)
+ * ptr func(int)
+ * ptr func(ptr)
+ * int func(int,int)
+ * int func(int,ptr)
+ * int func(ptr,int)
+ * int func(ptr,ptr)
+ * ptr func(int,int)
+ * ptr func(int,ptr)
+ * ptr func(ptr,int)
+ * ptr func(ptr,ptr)
+ * int func(int,int,int)
+ * int func(int,int,ptr)
+ * int func(int,ptr,int)
+ * int func(int,ptr,ptr)
+ * int func(ptr,int,int)
+ * int func(ptr,int,ptr)
+ * int func(ptr,ptr,int)
+ * int func(ptr,ptr,ptr)
+ * ptr func(int,int,int)
+ * ptr func(int,int,ptr)
+ * ptr func(int,ptr,int)
+ * ptr func(int,ptr,ptr)
+ * ptr func(ptr,int,int)
+ * ptr func(ptr,int,ptr)
+ * ptr func(ptr,ptr,int)
+ * ptr func(ptr,ptr,ptr)
+ *
+ * 3. Actually currently used hooks.
+ *
+ * int func(ptr,ptr,int) e.g. ap::buff::read [http_main.c]
+ * int func(ptr,ptr,int) e.g. ap::buff::write [http_main.c]
+ * int func(ptr,ptr,int) e.g. ap::buff::writev [http_main.c]
+ * int func(ptr,ptr,int) e.g. ap::buff::sendwithtimeout [http_main.c]
+ * int func(ptr,ptr,int) e.g. ap::buff::recvwithtimeout [http_main.c]
+ * int func(ptr,ptr) e.g. ap::mod_proxy::canon [mod_proxy.c]
+ * int func(ptr,ptr,ptr,int) e.g. ap::mod_proxy::http::canon [mod_proxy.c]
+ * int func(ptr,ptr,ptr,ptr,int) e.g. ap::mod_proxy::http::handler [mod_proxy.c]
+ * int func(ptr,ptr) e.g. ap::mod_proxy::error [mod_proxy.c]
+ * int func(ptr,ptr,ptr,ptr,int,ptr) e.g. ap::mod_proxy::handler [mod_proxy.c]
+ * int func(ptr) e.g. ap::mod_proxy::http::handler::set_destport [proxy_http.c]
+ * ptr func(ptr,ptr) e.g. ap::mod_proxy::http::handler::new_connection [proxy_http.c]
+ * int func(ptr,ptr,ptr,int,ptr) e.g. ap::mod_proxy::http::handler::write_host_header [proxy_http.c]
+ * ptr func(ptr,ptr,ptr,ptr,ptr) e.g. ap::mod_ssl::var_lookup [ssl_engine_vars.c]
+ * ptr func(ptr,ptr) e.g. ap::mod_rewrite::lookup_variable [mod_rewrite.c]
+ *
+ * To simplify the programming task we generate the actual dispatch code
+ * for these calls via the embedded Perl script at the end of this source
+ * file. This script parses the above lines and generates the section
+ * below. So, when you need more signature variants just add them to the
+ * above list and run
+ *
+ * $ perl ap_hook.c
+ *
+ * This automatically updates the above code.
+ */
+
+ rc = TRUE;
+ v_rc = NULL;
+ if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void))
+ v_rc = va_arg(ap, void *);
+
+ /* ----BEGIN GENERATED SECTION-------- */
+ if (he->he_sig == AP_HOOK_SIG1(void)) {
+ /* Call: void func() */
+ ((void(*)())(hf->hf_ptr))();
+ }
+ else if (he->he_sig == AP_HOOK_SIG1(int)) {
+ /* Call: int func() */
+ *((int *)v_rc) = ((int(*)())(hf->hf_ptr))();
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG1(ptr)) {
+ /* Call: ptr func() */
+ *((void * *)v_rc) = ((void *(*)())(hf->hf_ptr))();
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG2(int, int)) {
+ /* Call: int func(int) */
+ int v1 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(int))(hf->hf_ptr))(v1);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG2(int, ptr)) {
+ /* Call: int func(ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *))(hf->hf_ptr))(v1);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG2(ptr, int)) {
+ /* Call: ptr func(int) */
+ int v1 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(int))(hf->hf_ptr))(v1);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG2(ptr, ptr)) {
+ /* Call: ptr func(ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(void *))(hf->hf_ptr))(v1);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(int, int, int)) {
+ /* Call: int func(int,int) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(int, int))(hf->hf_ptr))(v1, v2);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(int, int, ptr)) {
+ /* Call: int func(int,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(int, void *))(hf->hf_ptr))(v1, v2);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(int, ptr, int)) {
+ /* Call: int func(ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(void *, int))(hf->hf_ptr))(v1, v2);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(int, ptr, ptr)) {
+ /* Call: int func(ptr,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *, void *))(hf->hf_ptr))(v1, v2);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(ptr, int, int)) {
+ /* Call: ptr func(int,int) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(int, int))(hf->hf_ptr))(v1, v2);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(ptr, int, ptr)) {
+ /* Call: ptr func(int,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(int, void *))(hf->hf_ptr))(v1, v2);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, int)) {
+ /* Call: ptr func(ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(void *, int))(hf->hf_ptr))(v1, v2);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, ptr)) {
+ /* Call: ptr func(ptr,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(void *, void *))(hf->hf_ptr))(v1, v2);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, int, int, int)) {
+ /* Call: int func(int,int,int) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ int v3 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, int, int, ptr)) {
+ /* Call: int func(int,int,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, int)) {
+ /* Call: int func(int,ptr,int) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ int v3 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, ptr)) {
+ /* Call: int func(int,ptr,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, int)) {
+ /* Call: int func(ptr,int,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ int v3 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, ptr)) {
+ /* Call: int func(ptr,int,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, int)) {
+ /* Call: int func(ptr,ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ int v3 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, ptr)) {
+ /* Call: int func(ptr,ptr,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, int)) {
+ /* Call: ptr func(int,int,int) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ int v3 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, ptr)) {
+ /* Call: ptr func(int,int,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ int v2 = va_arg(ap, va_type(int));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, int)) {
+ /* Call: ptr func(int,ptr,int) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ int v3 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, ptr)) {
+ /* Call: ptr func(int,ptr,ptr) */
+ int v1 = va_arg(ap, va_type(int));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, int)) {
+ /* Call: ptr func(ptr,int,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ int v3 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, ptr)) {
+ /* Call: ptr func(ptr,int,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ int v2 = va_arg(ap, va_type(int));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, int)) {
+ /* Call: ptr func(ptr,ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ int v3 = va_arg(ap, va_type(int));
+ *((void * *)v_rc) = ((void *(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, ptr)) {
+ /* Call: ptr func(ptr,ptr,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG5(int, ptr, ptr, ptr, int)) {
+ /* Call: int func(ptr,ptr,ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ int v4 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, ptr, int)) {
+ /* Call: int func(ptr,ptr,ptr,ptr,int) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ void *v4 = va_arg(ap, va_type(ptr));
+ int v5 = va_arg(ap, va_type(int));
+ *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG7(int, ptr, ptr, ptr, ptr, int, ptr)) {
+ /* Call: int func(ptr,ptr,ptr,ptr,int,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ void *v4 = va_arg(ap, va_type(ptr));
+ int v5 = va_arg(ap, va_type(int));
+ void *v6 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5, v6);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) {
+ /* Call: int func(ptr,ptr,ptr,int,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ int v4 = va_arg(ap, va_type(int));
+ void *v5 = va_arg(ap, va_type(ptr));
+ *((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+ rc = (*((int *)v_rc) != he->he_modeval.v_int);
+ }
+ else if (he->he_sig == AP_HOOK_SIG6(ptr, ptr, ptr, ptr, ptr, ptr)) {
+ /* Call: ptr func(ptr,ptr,ptr,ptr,ptr) */
+ void *v1 = va_arg(ap, va_type(ptr));
+ void *v2 = va_arg(ap, va_type(ptr));
+ void *v3 = va_arg(ap, va_type(ptr));
+ void *v4 = va_arg(ap, va_type(ptr));
+ void *v5 = va_arg(ap, va_type(ptr));
+ *((void * *)v_rc) = ((void *(*)(void *, void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ else if (he->he_sig == AP_HOOK_SIG2(ptr, char)) {
+ /* Call: ptr func(char) */
+ char v1 = va_arg(ap, va_type(char));
+ *((void * *)v_rc) = ((void *(*)(char))(hf->hf_ptr))(v1);
+ rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
+ }
+ /* ----END GENERATED SECTION---------- */
+ else
+ ap_log_assert("hook signature not implemented", __FILE__, __LINE__);
+
+ if (he->he_modeid == AP_HOOK_MODE_ALL)
+ rc = FALSE;
+ else if (he->he_modeid == AP_HOOK_MODE_TOPMOST)
+ rc = TRUE;
+
+ return rc;
+}
+
+/*
+=cut
+##
+## Embedded Perl script for generating the dispatch section
+##
+
+require 5.003;
+use strict;
+
+# configuration
+my $file = $0;
+my $begin = '----BEGIN GENERATED SECTION--------';
+my $end = '----END GENERATED SECTION----------';
+
+# special command: find used signatures
+if ($ARGV[0] eq 'used') {
+ my @S = `find .. -type f -name "*.c" -print`;
+ my $s;
+ foreach $s (@S) {
+ $s =~ s|\n$||;
+ open(FP, "<$s") || die;
+ my $source = '';
+ $source .= $_ while (<FP>);
+ close(FP);
+ my %seen = ();
+ sub printme {
+ my ($src, $hook, $sig) = @_;
+ return if ($seen{$hook} == 1);
+ $seen{$hook} = 1;
+ my ($rc, $args) = ($sig =~ m|^([^,]+)(.*)$|);
+ $args =~ s|^,||;
+ $src =~ s|^.+/||;
+ printf(" * %-6s%-30s e.g. %s [%s]\n", $rc, "func($args)", $hook, $src);
+ }
+ $source =~ s|\("([^"]+)",\s*AP_HOOK_SIG[0-9]\((.+?)\)|&printme($s, $1, $2), ''|sge;
+ }
+ exit(0);
+}
+
+# read ourself and keep a backup
+open(FP, "<$file") || die;
+my $source = '';
+$source .= $_ while (<FP>);
+close(FP);
+open(FP, ">$file.bak") || die;
+print FP $source;
+close(FP);
+
+# now parse the signature lines and update the code
+my $o = '';
+my $next = 0;
+my $line;
+my %seen = ();
+foreach $line (split(/\n/, $source)) {
+ next if (not $line =~ m|\*\s+\S+\s+func\(.*\)|);
+ my ($sig, $rc, $param) = ($line =~ m|\*\s+((\S+)\s+func\((.*?)\))|);
+ $sig =~ s|\s+| |g;
+
+ next if ($seen{$sig} == 1);
+ $seen{$sig} = 1;
+
+ print "Generating code for `$sig'\n";
+
+ my @S = ($rc, split(/[\s,]+/, $param));
+ my @RS = @S;
+ my $i;
+ for ($i = 0; $i <= $#RS; $i++) {
+ $RS[$i] = 'void *' if ($RS[$i] eq 'ptr');
+ $RS[$i] = 'void *' if ($RS[$i] eq 'ctx');
+ }
+
+ $o .= "else " if ($next); $next++;
+ $o .= sprintf("if (he->he_sig == AP_HOOK_SIG%d(%s)) {\n", $#S+1, join(', ',@S));
+ $o .= sprintf(" \/\* Call: %s \*\/\n", $sig);
+ for ($i = 1; $i <= $#S; $i++) {
+ $o .= sprintf(" %-6sv%d = va_arg(ap, va_type(%s));\n", $RS[$i], $i, $S[$i]);
+ }
+ $o .= " ";
+ $o .= sprintf("*((%s *)v_rc) = ", $RS[0]) if ($S[0] ne 'void');
+ $o .= sprintf("((%s(*)(%s))(hf->hf_ptr))", $RS[0], join(', ', @RS[1..$#RS]));
+ $o .= "(";
+ for ($i = 1; $i <= $#S; $i++) {
+ $o .= "hf->hf_ctx" if ($S[$i] eq 'ctx');
+ $o .= sprintf("v%d", $i) if ($S[$i] ne 'ctx');
+ $o .= ", " if ($i < $#S);
+ }
+ $o .= ");\n";
+ $o .= sprintf(" rc = (*((%s *)v_rc) != he->he_modeval.v_%s);\n",
+ $RS[0], $S[0]) if ($S[0] ne 'void');
+ $o .= "}\n";
+}
+
+# insert the generated code at the target location
+$o =~ s|^| |mg;
+$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s;
+
+# and update the source on disk
+print "Updating file `$file'\n";
+open(FP, ">$file") || die;
+print FP $source;
+close(FP);
+
+=pod
+*/
diff --git a/usr.sbin/httpd/src/include/ap_config_auto.h b/usr.sbin/httpd/src/include/ap_config_auto.h
new file mode 100644
index 00000000000..846e30351c4
--- /dev/null
+++ b/usr.sbin/httpd/src/include/ap_config_auto.h
@@ -0,0 +1,59 @@
+/*
+ * ap_config_auto.h -- Automatically determined configuration stuff
+ * THIS FILE WAS AUTOMATICALLY GENERATED - DO NOT EDIT!
+ */
+
+#ifndef AP_CONFIG_AUTO_H
+#define AP_CONFIG_AUTO_H
+
+/* check: #include <dlfcn.h> */
+#ifndef HAVE_DLFCN_H
+#define HAVE_DLFCN_H 1
+#endif
+
+/* check: #include <dl.h> */
+#ifdef HAVE_DL_H
+#undef HAVE_DL_H
+#endif
+
+/* check: #include <bstring.h> */
+#ifdef HAVE_BSTRING_H
+#undef HAVE_BSTRING_H
+#endif
+
+/* check: #include <crypt.h> */
+#ifdef HAVE_CRYPT_H
+#undef HAVE_CRYPT_H
+#endif
+
+/* check: #include <unistd.h> */
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif
+
+/* check: #include <sys/resource.h> */
+#ifndef HAVE_SYS_RESOURCE_H
+#define HAVE_SYS_RESOURCE_H 1
+#endif
+
+/* check: #include <sys/select.h> */
+#ifndef HAVE_SYS_SELECT_H
+#define HAVE_SYS_SELECT_H 1
+#endif
+
+/* check: #include <sys/processor.h> */
+#ifdef HAVE_SYS_PROCESSOR_H
+#undef HAVE_SYS_PROCESSOR_H
+#endif
+
+/* build flag: -DMOD_SSL=202103 */
+#ifndef MOD_SSL
+#define MOD_SSL 202103
+#endif
+
+/* build flag: -DEAPI */
+#ifndef EAPI
+#define EAPI 1
+#endif
+
+#endif /* AP_CONFIG_AUTO_H */
diff --git a/usr.sbin/httpd/src/include/ap_ctx.h b/usr.sbin/httpd/src/include/ap_ctx.h
new file mode 100644
index 00000000000..85a8ae93322
--- /dev/null
+++ b/usr.sbin/httpd/src/include/ap_ctx.h
@@ -0,0 +1,97 @@
+/* ====================================================================
+ * Copyright (c) 1998 The Apache Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+** Generic Context Interface for Apache
+** Written by Ralf S. Engelschall <rse@engelschall.com>
+*/
+
+#ifndef AP_CTX_H
+#define AP_CTX_H
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+/*
+ * Internal Context Record Definition
+ */
+
+#define AP_CTX_MAX_ENTRIES 1024
+
+typedef struct {
+ char *ce_key;
+ void *ce_val;
+} ap_ctx_entry;
+
+typedef struct {
+ pool *cr_pool;
+ ap_ctx_entry **cr_entry;
+} ap_ctx_rec;
+
+typedef ap_ctx_rec ap_ctx;
+
+/*
+ * Prototypes for Context Handling Functions
+ */
+
+API_EXPORT(ap_ctx *)ap_ctx_new(pool *p);
+API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val);
+API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key);
+
+#endif /* AP_CTX_H */
diff --git a/usr.sbin/httpd/src/include/ap_hook.h b/usr.sbin/httpd/src/include/ap_hook.h
new file mode 100644
index 00000000000..532dec8bc8d
--- /dev/null
+++ b/usr.sbin/httpd/src/include/ap_hook.h
@@ -0,0 +1,545 @@
+/* ====================================================================
+ * Copyright (c) 1998 The Apache Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the Apache Group
+ * for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+/*
+** Generic Hook Interface for Apache
+** Written by Ralf S. Engelschall <rse@engelschall.com>
+**
+** SYNOPSIS
+**
+** Main Setup:
+** void ap_hook_init (void);
+** void ap_hook_kill (void);
+**
+** Hook Configuration and Registration:
+** int ap_hook_configure (char *hook, int sig, int modeid, ap_hook_value modeval);
+** int ap_hook_register (char *hook, void *func, void *ctx);
+** int ap_hook_unregister(char *hook, void *func);
+**
+** Hook Usage:
+** int ap_hook_configured(char *hook);
+** int ap_hook_registered(char *hook);
+** int ap_hook_call (char *hook, ...);
+**
+** DESCRIPTION
+**
+** This implements a generic hook interface for Apache which can be used
+** for loosely couple code through arbitrary hooks. There are two use cases
+** for this mechanism:
+**
+** 1. Inside a specific code section you want to perform a specific
+** function call. But you want to allow one or even more modules to
+** override this function call by registering hook functions. Those
+** functions are registered on a stack and can be configured to have a
+** `decline' return value. As long as there are functions which return
+** the `decline' value the next function on the stack is tried. When a
+** function doesn't return the `decline' value the hook call stops. The
+** intent of this usage is to not hard-code function calls.
+**
+** 2. Inside a specific code you have a function you want to export.
+** But you first want to allow other code to override this function.
+** And second you want to export this function without real linker
+** symbol references. Instead you want to register the function and let
+** the users call this function via name. The intent of this usage is to
+** allow inter-module communication without direct symbol references,
+** which are a big NO-NO for the DSO situation.
+**
+** And we have one major design goal: The hook call should be very similar
+** to the corresponding direct function call while still providing maximum
+** flexiblity, i.e. any function signature (the set of types for the return
+** value and the arguments) should be supported. And it should be possible
+** to register always a context (ctx) variable with a function which is
+** passed to the corresponding function when the hook call is performed.
+**
+** Using this hook interface is always a four-step process:
+**
+** 1. Initialize or destroy the hook mechanism inside your main program:
+**
+** ap_hook_init();
+** :
+** ap_hook_kill();
+**
+** 2. Configure a particular hook by specifing its name, signature
+** and return type semantic:
+**
+** ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL));
+** ap_hook_configure("echo", AP_HOOK_SIG2(int,ptr), AP_HOOK_TOPMOST);
+**
+** This configures two hooks:
+** - A hook named "lookup" with the signature "void *lookup(void *)"
+** and a return code semantic which says: As long as a registered hook
+** function returns NULL and more registered functions exists we we
+** proceed.
+** - A hook named "echo" with the signature "int echo(void *)" and a
+** return code semantic which says: Only the top most function on the
+** registered function stack is tried, independed what value it
+** returns.
+**
+** 3. Register the actual functions which should be used by the hook:
+**
+** ap_hook_register("lookup", mylookup, mycontext);
+** ap_hook_register("echo", myecho);
+**
+** This registers the function mylookup() under the "lookup" hook with
+** the context given by the variable mycontext. And it registers the
+** function myecho() under the "echo" hook without any context.
+**
+** 4. Finally use the hook, i.e. instead of using direct function calls
+** like
+**
+** vp = mylookup("foo", mycontext);
+** n = myecho("bar");
+**
+** you now can use:
+**
+** ap_hook_call("lookup", &vp, "foo");
+** ap_hook_call("echo", &n, "bar");
+**
+** Notice two things: First the context for the mylookup() function is
+** automatically added by the hook mechanism. And it is a different and
+** not fixed context for each registered function, of course. Second,
+** return values always have to be pushed into variables and they a
+** pointer to them has to be given as the second argument (except for
+** functions which have a void return type, of course).
+**
+** BTW, the return value of ap_hook_call() is TRUE or FALSE. TRUE when
+** at least one function call was successful (always the case for
+** AP_HOOK_TOPMOST). FALSE when all functions returned the decline
+** value or no functions are registered at all.
+**
+** RESTRICTIONS
+**
+** To make the hook implementation efficient and to not bloat up the code a
+** few restrictions have to make:
+**
+** 1. Only function calls with up to 4 arguments are supported.
+** When more are needed you can either extend the hook implementation by
+** using more bits for the signature configuration or you can do a
+** workaround when the functions is your own one: Put the remaining
+** (N-5) arguments into a structure and pass only a pointer (one
+** argument) as the forth argument.
+**
+** 2. Only the following types are supported:
+** - For the return value:
+** void (= none), char, int, float, double, ptr (= void*)
+** - For the arguments:
+** ctx (= context), char, int, float, double, ptr (= void*)
+** This means in theory there are 6^5 (=7776) signature combinations are
+** possible. But because we don't need all of them inside Apache and it
+** would bloat up the code dramatically we implement only a subset of
+** those combinations. The to be implemented signatures can be specified
+** inside ap_hook.c and the corresponding code can be automatically
+** generated by running `perl ap_hook.c' (yeah, no joke ;-). So when
+** you need a hook with a different still not implemented signature you
+** either have to again use a workaround as above (i.e. use a structure)
+** or just add the signature to the ap_hook.c file.
+**
+** EXAMPLE
+**
+** We want to call `ssize_t read(int, void *, size_t)' through hooks in
+** order to allow modules to override this call. So, somewhere we have a
+** replacement function for read() defined:
+**
+** ssize_t my_read(int, void *, size_t);
+**
+** We now configure a `read' hook. Here the AP_HOOK_SIGx() macro defines
+** the signature of the read()-like callback functions and has to match the
+** prototype of read(). But we have to replace typedefs with the physical
+** types. And AP_HOOK_DECLINE() sets the return value of the read()-like
+** functions which forces the next hook to be called (here -1). And we
+** register the original read function.
+**
+** ap_hook_configure("read", AP_HOOK_SIG4(int,int,ptr,int),
+** AP_HOOK_DECLINE(-1));
+** ap_hook_register("read", read);
+**
+** Now a module wants to override the read() call and registers one more
+** function (which has to match the same prototype as read() of course):
+**
+** ap_hook_register("read", my_read);
+**
+** The function logically gets pushed onto a stack, so the execution order
+** is the reverse register order, i.e. last registered - first called. Now
+** we can replace the standard read() call
+**
+** bytes = read(fd, buf, bufsize);
+** if (bytes == -1)
+** ...error...
+**
+** with the hook-call:
+**
+** rc = ap_hook_call("read", &bytes, fd, buf, bufsize);
+** if (rc == FALSE)
+** ...error...
+**
+** Now internally the following is done: The call "bytes = my_read(fd, buf,
+** bufsize)" is done. When it returns not -1 (the decline value) nothing
+** more is done. But when my_read() returned -1 the next function is tried:
+** "bytes = read(fd, buf, bufsize)". When this one returns -1 again you get
+** rc == FALSE. When it finally returns not -1 you get rc == TRUE.
+*/
+
+#ifndef AP_HOOK_H
+#define AP_HOOK_H
+
+/*
+ * Function Signature Specification:
+ *
+ * We encode the complete signature ingredients as a bitfield
+ * stored in a single unsigned long integer value, which can be
+ * constructed with AP_HOOK_SIGx(...)
+ */
+
+/* the type of the signature bitfield */
+typedef unsigned long int ap_hook_sig;
+
+/* the mask (bin) 111 (hex 0x7) for the triples in the bitfield */
+#define AP_HOOK_SIG_TRIPLE_MASK 0x7
+
+/* the position of the triple */
+#define AP_HOOK_SIG_TRIPLE_POS(n) ((n)*3)
+
+/* the constructor for triple #n with value v */
+#define AP_HOOK_SIG_TRIPLE(n,v) \
+ (((ap_hook_sig)(v))<<((AP_HOOK_##n)*3))
+
+/* the check whether triple #n in sig contains value v */
+#define AP_HOOK_SIG_HAS(sig,n,v) \
+ ((((ap_hook_sig)(sig))&AP_HOOK_SIG_TRIPLE(n, AP_HOOK_SIG_TRIPLE_MASK)) == (AP_HOOK_##n##_##v))
+
+/* utility function to get triple #n in sig */
+#define AP_HOOK_SIG_TRIPLE_GET(sig,n) \
+ ((((ap_hook_sig)(sig))>>AP_HOOK_SIG_TRIPLE_POS(n))&(AP_HOOK_SIG_TRIPLE_MASK))
+
+/* utility function to set triple #n in sig to value v */
+#define AP_HOOK_SIG_TRIPLE_SET(sig,n,v) \
+ ((((ap_hook_sig)(sig))&~(AP_HOOK_SIG_TRIPLE_MASK<<AP_HOOK_SIG_TRIPLE_POS(n)))|((v)<<AP_HOOK_SIG_TRIPLE_POS(n)))
+
+/* define the ingredients for the triple #0: id stuff */
+#define AP_HOOK_ID 0
+#define AP_HOOK_ID_ok AP_HOOK_SIG_TRIPLE(ID,0)
+#define AP_HOOK_ID_undef AP_HOOK_SIG_TRIPLE(ID,1)
+
+/* define the ingredients for the triple #1: return code */
+#define AP_HOOK_RC 1
+#define AP_HOOK_RC_void AP_HOOK_SIG_TRIPLE(RC,0)
+#define AP_HOOK_RC_char AP_HOOK_SIG_TRIPLE(RC,1)
+#define AP_HOOK_RC_int AP_HOOK_SIG_TRIPLE(RC,2)
+#define AP_HOOK_RC_long AP_HOOK_SIG_TRIPLE(RC,3)
+#define AP_HOOK_RC_float AP_HOOK_SIG_TRIPLE(RC,4)
+#define AP_HOOK_RC_double AP_HOOK_SIG_TRIPLE(RC,5)
+#define AP_HOOK_RC_ptr AP_HOOK_SIG_TRIPLE(RC,6)
+
+/* define the ingredients for the triple #2: argument 1 */
+#define AP_HOOK_A1 2
+#define AP_HOOK_A1_ctx AP_HOOK_SIG_TRIPLE(A1,0)
+#define AP_HOOK_A1_char AP_HOOK_SIG_TRIPLE(A1,1)
+#define AP_HOOK_A1_int AP_HOOK_SIG_TRIPLE(A1,2)
+#define AP_HOOK_A1_long AP_HOOK_SIG_TRIPLE(A1,3)
+#define AP_HOOK_A1_float AP_HOOK_SIG_TRIPLE(A1,4)
+#define AP_HOOK_A1_double AP_HOOK_SIG_TRIPLE(A1,5)
+#define AP_HOOK_A1_ptr AP_HOOK_SIG_TRIPLE(A1,6)
+
+/* define the ingredients for the triple #3: argument 2 */
+#define AP_HOOK_A2 3
+#define AP_HOOK_A2_ctx AP_HOOK_SIG_TRIPLE(A2,0)
+#define AP_HOOK_A2_char AP_HOOK_SIG_TRIPLE(A2,1)
+#define AP_HOOK_A2_int AP_HOOK_SIG_TRIPLE(A2,2)
+#define AP_HOOK_A2_long AP_HOOK_SIG_TRIPLE(A2,3)
+#define AP_HOOK_A2_float AP_HOOK_SIG_TRIPLE(A2,4)
+#define AP_HOOK_A2_double AP_HOOK_SIG_TRIPLE(A2,5)
+#define AP_HOOK_A2_ptr AP_HOOK_SIG_TRIPLE(A2,6)
+
+/* define the ingredients for the triple #4: argument 3 */
+#define AP_HOOK_A3 4
+#define AP_HOOK_A3_ctx AP_HOOK_SIG_TRIPLE(A3,0)
+#define AP_HOOK_A3_char AP_HOOK_SIG_TRIPLE(A3,1)
+#define AP_HOOK_A3_int AP_HOOK_SIG_TRIPLE(A3,2)
+#define AP_HOOK_A3_long AP_HOOK_SIG_TRIPLE(A3,3)
+#define AP_HOOK_A3_float AP_HOOK_SIG_TRIPLE(A3,4)
+#define AP_HOOK_A3_double AP_HOOK_SIG_TRIPLE(A3,5)
+#define AP_HOOK_A3_ptr AP_HOOK_SIG_TRIPLE(A3,6)
+
+/* define the ingredients for the triple #5: argument 4 */
+#define AP_HOOK_A4 5
+#define AP_HOOK_A4_ctx AP_HOOK_SIG_TRIPLE(A4,0)
+#define AP_HOOK_A4_char AP_HOOK_SIG_TRIPLE(A4,1)
+#define AP_HOOK_A4_int AP_HOOK_SIG_TRIPLE(A4,2)
+#define AP_HOOK_A4_long AP_HOOK_SIG_TRIPLE(A4,3)
+#define AP_HOOK_A4_float AP_HOOK_SIG_TRIPLE(A4,4)
+#define AP_HOOK_A4_double AP_HOOK_SIG_TRIPLE(A4,5)
+#define AP_HOOK_A4_ptr AP_HOOK_SIG_TRIPLE(A4,6)
+
+/* define the ingredients for the triple #6: argument 5 */
+#define AP_HOOK_A5 6
+#define AP_HOOK_A5_ctx AP_HOOK_SIG_TRIPLE(A5,0)
+#define AP_HOOK_A5_char AP_HOOK_SIG_TRIPLE(A5,1)
+#define AP_HOOK_A5_int AP_HOOK_SIG_TRIPLE(A5,2)
+#define AP_HOOK_A5_long AP_HOOK_SIG_TRIPLE(A5,3)
+#define AP_HOOK_A5_float AP_HOOK_SIG_TRIPLE(A5,4)
+#define AP_HOOK_A5_double AP_HOOK_SIG_TRIPLE(A5,5)
+#define AP_HOOK_A5_ptr AP_HOOK_SIG_TRIPLE(A5,6)
+
+/* define the ingredients for the triple #7: argument 6 */
+#define AP_HOOK_A6 7
+#define AP_HOOK_A6_ctx AP_HOOK_SIG_TRIPLE(A6,0)
+#define AP_HOOK_A6_char AP_HOOK_SIG_TRIPLE(A6,1)
+#define AP_HOOK_A6_int AP_HOOK_SIG_TRIPLE(A6,2)
+#define AP_HOOK_A6_long AP_HOOK_SIG_TRIPLE(A6,3)
+#define AP_HOOK_A6_float AP_HOOK_SIG_TRIPLE(A6,4)
+#define AP_HOOK_A6_double AP_HOOK_SIG_TRIPLE(A6,5)
+#define AP_HOOK_A6_ptr AP_HOOK_SIG_TRIPLE(A6,6)
+
+/* define the ingredients for the triple #8: argument 7 */
+#define AP_HOOK_A7 8
+#define AP_HOOK_A7_ctx AP_HOOK_SIG_TRIPLE(A7,0)
+#define AP_HOOK_A7_char AP_HOOK_SIG_TRIPLE(A7,1)
+#define AP_HOOK_A7_int AP_HOOK_SIG_TRIPLE(A7,2)
+#define AP_HOOK_A7_long AP_HOOK_SIG_TRIPLE(A7,3)
+#define AP_HOOK_A7_float AP_HOOK_SIG_TRIPLE(A7,4)
+#define AP_HOOK_A7_double AP_HOOK_SIG_TRIPLE(A7,5)
+#define AP_HOOK_A7_ptr AP_HOOK_SIG_TRIPLE(A7,6)
+
+/* define the ingredients for the triple #9: argument 8 */
+#define AP_HOOK_A8 9
+#define AP_HOOK_A8_ctx AP_HOOK_SIG_TRIPLE(9,0)
+#define AP_HOOK_A8_char AP_HOOK_SIG_TRIPLE(9,1)
+#define AP_HOOK_A8_int AP_HOOK_SIG_TRIPLE(9,2)
+#define AP_HOOK_A8_long AP_HOOK_SIG_TRIPLE(9,3)
+#define AP_HOOK_A8_float AP_HOOK_SIG_TRIPLE(9,4)
+#define AP_HOOK_A8_double AP_HOOK_SIG_TRIPLE(9,5)
+#define AP_HOOK_A8_ptr AP_HOOK_SIG_TRIPLE(9,6)
+
+/* the constructor for unknown signatures */
+#define AP_HOOK_SIG_UNKNOWN AP_HOOK_ID_undef
+
+/* the constructor for signatures with 1 type */
+#define AP_HOOK_SIG1(rc) \
+ (AP_HOOK_RC_##rc)
+
+/* the constructor for signatures with 2 types */
+#define AP_HOOK_SIG2(rc,a1) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1)
+
+/* the constructor for signatures with 3 types */
+#define AP_HOOK_SIG3(rc,a1,a2) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2)
+
+/* the constructor for signatures with 4 types */
+#define AP_HOOK_SIG4(rc,a1,a2,a3) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3)
+
+/* the constructor for signatures with 5 types */
+#define AP_HOOK_SIG5(rc,a1,a2,a3,a4) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4)
+
+/* the constructor for signatures with 6 types */
+#define AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5)
+
+/* the constructor for signatures with 7 types */
+#define AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6)
+
+/* the constructor for signatures with 8 types */
+#define AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6|AP_HOOK_A7_##a7)
+
+/* the constructor for signatures with 9 types */
+#define AP_HOOK_SIG9(rc,a1,a2,a3,a4,a5,a6,a7,a8) \
+ (AP_HOOK_RC_##rc|AP_HOOK_A1_##a1|AP_HOOK_A2_##a2|AP_HOOK_A3_##a3|AP_HOOK_A4_##a4|AP_HOOK_A5_##a5|AP_HOOK_A6_##a6|AP_HOOK_A7_##a7|AP_HOOK_A8_##a8)
+
+/*
+ * Return Value Mode Identification
+ */
+
+/* the type of the return value modes */
+typedef unsigned int ap_hook_mode;
+
+/* the mode of the return value */
+#define AP_HOOK_MODE_UNKNOWN 0
+#define AP_HOOK_MODE_TOPMOST 1
+#define AP_HOOK_MODE_DECLINE 2
+#define AP_HOOK_MODE_ALL 3
+
+/* the constructors for the return value modes */
+#define AP_HOOK_TOPMOST AP_HOOK_MODE_TOPMOST
+#define AP_HOOK_DECLINE(val) AP_HOOK_MODE_DECLINE, (val)
+#define AP_HOOK_ALL AP_HOOK_MODE_ALL
+
+/*
+ * Hook State Identification
+ */
+
+/* the type of the hook state */
+typedef unsigned short int ap_hook_state;
+
+/* the values of the hook state */
+#define AP_HOOK_STATE_UNDEF 0
+#define AP_HOOK_STATE_NOTEXISTANT 1
+#define AP_HOOK_STATE_ESTABLISHED 2
+#define AP_HOOK_STATE_CONFIGURED 3
+#define AP_HOOK_STATE_REGISTERED 4
+
+/*
+ * Hook Context Identification
+ *
+ * Notice: Null is ok here, because AP_HOOK_NOCTX is just a dummy argument
+ * because we know from the signature whether the argument is a
+ * context value or just the dummy value.
+ */
+
+#define AP_HOOK_NOCTX (void *)(0)
+#define AP_HOOK_CTX(v) (void *)(v)
+
+/*
+ * Internal Hook Record Definition
+ */
+
+/* the union holding the arbitrary decline values */
+typedef union {
+ char v_char;
+ int v_int;
+ long v_long;
+ float v_float;
+ double v_double;
+ void *v_ptr;
+} ap_hook_value;
+
+/* the structure holding one hook function and its context */
+typedef struct {
+ void *hf_ptr; /* function pointer */
+ void *hf_ctx; /* function context */
+} ap_hook_func;
+
+/* the structure holding one hook entry with all its registered functions */
+typedef struct {
+ char *he_hook; /* hook name (=unique id) */
+ ap_hook_sig he_sig; /* hook signature */
+ int he_modeid; /* hook mode id */
+ ap_hook_value he_modeval; /* hook mode value */
+ ap_hook_func **he_func; /* hook registered funcs */
+} ap_hook_entry;
+
+/* the maximum number of hooks and functions per hook */
+#define AP_HOOK_MAX_ENTRIES 512
+#define AP_HOOK_MAX_FUNCS 128
+
+/*
+ * Extended Variable Argument (vararg) Support
+ *
+ * In ANSI C varargs exists, but because the prototypes of function with
+ * varargs cannot reflect the types of the varargs, K&R argument passing
+ * conventions have to apply for the compiler. This means mainly a conversion
+ * of shorter type variants to the maximum variant (according to sizeof). The
+ * above va_type() macro provides this mapping from the wanted types to the
+ * physically used ones.
+ */
+
+/* the mapping */
+#define VA_TYPE_char int
+#define VA_TYPE_short int
+#define VA_TYPE_int int
+#define VA_TYPE_long long
+#define VA_TYPE_float double
+#define VA_TYPE_double double
+#define VA_TYPE_ptr void *
+#define VA_TYPE_ctx void *
+
+/* the constructor */
+#ifdef va_type
+#undef va_type
+#endif
+#define va_type(type) VA_TYPE_ ## type
+
+/*
+ * Miscellaneous stuff
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+/*
+ * Wrapper macros for the callback-function register/unregister calls.
+ *
+ * Background: Strict ANSI C doesn't allow a function pointer to be treated as
+ * a void pointer on argument passing, but we cannot declare the argument as a
+ * function prototype, because the functions can have arbitrary signatures. So
+ * we have to use a void pointer here. But to not require explicit casts on
+ * function pointers for every register/unregister call, we smooth the API a
+ * little bit by providing these macros.
+ */
+
+#define ap_hook_register(hook,func,ctx) ap_hook_register_I(hook,(void *)(func),ctx)
+#define ap_hook_unregister(hook,func) ap_hook_unregister_I(hook,(void *)(func))
+
+/*
+ * Prototypes for the hook API functions
+ */
+
+API_EXPORT(void) ap_hook_init (void);
+API_EXPORT(void) ap_hook_kill (void);
+API_EXPORT(int) ap_hook_configure (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
+API_EXPORT(int) ap_hook_register_I (char *hook, void *func, void *ctx);
+API_EXPORT(int) ap_hook_unregister_I (char *hook, void *func);
+API_EXPORT(ap_hook_state) ap_hook_status (char *hook);
+API_EXPORT(int) ap_hook_use (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);
+API_EXPORT(int) ap_hook_call (char *hook, ...);
+
+#endif /* AP_HOOK_H */
diff --git a/usr.sbin/httpd/src/include/ap_mmn.h b/usr.sbin/httpd/src/include/ap_mmn.h
index bbfabe604f4..4a4316027d1 100644
--- a/usr.sbin/httpd/src/include/ap_mmn.h
+++ b/usr.sbin/httpd/src/include/ap_mmn.h
@@ -205,7 +205,23 @@
* for a non-binary-compatible release.
*/
+/*
+ * Under Extended API situations we replace the magic cookie "AP13" with
+ * "EAPI" to let us distinguish between the EAPI module structure (which
+ * contain additional pointers at the end) and standard module structures
+ * (which lack at least NULL's for the pointers at the end). This is
+ * important because standard ("AP13") modules would dump core when we
+ * dispatch over the additional hooks because NULL's are missing at the end of
+ * the module structure. See also the code in mod_so for details on loading
+ * (we accept both "AP13" and "EAPI").
+ */
+#ifdef EAPI
+#define MODULE_MAGIC_COOKIE_AP13 0x41503133UL /* "AP13" */
+#define MODULE_MAGIC_COOKIE_EAPI 0x45415049UL /* "EAPI" */
+#define MODULE_MAGIC_COOKIE MODULE_MAGIC_COOKIE_EAPI
+#else
#define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
+#endif
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 19990108
diff --git a/usr.sbin/httpd/src/include/buff.h b/usr.sbin/httpd/src/include/buff.h
index 27ccd1537be..e2e00a5f126 100644
--- a/usr.sbin/httpd/src/include/buff.h
+++ b/usr.sbin/httpd/src/include/buff.h
@@ -124,6 +124,10 @@ struct buff_struct {
/* transport handle, for RPC binding handle or some such */
void *t_handle;
+#ifdef EAPI
+ ap_ctx *ctx;
+#endif /* EAPI */
+
#ifdef B_SFIO
Sfio_t *sf_in;
Sfio_t *sf_out;
diff --git a/usr.sbin/httpd/src/include/http_conf_globals.h b/usr.sbin/httpd/src/include/http_conf_globals.h
index c540c4e0a8c..53c429421be 100644
--- a/usr.sbin/httpd/src/include/http_conf_globals.h
+++ b/usr.sbin/httpd/src/include/http_conf_globals.h
@@ -86,6 +86,9 @@ extern MODULE_VAR_EXPORT int ap_suexec_enabled;
extern int ap_listenbacklog;
extern int ap_dump_settings;
extern API_VAR_EXPORT int ap_extended_status;
+#ifdef EAPI
+extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
+#endif /* EAPI */
extern char *ap_pid_fname;
extern char *ap_scoreboard_fname;
diff --git a/usr.sbin/httpd/src/include/http_config.h b/usr.sbin/httpd/src/include/http_config.h
index 5962efc186c..21b51ddf8bc 100644
--- a/usr.sbin/httpd/src/include/http_config.h
+++ b/usr.sbin/httpd/src/include/http_config.h
@@ -273,6 +273,55 @@ typedef struct module_struct {
void (*child_exit) (server_rec *, pool *);
#endif
int (*post_read_request) (request_rec *);
+
+#ifdef EAPI
+ /*
+ * ANSI C guarantees us that we can at least _extend_ the module structure
+ * with additional hooks without the need to change all existing modules.
+ * Because: ``If there are fewer initializers in the list than members of
+ * the structure, the trailing members are initialized with 0.'' (The C
+ * Programming Language, 2nd Ed., A8.7 Initialization). So we just
+ * have to put our additional hooks here:
+ *
+ * add_module:
+ * Called from within ap_add_module() right after the module structure
+ * was linked into the Apache internal module list. It is mainly
+ * intended to be used to define configuration defines (<IfDefine>)
+ * which have to be available directly after a LoadModule/AddModule.
+ * Actually this is the earliest possible hook a module can use.
+ *
+ * remove_module:
+ * Called from within ap_remove_module() right before the module
+ * structure is kicked out from the Apache internal module list.
+ * Actually this is last possible hook a module can use and exists for
+ * consistency with the add_module hook.
+ *
+ * rewrite_command:
+ * Called right after a configuration directive line was read and
+ * before it is processed. It is mainly intended to be used for
+ * rewriting directives in order to provide backward compatibility to
+ * old directive variants.
+ *
+ * new_connection:
+ * Called from within the internal new_connection() function, right
+ * after the conn_rec structure for the new established connection was
+ * created and before Apache starts processing the request with
+ * ap_read_request(). It is mainly intended to be used to setup/run
+ * connection dependent things like sending start headers for
+ * on-the-fly compression, etc.
+ */
+#ifdef ULTRIX_BRAIN_DEATH
+ void (*add_module) ();
+ void (*remove_module) ();
+ char *(*rewrite_command) ();
+ void (*new_connection) ();
+#else
+ void (*add_module) (struct module_struct *);
+ void (*remove_module) (struct module_struct *);
+ char *(*rewrite_command) (cmd_parms *, void *config, const char *);
+ void (*new_connection) (conn_rec *);
+#endif
+#endif /* EAPI */
} module;
/* Initializer for the first few module slots, which are only
diff --git a/usr.sbin/httpd/src/include/http_main.h b/usr.sbin/httpd/src/include/http_main.h
index a0d014de785..fec41a6034c 100644
--- a/usr.sbin/httpd/src/include/http_main.h
+++ b/usr.sbin/httpd/src/include/http_main.h
@@ -124,7 +124,11 @@ API_EXPORT(void) ap_child_terminate(request_rec *r);
API_EXPORT(void) ap_sync_scoreboard_image(void);
int ap_update_child_status(int child_num, int status, request_rec *r);
void ap_time_process_request(int child_num, int status);
+#ifdef EAPI
+API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x);
+#else
unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x);
+#endif
API_EXPORT(int) ap_check_alarm(void);
#ifndef NO_OTHER_CHILD
diff --git a/usr.sbin/httpd/src/include/httpd.h b/usr.sbin/httpd/src/include/httpd.h
index 318966b4a8d..581836ec522 100644
--- a/usr.sbin/httpd/src/include/httpd.h
+++ b/usr.sbin/httpd/src/include/httpd.h
@@ -70,6 +70,15 @@ extern "C" {
#include "ap_config.h"
#include "alloc.h"
+/*
+ * Include the Extended API headers.
+ * Don't move the position. It has to be after alloc.h because it uses the
+ * pool stuff but before buff.h because the buffer stuff uses the EAPI, too.
+ */
+#ifdef EAPI
+#include "ap_hook.h"
+#include "ap_ctx.h"
+#endif /* EAPI */
#include "buff.h"
#include "ap.h"
@@ -136,8 +145,13 @@ extern "C" {
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_HTTPS_PORT 443
#define ap_is_default_port(port,r) ((port) == ap_default_port(r))
+#ifdef EAPI
+#define ap_http_method(r) (ap_ctx_get((r)->ctx, "ap::http::method") != NULL ? ((char *)ap_ctx_get((r)->ctx, "ap::http::method")) : "http")
+#define ap_default_port(r) (ap_ctx_get((r)->ctx, "ap::default::port") != NULL ? atoi((char *)ap_ctx_get((r)->ctx, "ap::default::port")) : DEFAULT_HTTP_PORT)
+#else /* EAPI */
#define ap_http_method(r) "http"
#define ap_default_port(r) DEFAULT_HTTP_PORT
+#endif /* EAPI */
/* --------- Default user name and group name running standalone ---------- */
/* --- These may be specified as numbers by placing a # before a number --- */
@@ -426,6 +440,9 @@ enum server_token_type {
API_EXPORT(const char *) ap_get_server_version(void);
API_EXPORT(void) ap_add_version_component(const char *component);
API_EXPORT(const char *) ap_get_server_built(void);
+#ifdef EAPI
+API_EXPORT(void) ap_add_config_define(const char *define);
+#endif /* EAPI */
/* Numeric release version identifier: MMNNFFRBB: major minor fix final beta
* Always increases along the same track as the source branch.
@@ -780,6 +797,10 @@ struct request_rec {
* record to improve 64bit alignment the next time we need to break
* binary compatibility for some other reason.
*/
+
+#ifdef EAPI
+ ap_ctx *ctx;
+#endif /* EAPI */
};
@@ -824,6 +845,10 @@ struct conn_rec {
signed int double_reverse:2;/* have we done double-reverse DNS?
* -1 yes/failure, 0 not yet, 1 yes/success */
int keepalives; /* How many times have we used it? */
+
+#ifdef EAPI
+ ap_ctx *ctx;
+#endif /* EAPI */
};
/* Per-vhost config... */
@@ -896,6 +921,10 @@ struct server_rec {
int limit_req_line; /* limit on size of the HTTP request line */
int limit_req_fieldsize; /* limit on size of any request header field */
int limit_req_fields; /* limit on number of request header fields */
+
+#ifdef EAPI
+ ap_ctx *ctx;
+#endif /* EAPI */
};
/* These are more like real hosts than virtual hosts */
diff --git a/usr.sbin/httpd/src/main/buff.c b/usr.sbin/httpd/src/main/buff.c
index cf78599c7c7..85006a92478 100644
--- a/usr.sbin/httpd/src/main/buff.c
+++ b/usr.sbin/httpd/src/main/buff.c
@@ -125,7 +125,11 @@
select() sometimes returns 1 even though the write will block. We must work around this.
*/
+#ifdef EAPI
+API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags)
+#else /* EAPI */
int sendwithtimeout(int sock, const char *buf, int len, int flags)
+#endif /* EAPI */
{
int iostate = 1;
fd_set fdset;
@@ -183,8 +187,11 @@ int sendwithtimeout(int sock, const char *buf, int len, int flags)
return (rv);
}
-
+#ifdef EAPI
+API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags)
+#else /* EAPI */
int recvwithtimeout(int sock, char *buf, int len, int flags)
+#endif /* EAPI */
{
int iostate = 1;
fd_set fdset;
@@ -242,6 +249,9 @@ static int ap_read(BUFF *fb, void *buf, int nbyte)
}
else
#endif
+#ifdef EAPI
+ if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
+#endif /* EAPI */
rv = read(fb->fd_in, buf, nbyte);
return rv;
@@ -253,6 +263,9 @@ static ap_inline int buff_read(BUFF *fb, void *buf, int nbyte)
#if defined (WIN32)
if (fb->flags & B_SOCKET) {
+#ifdef EAPI
+ if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
+#endif /* EAPI */
rv = recvwithtimeout(fb->fd_in, buf, nbyte, 0);
if (rv == SOCKET_ERROR)
errno = WSAGetLastError();
@@ -295,6 +308,9 @@ static int ap_write(BUFF *fb, const void *buf, int nbyte)
}
else
#endif
+#ifdef EAPI
+ if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
+#endif /* EAPI */
#if defined (B_SFIO)
rv = sfwrite(fb->sf_out, buf, nbyte);
#else
@@ -310,6 +326,9 @@ static ap_inline int buff_write(BUFF *fb, const void *buf, int nbyte)
#if defined(WIN32)
if (fb->flags & B_SOCKET) {
+#ifdef EAPI
+ if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
+#endif /* EAPI */
rv = sendwithtimeout(fb->fd, buf, nbyte, 0);
if (rv == SOCKET_ERROR)
errno = WSAGetLastError();
@@ -385,6 +404,10 @@ API_EXPORT(BUFF *) ap_bcreate(pool *p, int flags)
(size_t) SF_UNBOUND, 1, SF_WRITE);
#endif
+#ifdef EAPI
+ fb->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
return fb;
}
@@ -1041,6 +1064,9 @@ static int writev_it_all(BUFF *fb, struct iovec *vec, int nvec)
i = 0;
while (i < nvec) {
do
+#ifdef EAPI
+ if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
+#endif /* EAPI */
rv = writev(fb->fd, &vec[i], nvec - i);
while (rv == -1 && (errno == EINTR || errno == EAGAIN)
&& !(fb->flags & B_EOUT));
diff --git a/usr.sbin/httpd/src/main/http_config.c b/usr.sbin/httpd/src/main/http_config.c
index 206dae888eb..2159c448550 100644
--- a/usr.sbin/httpd/src/main/http_config.c
+++ b/usr.sbin/httpd/src/main/http_config.c
@@ -580,6 +580,20 @@ API_EXPORT(void) ap_add_module(module *m)
m->name = tmp;
}
#endif /*_OSD_POSIX*/
+
+#ifdef EAPI
+ /*
+ * Invoke the `add_module' hook inside the now existing set
+ * of modules to let them all now that this module was added.
+ */
+ {
+ module *m2;
+ for (m2 = top_module; m2 != NULL; m2 = m2->next)
+ if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
+ if (m2->add_module != NULL)
+ (*m2->add_module)(m);
+ }
+#endif /* EAPI */
}
/*
@@ -594,6 +608,21 @@ API_EXPORT(void) ap_remove_module(module *m)
{
module *modp;
+#ifdef EAPI
+ /*
+ * Invoke the `remove_module' hook inside the now existing
+ * set of modules to let them all now that this module is
+ * beeing removed.
+ */
+ {
+ module *m2;
+ for (m2 = top_module; m2 != NULL; m2 = m2->next)
+ if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
+ if (m2->remove_module != NULL)
+ (*m2->remove_module)(m);
+ }
+#endif /* EAPI */
+
modp = top_module;
if (modp == m) {
/* We are the top module, special case */
@@ -960,6 +989,27 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons
const command_rec *cmd;
module *mod = top_module;
+#ifdef EAPI
+ /*
+ * Invoke the `rewrite_command' of modules to allow
+ * they to rewrite the directive line before we
+ * process it.
+ */
+ {
+ module *m;
+ char *cp;
+ for (m = top_module; m != NULL; m = m->next) {
+ if (m->magic == MODULE_MAGIC_COOKIE_EAPI) {
+ if (m->rewrite_command != NULL) {
+ cp = (m->rewrite_command)(parms, config, l);
+ if (cp != NULL)
+ l = cp;
+ }
+ }
+ }
+ }
+#endif /* EAPI */
+
if ((l[0] == '#') || (!l[0]))
return NULL;
@@ -1319,6 +1369,10 @@ CORE_EXPORT(const char *) ap_init_virtual_host(pool *p, const char *hostname,
s->limit_req_fieldsize = main_server->limit_req_fieldsize;
s->limit_req_fields = main_server->limit_req_fields;
+#ifdef EAPI
+ s->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
*ps = s;
return ap_parse_vhost_addrs(p, hostname, s);
@@ -1430,6 +1484,10 @@ static server_rec *init_server_config(pool *p)
s->module_config = create_server_config(p, s);
s->lookup_defaults = create_default_per_dir_config(p);
+#ifdef EAPI
+ s->ctx = ap_ctx_new(p);
+#endif /* EAPI */
+
return s;
}
diff --git a/usr.sbin/httpd/src/main/http_main.c b/usr.sbin/httpd/src/main/http_main.c
index 46ca62a1097..c197baa2191 100644
--- a/usr.sbin/httpd/src/main/http_main.c
+++ b/usr.sbin/httpd/src/main/http_main.c
@@ -249,6 +249,9 @@ int ap_suexec_enabled = 0;
int ap_listenbacklog;
int ap_dump_settings = 0;
API_VAR_EXPORT int ap_extended_status = 0;
+#ifdef EAPI
+API_VAR_EXPORT ap_ctx *ap_global_ctx;
+#endif /* EAPI */
/*
* The max child slot ever assigned, preserved across restarts. Necessary
@@ -413,6 +416,16 @@ static void ap_set_version(void)
}
}
+#ifdef EAPI
+API_EXPORT(void) ap_add_config_define(const char *define)
+{
+ char **var;
+ var = (char **)ap_push_array(ap_server_config_defines);
+ *var = ap_pstrdup(pcommands, define);
+ return;
+}
+#endif /* EAPI */
+
static APACHE_TLS int volatile exit_after_unblock = 0;
#ifdef GPROF
@@ -1147,7 +1160,11 @@ static void alrm_handler(int sig)
}
#endif
+#ifdef EAPI
+API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x)
+#else
unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x)
+#endif
{
unsigned int old;
@@ -2971,6 +2988,24 @@ static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
conn->remote_addr = *remaddr;
conn->remote_ip = ap_pstrdup(conn->pool,
inet_ntoa(conn->remote_addr.sin_addr));
+#ifdef EAPI
+ conn->ctx = ap_ctx_new(conn->pool);
+#endif /* EAPI */
+
+#ifdef EAPI
+ /*
+ * Invoke the `new_connection' hook of modules to let them do
+ * some connection dependent actions before we go on with
+ * processing the request on this connection.
+ */
+ {
+ module *m;
+ for (m = top_module; m != NULL; m = m->next)
+ if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
+ if (m->new_connection != NULL)
+ (*m->new_connection)(conn);
+ }
+#endif /* EAPI */
return conn;
}
@@ -3341,6 +3376,9 @@ static void show_compile_settings(void)
printf("Server's Module Magic Number: %u:%u\n",
MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
printf("Server compiled with....\n");
+#ifdef EAPI
+ printf(" -D EAPI\n");
+#endif
#ifdef BIG_SECURITY_HOLE
printf(" -D BIG_SECURITY_HOLE\n");
#endif
@@ -3486,6 +3524,22 @@ static void common_init(void)
ap_server_pre_read_config = ap_make_array(pcommands, 1, sizeof(char *));
ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
ap_server_config_defines = ap_make_array(pcommands, 1, sizeof(char *));
+
+#ifdef EAPI
+ ap_hook_init();
+ ap_hook_configure("ap::buff::read",
+ AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_configure("ap::buff::write",
+ AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_configure("ap::buff::writev",
+ AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_configure("ap::buff::sendwithtimeout",
+ AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_configure("ap::buff::recvwithtimeout",
+ AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
+
+ ap_global_ctx = ap_ctx_new(NULL);
+#endif /* EAPI */
}
#ifndef MULTITHREAD
diff --git a/usr.sbin/httpd/src/main/http_protocol.c b/usr.sbin/httpd/src/main/http_protocol.c
index cae3aa2e8fe..9c4f831748e 100644
--- a/usr.sbin/httpd/src/main/http_protocol.c
+++ b/usr.sbin/httpd/src/main/http_protocol.c
@@ -916,6 +916,10 @@ request_rec *ap_read_request(conn_rec *conn)
r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
r->the_request = NULL;
+#ifdef EAPI
+ r->ctx = ap_ctx_new(r->pool);
+#endif /* EAPI */
+
#ifdef CHARSET_EBCDIC
ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
#endif
@@ -1065,6 +1069,11 @@ void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
rnew->read_body = REQUEST_NO_BODY;
rnew->main = (request_rec *) r;
+
+#ifdef EAPI
+ rnew->ctx = r->ctx;
+#endif /* EAPI */
+
}
void ap_finalize_sub_req_protocol(request_rec *sub)
diff --git a/usr.sbin/httpd/src/main/http_request.c b/usr.sbin/httpd/src/main/http_request.c
index 71089516a07..693cf310648 100644
--- a/usr.sbin/httpd/src/main/http_request.c
+++ b/usr.sbin/httpd/src/main/http_request.c
@@ -1301,6 +1301,9 @@ static request_rec *internal_internal_redirect(const char *new_uri, request_rec
new->no_local_copy = r->no_local_copy;
new->read_length = r->read_length; /* We can only read it once */
new->vlist_validator = r->vlist_validator;
+#ifdef EAPI
+ new->ctx = r->ctx;
+#endif /* EAPI */
ap_table_setn(new->subprocess_env, "REDIRECT_STATUS",
ap_psprintf(r->pool, "%d", r->status));
diff --git a/usr.sbin/httpd/src/modules/proxy/mod_proxy.c b/usr.sbin/httpd/src/modules/proxy/mod_proxy.c
index 0816f6640d2..f5fcf29af6b 100644
--- a/usr.sbin/httpd/src/modules/proxy/mod_proxy.c
+++ b/usr.sbin/httpd/src/modules/proxy/mod_proxy.c
@@ -214,6 +214,9 @@ static int proxy_trans(request_rec *r)
static int proxy_fixup(request_rec *r)
{
char *url, *p;
+#ifdef EAPI
+ int rc;
+#endif /* EAPI */
if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0)
return DECLINED;
@@ -221,6 +224,14 @@ static int proxy_fixup(request_rec *r)
url = &r->filename[6];
/* canonicalise each specific scheme */
+#ifdef EAPI
+ if (ap_hook_use("ap::mod_proxy::canon",
+ AP_HOOK_SIG3(int,ptr,ptr),
+ AP_HOOK_DECLINE(DECLINED),
+ &rc, r, url) && rc != DECLINED)
+ return rc;
+ else
+#endif /* EAPI */
if (strncasecmp(url, "http:", 5) == 0)
return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
else if (strncasecmp(url, "ftp:", 4) == 0)
@@ -238,7 +249,38 @@ static void proxy_init(server_rec *r, pool *p)
ap_proxy_garbage_init(r, p);
}
+#ifdef EAPI
+static void proxy_addmod(module *m)
+{
+ /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */
+ ap_hook_configure("ap::mod_proxy::http::canon",
+ AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_register("ap::mod_proxy::http::canon",
+ ap_proxy_http_canon, AP_HOOK_NOCTX);
+
+ /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */
+ ap_hook_configure("ap::mod_proxy::http::handler",
+ AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
+ ap_hook_register("ap::mod_proxy::http::handler",
+ ap_proxy_http_handler, AP_HOOK_NOCTX);
+
+ /* export: ap_proxyerror() as `ap::mod_proxy::error' */
+ ap_hook_configure("ap::mod_proxy::error",
+ AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST);
+ ap_hook_register("ap::mod_proxy::error",
+ ap_proxyerror, AP_HOOK_NOCTX);
+ return;
+}
+static void proxy_remmod(module *m)
+{
+ /* remove the hook references */
+ ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon);
+ ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler);
+ ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror);
+ return;
+}
+#endif /* EAPI */
/* Send a redirection if the request contains a hostname which is not */
/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
@@ -368,6 +410,14 @@ static int proxy_handler(request_rec *r)
/* CONNECT is a special method that bypasses the normal
* proxy code.
*/
+#ifdef EAPI
+ if (!ap_hook_use("ap::mod_proxy::handler",
+ AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
+ AP_HOOK_DECLINE(DECLINED),
+ &rc, r, cr, url,
+ ents[i].hostname, ents[i].port,
+ ents[i].protocol) || rc == DECLINED) {
+#endif /* EAPI */
if (r->method_number == M_CONNECT)
rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
ents[i].port);
@@ -377,6 +427,9 @@ static int proxy_handler(request_rec *r)
ents[i].port);
else
rc = DECLINED;
+#ifdef EAPI
+ }
+#endif /* EAPI */
/* an error or success */
if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
@@ -390,6 +443,14 @@ static int proxy_handler(request_rec *r)
* give up??
*/
/* handle the scheme */
+#ifdef EAPI
+ if (ap_hook_use("ap::mod_proxy::handler",
+ AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
+ AP_HOOK_DECLINE(DECLINED),
+ &rc, r, cr, url,
+ NULL, 0, scheme) && rc != DECLINED)
+ return rc;
+#endif /* EAPI */
if (r->method_number == M_CONNECT)
return ap_proxy_connect_handler(r, cr, url, NULL, 0);
if (strcasecmp(scheme, "http") == 0)
@@ -895,4 +956,10 @@ module MODULE_VAR_EXPORT proxy_module =
NULL, /* child_init */
NULL, /* child_exit */
proxy_detect /* post read-request */
+#ifdef EAPI
+ ,proxy_addmod, /* EAPI: add_module */
+ proxy_remmod, /* EAPI: remove_module */
+ NULL, /* EAPI: rewrite_command */
+ NULL /* EAPI: new_connection */
+#endif
};
diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_http.c b/usr.sbin/httpd/src/modules/proxy/proxy_http.c
index 2447b96aefe..d43dd1ee112 100644
--- a/usr.sbin/httpd/src/modules/proxy/proxy_http.c
+++ b/usr.sbin/httpd/src/modules/proxy/proxy_http.c
@@ -206,6 +206,12 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
return HTTP_BAD_REQUEST;
urlptr += 3;
destport = DEFAULT_HTTP_PORT;
+#ifdef EAPI
+ ap_hook_use("ap::mod_proxy::http::handler::set_destport",
+ AP_HOOK_SIG2(int,ptr),
+ AP_HOOK_TOPMOST,
+ &destport, r);
+#endif /* EAPI */
strp = strchr(urlptr, '/');
if (strp == NULL) {
desthost = ap_pstrdup(p, urlptr);
@@ -301,13 +307,41 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
f = ap_bcreate(p, B_RDWR | B_SOCKET);
ap_bpushfd(f, sock, sock);
+#ifdef EAPI
+ {
+ char *errmsg = NULL;
+ ap_hook_use("ap::mod_proxy::http::handler::new_connection",
+ AP_HOOK_SIG3(ptr,ptr,ptr),
+ AP_HOOK_DECLINE(NULL),
+ &errmsg, r, f);
+ if (errmsg != NULL)
+ return ap_proxyerror(r, errmsg);
+ }
+#endif /* EAPI */
+
ap_hard_timeout("proxy send", r);
ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
NULL);
+#ifdef EAPI
+ {
+ int rc = DECLINED;
+ ap_hook_use("ap::mod_proxy::http::handler::write_host_header",
+ AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr),
+ AP_HOOK_DECLINE(DECLINED),
+ &rc, r, f, desthost, destport, destportstr);
+ if (rc == DECLINED) {
+ if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
+ ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
+ else
+ ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
+ }
+ }
+#else /* EAPI */
if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
else
ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
+#endif /* EAPI */
if (conf->viaopt == via_block) {
/* Block all outgoing Via: headers */
diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile b/usr.sbin/httpd/src/modules/ssl/Makefile
new file mode 100644
index 00000000000..167ccb839a9
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/Makefile
@@ -0,0 +1,471 @@
+##
+## Apache Makefile, automatically generated by Configure script.
+## Hand-edited changes will be lost if the Configure script is re-run.
+## Sources: - ../../Makefile.config (via /home/beck/src/usr.sbin/httpd/src/obj/Configuration)
+## - ./Makefile.tmpl
+##
+
+##
+## Inherited Makefile options from Configure script
+## (Begin of automatically generated section)
+##
+SRCDIR=../..
+SSL_BASE=SYSTEM
+EXTRA_CFLAGS=
+EXTRA_LDFLAGS=
+EXTRA_LIBS=
+EXTRA_INCLUDES=
+EXTRA_DEPS=
+OSDIR=$(SRCDIR)/os/unix
+INCDIR=$(SRCDIR)/include
+INCLUDES0=-I$(OSDIR) -I$(INCDIR)
+SHELL=/bin/sh
+CC=cc
+CPP=cc -E
+TARGET=httpd
+OPTIM=
+SSL_BASE=SYSTEM
+SSL_BINDIR=/usr/sbin
+SSL_INCDIR=/usr/include/ssl/
+SSL_LIBDIR=/usr/lib
+SSL_PROGRAM=/usr/sbin/ssleay
+SSL_VERSION=-DMOD_SSL_VERSION=\"2.2.3\"
+SSL_CFLAGS= -DSSL_COMPAT -I$(SSL_INCDIR)
+CFLAGS1=-O2 -DMOD_SSL=202103 -DEAPI
+INCLUDES1=
+LIBS_SHLIB=
+LDFLAGS1= -L$(SSL_LIBDIR)
+MFLAGS_STATIC=
+REGLIB=
+RANLIB=ranlib
+LIBS1= -lssl -lcrypto
+##
+## (End of automatically generated section)
+##
+
+##
+## Default Makefile options from Configure script
+## (Begin of automatically generated section)
+##
+CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS)
+LIBS=$(EXTRA_LIBS) $(LIBS1)
+INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES)
+LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS)
+INCDIR=$(SRCDIR)/include
+LIBEXT=a
+##
+## (End of automatically generated section)
+##
+## _ _
+## _ __ ___ ___ __| | ___ ___| |
+## | '_ ` _ \ / _ \ / _` | / __/ __| |
+## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+## |_____|
+## Makefile.tmpl
+## Apache 1.3 Makefile template for SSL module (Unix environment)
+##
+
+## ====================================================================
+## Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following
+## disclaimer in the documentation and/or other materials
+## provided with the distribution.
+##
+## 3. All advertising materials mentioning features or use of this
+## software must display the following acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## 4. The names "mod_ssl" must not be used to endorse or promote
+## products derived from this software without prior written
+## permission. For written permission, please contact
+## rse@engelschall.com.
+##
+## 5. Products derived from this software may not be called "mod_ssl"
+## nor may "mod_ssl" appear in their names without prior
+## written permission of Ralf S. Engelschall.
+##
+## 6. Redistributions of any form whatsoever must retain the following
+## acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+## HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+## OF THE POSSIBILITY OF SUCH DAMAGE.
+## ====================================================================
+##
+ #
+ # ``I cannot write a program which is
+ # as popular as one from Larry Wall.
+ # But I can write one which is from me.''
+ # -- RSE
+
+LIB=libssl.$(LIBEXT)
+
+OBJS=\
+ mod_ssl.o\
+ ssl_engine_config.o\
+ ssl_engine_compat.o\
+ ssl_engine_ds.o\
+ ssl_engine_init.o\
+ ssl_engine_kernel.o\
+ ssl_engine_rand.o\
+ ssl_engine_io.o\
+ ssl_engine_log.o\
+ ssl_engine_mutex.o\
+ ssl_engine_pphrase.o\
+ ssl_engine_scache.o\
+ ssl_engine_vars.o\
+ ssl_engine_ext.o\
+ ssl_expr.o\
+ ssl_expr_scan.o\
+ ssl_expr_parse.o\
+ ssl_expr_eval.o\
+ ssl_util.o\
+ ssl_util_ssl.o\
+ ssl_util_sdbm.o
+
+OBJS_PIC=\
+ mod_ssl.lo\
+ ssl_engine_config.lo\
+ ssl_engine_compat.lo\
+ ssl_engine_ds.lo\
+ ssl_engine_init.lo\
+ ssl_engine_kernel.lo\
+ ssl_engine_rand.lo\
+ ssl_engine_io.lo\
+ ssl_engine_log.lo\
+ ssl_engine_mutex.lo\
+ ssl_engine_pphrase.lo\
+ ssl_engine_scache.lo\
+ ssl_engine_vars.lo\
+ ssl_engine_ext.lo\
+ ssl_expr.lo\
+ ssl_expr_scan.lo\
+ ssl_expr_parse.lo\
+ ssl_expr_eval.lo\
+ ssl_util.lo\
+ ssl_util_ssl.lo\
+ ssl_util_sdbm.lo
+
+##
+## END-USER AREA
+##
+
+all: lib
+
+lib: $(LIB)
+
+libssl.a: $(OBJS)
+ rm -f $@
+ ar cr $@ $(OBJS)
+ $(RANLIB) $@
+
+libssl.so: $(OBJS_PIC)
+ rm -f $@
+ $(LD_SHLIB) $(SSL_LDFLAGS) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC) $(SSL_LIBS) $(LIBS_SHLIB)
+
+.SUFFIXES: .o .lo
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) $(SSL_VERSION) $<
+
+.c.lo:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $(SSL_CFLAGS) $(SSL_VERSION) $< && mv $*.o $*.lo
+
+clean:
+ rm -f $(OBJS) $(OBJS_PIC)
+ rm -f libssl.a libssl.so
+
+realclean: clean
+ rm -f ssl_expr_parse.c ssl_expr_parse.h
+ rm -f ssl_expr_scan.c
+
+distclean: clean
+ -rm -f Makefile
+
+##
+## DEVELOPER AREA
+## We really don't expect end users to use these targets!
+##
+
+ssl_expr_scan.c: ssl_expr_scan.l ssl_expr_parse.h
+ flex -Pssl_expr_yy -s -B ssl_expr_scan.l
+ sed -e '/$$Header:/d' <lex.ssl_expr_yy.c >ssl_expr_scan.c && rm -f lex.ssl_expr_yy.c
+
+ssl_expr_parse.c ssl_expr_parse.h: ssl_expr_parse.y
+ yacc -d -l ssl_expr_parse.y
+ sed -e 's;yy;ssl_expr_yy;g' -e '/yysccsid/d' \
+ <y.tab.c >ssl_expr_parse.c && rm -f y.tab.c
+ sed -e 's;yy;ssl_expr_yy;g' \
+ <y.tab.h >ssl_expr_parse.h && rm -f y.tab.h
+
+noexp:
+ @$(MAKE) $(MFLAGS) $(MFLAGS_STATIC) \
+ SSL_CFLAGS="`echo $(SSL_CFLAGS) |\
+ sed -e 's;-DSSL_EXPERIMENTAL;;'`" all
+
+exp:
+ @$(MAKE) $(MFLAGS) $(MFLAGS_STATIC) \
+ SSL_CFLAGS="`echo $(SSL_CFLAGS) |\
+ sed -e 's;-DSSL_EXPERIMENTAL;;' \
+ -e 's;^;-DSSL_EXPERIMENTAL ;'`" all
+
+depend:
+ cp Makefile.tmpl Makefile.tmpl.bak \
+ && sed -ne '1,/^# DO NOT REMOVE/p' Makefile.tmpl > Makefile.new \
+ && gcc -MM $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) *.c >> Makefile.new \
+ && sed -e '1,$$s; $(INCDIR)/; $$(INCDIR)/;g' \
+ -e '1,$$s; $(OSDIR)/; $$(OSDIR)/;g' \
+ -e '1,$$s;^\([a-z0-9_]*\)\.o:;\1.o \1.lo:;g' Makefile.new \
+ > Makefile.tmpl \
+ && rm Makefile.new
+
+##
+## DEPENDENCY AREA
+##
+
+$(OBJS) $(OBJS_PIC): Makefile
+
+# DO NOT REMOVE
+mod_ssl.o mod_ssl.lo: mod_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_compat.o ssl_engine_compat.lo: ssl_engine_compat.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_config.o ssl_engine_config.lo: ssl_engine_config.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_ds.o ssl_engine_ds.lo: ssl_engine_ds.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_ext.o ssl_engine_ext.lo: ssl_engine_ext.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_init.o ssl_engine_init.lo: ssl_engine_init.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_io.o ssl_engine_io.lo: ssl_engine_io.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_kernel.o ssl_engine_kernel.lo: ssl_engine_kernel.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_log.o ssl_engine_log.lo: ssl_engine_log.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_mutex.o ssl_engine_mutex.lo: ssl_engine_mutex.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_pphrase.o ssl_engine_pphrase.lo: ssl_engine_pphrase.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_rand.o ssl_engine_rand.lo: ssl_engine_rand.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_scache.o ssl_engine_scache.lo: ssl_engine_scache.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_vars.o ssl_engine_vars.lo: ssl_engine_vars.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr.o ssl_expr.lo: ssl_expr.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_eval.o ssl_expr_eval.lo: ssl_expr_eval.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_parse.o ssl_expr_parse.lo: ssl_expr_parse.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_scan.o ssl_expr_scan.lo: ssl_expr_scan.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_expr_parse.h
+ssl_util.o ssl_util.lo: ssl_util.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_util_sdbm.o ssl_util_sdbm.lo: ssl_util_sdbm.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_util_ssl.o ssl_util_ssl.lo: ssl_util_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.libdir b/usr.sbin/httpd/src/modules/ssl/Makefile.libdir
new file mode 100644
index 00000000000..499ce4a3d95
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/Makefile.libdir
@@ -0,0 +1,15 @@
+## _ _
+## _ __ ___ ___ __| | ___ ___| |
+## | '_ ` _ \ / _ \ / _` | / __/ __| |
+## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+## |_____|
+## Makefile.libdir
+## Apache 1.3 Configuration mechanism indicator file
+##
+
+This is a place-holder which indicates to Apache's Configure script that it
+shouldn't provide the default targets when building the Makefile in this
+directory. Instead it'll just prepend all the important variable definitions,
+and copy the Makefile.tmpl onto the end.
+
diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl b/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl
new file mode 100644
index 00000000000..2181e709fe6
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl
@@ -0,0 +1,413 @@
+## _ _
+## _ __ ___ ___ __| | ___ ___| |
+## | '_ ` _ \ / _ \ / _` | / __/ __| |
+## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+## |_____|
+## Makefile.tmpl
+## Apache 1.3 Makefile template for SSL module (Unix environment)
+##
+
+## ====================================================================
+## Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following
+## disclaimer in the documentation and/or other materials
+## provided with the distribution.
+##
+## 3. All advertising materials mentioning features or use of this
+## software must display the following acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## 4. The names "mod_ssl" must not be used to endorse or promote
+## products derived from this software without prior written
+## permission. For written permission, please contact
+## rse@engelschall.com.
+##
+## 5. Products derived from this software may not be called "mod_ssl"
+## nor may "mod_ssl" appear in their names without prior
+## written permission of Ralf S. Engelschall.
+##
+## 6. Redistributions of any form whatsoever must retain the following
+## acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+## HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+## OF THE POSSIBILITY OF SUCH DAMAGE.
+## ====================================================================
+##
+ #
+ # ``I cannot write a program which is
+ # as popular as one from Larry Wall.
+ # But I can write one which is from me.''
+ # -- RSE
+
+LIB=libssl.$(LIBEXT)
+
+OBJS=\
+ mod_ssl.o\
+ ssl_engine_config.o\
+ ssl_engine_compat.o\
+ ssl_engine_ds.o\
+ ssl_engine_init.o\
+ ssl_engine_kernel.o\
+ ssl_engine_rand.o\
+ ssl_engine_io.o\
+ ssl_engine_log.o\
+ ssl_engine_mutex.o\
+ ssl_engine_pphrase.o\
+ ssl_engine_scache.o\
+ ssl_engine_vars.o\
+ ssl_engine_ext.o\
+ ssl_expr.o\
+ ssl_expr_scan.o\
+ ssl_expr_parse.o\
+ ssl_expr_eval.o\
+ ssl_util.o\
+ ssl_util_ssl.o\
+ ssl_util_sdbm.o
+
+OBJS_PIC=\
+ mod_ssl.lo\
+ ssl_engine_config.lo\
+ ssl_engine_compat.lo\
+ ssl_engine_ds.lo\
+ ssl_engine_init.lo\
+ ssl_engine_kernel.lo\
+ ssl_engine_rand.lo\
+ ssl_engine_io.lo\
+ ssl_engine_log.lo\
+ ssl_engine_mutex.lo\
+ ssl_engine_pphrase.lo\
+ ssl_engine_scache.lo\
+ ssl_engine_vars.lo\
+ ssl_engine_ext.lo\
+ ssl_expr.lo\
+ ssl_expr_scan.lo\
+ ssl_expr_parse.lo\
+ ssl_expr_eval.lo\
+ ssl_util.lo\
+ ssl_util_ssl.lo\
+ ssl_util_sdbm.lo
+
+##
+## END-USER AREA
+##
+
+all: lib
+
+lib: $(LIB)
+
+libssl.a: $(OBJS)
+ rm -f $@
+ ar cr $@ $(OBJS)
+ $(RANLIB) $@
+
+libssl.so: $(OBJS_PIC)
+ rm -f $@
+ $(LD_SHLIB) $(SSL_LDFLAGS) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC) $(SSL_LIBS) $(LIBS_SHLIB)
+
+.SUFFIXES: .o .lo
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) $(SSL_VERSION) $<
+
+.c.lo:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $(SSL_CFLAGS) $(SSL_VERSION) $< && mv $*.o $*.lo
+
+clean:
+ rm -f $(OBJS) $(OBJS_PIC)
+ rm -f libssl.a libssl.so
+
+realclean: clean
+ rm -f ssl_expr_parse.c ssl_expr_parse.h
+ rm -f ssl_expr_scan.c
+
+distclean: clean
+ -rm -f Makefile
+
+##
+## DEVELOPER AREA
+## We really don't expect end users to use these targets!
+##
+
+ssl_expr_scan.c: ssl_expr_scan.l ssl_expr_parse.h
+ flex -Pssl_expr_yy -s -B ssl_expr_scan.l
+ sed -e '/$$Header:/d' <lex.ssl_expr_yy.c >ssl_expr_scan.c && rm -f lex.ssl_expr_yy.c
+
+ssl_expr_parse.c ssl_expr_parse.h: ssl_expr_parse.y
+ yacc -d -l ssl_expr_parse.y
+ sed -e 's;yy;ssl_expr_yy;g' -e '/yysccsid/d' \
+ <y.tab.c >ssl_expr_parse.c && rm -f y.tab.c
+ sed -e 's;yy;ssl_expr_yy;g' \
+ <y.tab.h >ssl_expr_parse.h && rm -f y.tab.h
+
+noexp:
+ @$(MAKE) $(MFLAGS) $(MFLAGS_STATIC) \
+ SSL_CFLAGS="`echo $(SSL_CFLAGS) |\
+ sed -e 's;-DSSL_EXPERIMENTAL;;'`" all
+
+exp:
+ @$(MAKE) $(MFLAGS) $(MFLAGS_STATIC) \
+ SSL_CFLAGS="`echo $(SSL_CFLAGS) |\
+ sed -e 's;-DSSL_EXPERIMENTAL;;' \
+ -e 's;^;-DSSL_EXPERIMENTAL ;'`" all
+
+depend:
+ cp Makefile.tmpl Makefile.tmpl.bak \
+ && sed -ne '1,/^# DO NOT REMOVE/p' Makefile.tmpl > Makefile.new \
+ && gcc -MM $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) *.c >> Makefile.new \
+ && sed -e '1,$$s; $(INCDIR)/; $$(INCDIR)/;g' \
+ -e '1,$$s; $(OSDIR)/; $$(OSDIR)/;g' \
+ -e '1,$$s;^\([a-z0-9_]*\)\.o:;\1.o \1.lo:;g' Makefile.new \
+ > Makefile.tmpl \
+ && rm Makefile.new
+
+##
+## DEPENDENCY AREA
+##
+
+$(OBJS) $(OBJS_PIC): Makefile
+
+# DO NOT REMOVE
+mod_ssl.o mod_ssl.lo: mod_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_compat.o ssl_engine_compat.lo: ssl_engine_compat.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_config.o ssl_engine_config.lo: ssl_engine_config.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_ds.o ssl_engine_ds.lo: ssl_engine_ds.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_ext.o ssl_engine_ext.lo: ssl_engine_ext.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_init.o ssl_engine_init.lo: ssl_engine_init.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_io.o ssl_engine_io.lo: ssl_engine_io.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_kernel.o ssl_engine_kernel.lo: ssl_engine_kernel.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_log.o ssl_engine_log.lo: ssl_engine_log.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_mutex.o ssl_engine_mutex.lo: ssl_engine_mutex.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_pphrase.o ssl_engine_pphrase.lo: ssl_engine_pphrase.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_rand.o ssl_engine_rand.lo: ssl_engine_rand.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_scache.o ssl_engine_scache.lo: ssl_engine_scache.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_engine_vars.o ssl_engine_vars.lo: ssl_engine_vars.c mod_ssl.h \
+ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \
+ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \
+ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr.o ssl_expr.lo: ssl_expr.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_eval.o ssl_expr_eval.lo: ssl_expr_eval.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_parse.o ssl_expr_parse.lo: ssl_expr_parse.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_expr_scan.o ssl_expr_scan.lo: ssl_expr_scan.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_expr_parse.h
+ssl_util.o ssl_util.lo: ssl_util.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_util_sdbm.o ssl_util_sdbm.lo: ssl_util_sdbm.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
+ssl_util_ssl.o ssl_util_ssl.lo: ssl_util_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \
+ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \
+ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \
+ $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \
+ $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \
+ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \
+ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \
+ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \
+ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \
+ $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h
diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.win32 b/usr.sbin/httpd/src/modules/ssl/Makefile.win32
new file mode 100644
index 00000000000..3cf7677078d
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/Makefile.win32
@@ -0,0 +1,128 @@
+## _ _
+## _ __ ___ ___ __| | ___ ___| |
+## | '_ ` _ \ / _ \ / _` | / __/ __| |
+## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+## |_____|
+## Makefile.win32
+## Apache 1.3 Makefile for SSL module (Win32 environment)
+##
+
+##
+## ====================================================================
+## Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following
+## disclaimer in the documentation and/or other materials
+## provided with the distribution.
+##
+## 3. All advertising materials mentioning features or use of this
+## software must display the following acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## 4. The names "mod_ssl" must not be used to endorse or promote
+## products derived from this software without prior written
+## permission. For written permission, please contact
+## rse@engelschall.com.
+##
+## 5. Products derived from this software may not be called "mod_ssl"
+## nor may "mod_ssl" appear in their names without prior
+## written permission of Ralf S. Engelschall.
+##
+## 6. Redistributions of any form whatsoever must retain the following
+## acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+## HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+## OF THE POSSIBILITY OF SUCH DAMAGE.
+## ====================================================================
+##
+
+# the following variables are automatically
+# adjusted by the configure.bat script.
+SSLEAY_INC = p:\ssl\work\win32\ssleay\include
+SSLEAY_LIB = p:\ssl\work\win32\ssleay\lib
+MOD_SSL_VERS_NUM = 000000
+MOD_SSL_VERS_STR = 0.0.0
+
+# build tools and flags
+CC = cl.exe
+CFLAGS = /nologo /c /O2 /MD /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS /DSHARED_MODULE /DEAPI
+CFLAGS = $(CFLAGS) /DMOD_SSL=$(MOD_SSL_VERS_NUM) /DMOD_SSL_VERSION=\"$(MOD_SSL_VERS_STR)\"
+CFLAGS = $(CFLAGS) /I..\..\include /I$(SSLEAY_INC)
+LD = link.exe
+LDFLAGS = /nologo
+RM = del
+
+# name and extension of generated mod_ssl library file
+LIBNAME = ApacheModuleSSL
+LIBEXT = dll
+LIBFILE = $(LIBNAME).$(LIBEXT)
+
+# mod_ssl object files
+OBJS=\
+ mod_ssl.obj\
+ ssl_engine_config.obj\
+ ssl_engine_compat.obj\
+ ssl_engine_ds.obj\
+ ssl_engine_init.obj\
+ ssl_engine_kernel.obj\
+ ssl_engine_rand.obj\
+ ssl_engine_io.obj\
+ ssl_engine_log.obj\
+ ssl_engine_mutex.obj\
+ ssl_engine_pphrase.obj\
+ ssl_engine_scache.obj\
+ ssl_engine_vars.obj\
+ ssl_engine_ext.obj\
+ ssl_expr.obj\
+ ssl_expr_scan.obj\
+ ssl_expr_parse.obj\
+ ssl_expr_eval.obj\
+ ssl_util.obj\
+ ssl_util_ssl.obj\
+ ssl_util_sdbm.obj
+
+.c.obj:
+ $(CC) $(CFLAGS) $<
+
+all: $(LIBFILE)
+
+$(LIBNAME).lib: $(OBJS)
+ $(LD) $(LDFLAGS) /lib /out:$@ \
+ $(OBJS)
+
+$(LIBNAME).dll: $(OBJS)
+ $(LD) $(LDFLAGS) /dll /out:$@ \
+ $(OBJS) \
+ ..\..\CoreR\ApacheCore.lib \
+ $(SSLEAY_LIB)\ssleay32.lib \
+ $(SSLEAY_LIB)\libeay32.lib \
+ wsock32.lib
+
+clean:
+ -$(RM) $(LIBFILE)
+ -$(RM) $(OBJS)
+
diff --git a/usr.sbin/httpd/src/modules/ssl/README b/usr.sbin/httpd/src/modules/ssl/README
new file mode 100644
index 00000000000..fc5269acd39
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/README
@@ -0,0 +1,92 @@
+ _ _
+ _ __ ___ ___ __| | ___ ___| |
+ | '_ ` _ \ / _ \ / _` | / __/ __| |
+ | | | | | | (_) | (_| | \__ \__ \ | ``mod_ssl combines the flexibility of
+ |_| |_| |_|\___/ \__,_|___|___/___/_| Apache with the security of SSLeay.''
+ |_____|
+ ``Ralf Engelschall has released an
+ mod_ssl - Apache Interface to SSLeay excellent module that integrates
+ http://www.engelschall.com/sw/mod_ssl/ Apache and SSLeay.''
+ Version 2.1.0-1.3.3 Tim J. Hudson, SSLeay co-author
+
+ This Apache module provides strong cryptography for the Apache 1.3 webserver
+ via the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS
+ v1) protocols by the help of the SSL/TLS implementation library SSLeay from
+ Eric A. Young and Tim J. Hudson. The mod_ssl package was created in April
+ 1998 by Ralf S. Engelschall and was originally derived from software
+ developed by Ben Laurie for use in the Apache-SSL HTTP server project.
+
+ Here is a short overview of the source files:
+
+ Makefile.libdir ......... dummy for Apache config mechanism
+ Makefile.tmpl ........... Makefile template for Unix platform
+ Makefile.win32 .......... Makefile template for Win32 platform
+ libssl.module ........... stub called from the Apache config mechanism
+ libssl.version .......... file containing the mod_ssl version information
+ mod_ssl.c ............... main source file containing API structures
+ mod_ssl.h ............... common header file of mod_ssl
+ ssl_engine_compat.c ..... backward compatibility support
+ ssl_engine_config.c ..... module configuration handling
+ ssl_engine_ds.c ......... data structures
+ ssl_engine_init.c ....... module initialization
+ ssl_engine_kernel.c ..... SSL engine kernel
+ ssl_engine_io.c ......... I/O support
+ ssl_engine_log.c ........ logfile support
+ ssl_engine_mutex.c ...... mutual exclusion support
+ ssl_engine_pphrase.c .... pass-phrase handling
+ ssl_engine_scache.c ..... session cache support
+ ssl_engine_ext.c ........ Extensions to other Apache parts
+ ssl_expr.c .............. expression handling main source
+ ssl_expr.h .............. expression handling common header
+ ssl_expr_scan.c ......... expression scanner automaton (pre-generated)
+ ssl_expr_scan.l ......... expression scanner source
+ ssl_expr_parse.c ........ expression parser automaton (pre-generated)
+ ssl_expr_parse.h ........ expression parser header (pre-generated)
+ ssl_expr_parse.y ........ expression parser source
+ ssl_expr_eval.c ......... expression machine evaluation
+ ssl_util.c .............. utility functions
+ ssl_util_sdbm.c ......... the SDBM library source
+ ssl_util_sdbm.h ......... the SDBM library header
+
+ The source files are written in clean ANSI C and pass the ``gcc -O -g -ggdb3
+ -Wall -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
+ -Wmissing-declarations -Wnested-externs -Winline'' compiler test without any
+ complains. When you make changes or additions make sure the source still
+ passes this compiler test.
+
+ Inside the source code you will be confronted with the following types of
+ functions which can be identified by their prefixes:
+
+ ap_xxxx() ............... Apache API function
+ ssl_xxxx() .............. mod_ssl function
+ SSL_xxxx() .............. SSLeay function (SSL library)
+ SSLeay_xxxx() ........... SSLeay function (SSL library)
+ X509_xxxx() ............. SSLeay function (Crypto library)
+ PEM_xxxx() .............. SSLeay function (Crypto library)
+ EVP_xxxx() .............. SSLeay function (Crypto library)
+ RSA_xxxx() .............. SSLeay function (Crypto library)
+
+ Inside the source code you will be confronted with the following
+ data structures:
+
+ ap_ctx .................. Apache EAPI Context
+ server_rec .............. Apache (Virtual) Server
+ conn_rec ................ Apache Connection
+ BUFF .................... Apache Connection Buffer
+ request_rec ............. Apache Request
+ SSLModConfig ............ mod_ssl (Global) Module Configuration
+ SSLSrvConfig ............ mod_ssl (Virtual) Server Configuration
+ SSLDirConfig ............ mod_ssl Directory Configuration
+ SSL_CTX ................. SSLeay Context
+ SSL_METHOD .............. SSLeay Protocol Method
+ SSL_CIPHER .............. SSLeay Cipher
+ SSL_SESSION ............. SSLeay Session
+ SSL ..................... SSLeay Connection
+ BIO ..................... SSLeay Connection Buffer
+
+ For an overview how these are related and chained together have a look at the
+ page in README.dsov.{fig,ps}. It contains overview diagrams for those data
+ structures. It's designed for DIN A4 paper size, but you can easily generate
+ a smaller version inside XFig by specifing a magnification on the Export
+ panel.
+
diff --git a/usr.sbin/httpd/src/modules/ssl/README.dsov.fig b/usr.sbin/httpd/src/modules/ssl/README.dsov.fig
new file mode 100644
index 00000000000..9a76380718c
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/README.dsov.fig
@@ -0,0 +1,346 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+Letter
+100.00
+Single
+-2
+1200 2
+0 32 #616561
+0 33 #b6b2b6
+0 34 #f7f3f7
+0 35 #cfcfcf
+0 36 #ffffff
+6 6345 2835 7155 3150
+6 6345 2970 7110 3150
+4 0 0 200 0 20 8 0.0000 4 120 750 6345 3105 "ssl_module")\001
+-6
+4 0 0 200 0 20 8 0.0000 4 135 810 6345 2970 ap_ctx_get(...,\001
+-6
+6 10800 2610 12240 3060
+4 0 0 200 0 20 8 0.0000 4 120 1425 10800 2745 ap_get_module_config(...\001
+4 0 0 200 0 20 8 0.0000 4 135 1035 10800 2880 ->per_dir_config,\001
+4 0 0 200 0 20 8 0.0000 4 120 750 10800 3015 &ssl_module)\001
+-6
+6 7920 4770 9135 4995
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 9135 4995 7920 4995 7920 4770 9135 4770 9135 4995
+4 0 0 100 0 18 12 0.0000 4 180 1065 8010 4950 request_rec\001
+-6
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6975 3330 7425 2520
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7200 4230 9450 2520
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7875 4905 7200 5220
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6750 5130 6750 4545
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6705 5445 7155 6120
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7875 4815 7200 4590
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9585 2565 11475 4230
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10170 5130 11835 4545
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7920 6075 9855 5400
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9990 5445 10935 5625
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10215 5310 10935 5310
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11925 4590 11925 5085
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9810 5490 9810 6840
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9945 5445 10935 6030
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 8865 4725 10800 2565
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 675 6075 5850 6075
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 675 6525 675 6075
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 5850 6075 5850 6525
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 900 5625 5625 5625
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 1125 5175 5400 5175
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 1350 4725 5175 4725
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 1575 4275 4950 4275
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 1800 3825 4725 3825
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 2025 3375 4500 3375
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 2250 2925 4275 2925
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 2475 2475 4050 2475
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 2700 2025 3825 2025
+2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2
+ 2925 1575 3600 1575
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 900 6075 900 5625
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1125 6525 1125 5175
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1350 5175 1350 4725
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1575 4725 1575 4275
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 6525 1800 3825
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2025 3825 2025 3375
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2250 3375 2250 2925
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2475 2925 2475 2475
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 5625 5625 5625 6075
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 5400 5175 5400 6525
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 5175 4725 5175 5175
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 4950 4275 4950 4725
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 4725 3825 4725 6525
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 4500 3375 4500 3825
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 4275 2925 4275 3375
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 4050 2475 4050 2925
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2700 6525 2700 2025
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 3825 2025 3825 6525
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 0 1.00 60.00 120.00
+ 3600 1575 3600 2025
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2925 2025 2925 1575
+2 1 0 4 0 0 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 4.00 60.00 120.00
+ 540 6525 6300 6525
+2 3 0 1 7 7 800 0 20 0.000 0 0 -1 0 0 9
+ 675 6525 5850 6525 5850 6075 5625 6075 5625 5625 900 5625
+ 900 6075 675 6075 675 6525
+2 3 0 1 34 34 700 0 20 0.000 0 0 -1 0 0 13
+ 1125 6525 5355 6525 5400 5175 5175 5175 5175 4725 4950 4725
+ 4950 4275 1575 4275 1575 4725 1350 4725 1350 5175 1125 5175
+ 1125 6525
+2 3 0 1 35 35 500 0 20 0.000 0 0 -1 0 0 17
+ 1800 6525 4725 6525 4725 3825 4500 3825 4500 3375 4275 3375
+ 4275 2925 4050 2925 4050 2475 2475 2475 2475 2925 2250 2925
+ 2250 3375 2025 3375 2025 3825 1800 3825 1800 6525
+2 3 0 1 33 33 400 0 20 0.000 0 0 -1 0 0 9
+ 2700 6525 3825 6525 3825 2025 3600 2025 3600 1575 2925 1575
+ 2925 2025 2700 2025 2700 6525
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2
+ 2 0 1.00 60.00 120.00
+ 2 0 1.00 60.00 120.00
+ 2700 6750 3825 6750
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2
+ 2 0 1.00 60.00 120.00
+ 2 0 1.00 60.00 120.00
+ 1125 7200 5400 7200
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2
+ 2 0 1.00 60.00 120.00
+ 2 0 1.00 60.00 120.00
+ 1800 6975 4725 6975
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2
+ 2 0 1.00 60.00 120.00
+ 2 0 1.00 60.00 120.00
+ 675 7425 5850 7425
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 675 6570 675 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 1125 6570 1125 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 1800 6570 1800 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 2700 6570 2700 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 3825 6570 3825 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 4725 6570 4725 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 5400 6570 5400 7650
+2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2
+ 5850 6570 5850 7650
+2 4 0 2 0 7 100 0 -1 0.000 0 0 20 0 0 5
+ 12600 8550 450 8550 450 225 12600 225 12600 8550
+2 4 0 1 0 34 200 0 20 0.000 0 0 20 0 0 5
+ 12600 1350 450 1350 450 225 12600 225 12600 1350
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 10170 2475 8775 2475 8775 2250 10170 2250 10170 2475
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 11925 2475 10575 2475 10575 2250 11925 2250 11925 2475
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 12375 4500 11430 4500 11430 4275 12375 4275 12375 4500
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 12375 5400 10980 5400 10980 5175 12375 5175 12375 5400
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 10170 5400 9675 5400 9675 5175 10170 5175 10170 5400
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 7875 6300 7200 6300 7200 6075 7875 6075 7875 6300
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 8190 2475 6750 2475 6750 2250 8190 2250 8190 2475
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 7605 3600 6300 3600 6300 3375 7605 3375 7605 3600
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 7335 4500 6300 4500 6300 4275 7335 4275 7335 4500
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 7200 5400 6300 5400 6300 5175 7200 5175 7200 5400
+2 1 0 6 7 7 600 0 -1 0.000 0 0 -1 0 0 2
+ 9450 4500 6075 1935
+2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2
+ 9450 4500 12465 2205
+2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2
+ 9450 4500 9450 7785
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9630 5310 7245 5310
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11385 4365 7380 4365
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 12240 5805 10980 5805 10980 5580 12240 5580 12240 5805
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 12375 6210 10980 6210 10980 5985 12375 5985 12375 6210
+2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11205 6885 9900 5445
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 12285 7155 10530 7155 10530 6930 12285 6930 12285 7155
+2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5
+ 10170 7155 9630 7155 9630 6930 10170 6930 10170 7155
+2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2
+ 12510 6435 9450 6435
+2 1 0 1 0 34 300 0 20 0.000 0 0 7 1 0 4
+ 1 1 1.00 60.00 120.00
+ 12375 4455 12510 4635 12510 6210 11970 6885
+2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9850 5143 9175 4918
+3 1 0 1 34 34 800 0 20 0.000 0 0 0 41
+ 7380 1710 6390 2115 5535 2115 6075 3015 5670 3465 6165 3915
+ 5715 4410 6030 5040 6030 5310 6480 5715 6390 6255 6975 6300
+ 7065 6975 7965 6750 8100 7560 8955 7290 9360 7740 9720 7560
+ 10755 8145 12060 8280 12375 7650 12420 7200 12510 7065 12330 6660
+ 12510 6390 12420 5940 12375 5400 12510 5220 12510 4725 12600 4275
+ 12375 3645 12105 3240 12150 2745 12375 2700 12330 1980 11790 1575
+ 11250 1935 10125 1485 8955 2070 7785 1620 7695 1575
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000
+4 0 0 100 0 0 12 0.0000 4 180 1440 10575 675 Ralf S. Engelschall\001
+4 0 0 100 0 18 20 0.0000 4 270 3600 4275 675 Apache+mod_ssl+SSLeay\001
+4 0 0 100 0 0 10 0.0000 4 135 1320 10575 855 rse@engelschall.com\001
+4 0 0 100 0 0 10 0.0000 4 135 1410 10575 1035 www.engelschall.com\001
+4 0 0 100 0 0 12 0.0000 4 135 870 900 675 Version 1.3\001
+4 0 0 100 0 0 12 0.0000 4 135 1005 900 855 27-Jan-1998\001
+4 0 0 200 0 20 8 0.0000 4 75 510 6210 4680 ->server\001
+4 0 0 200 0 20 8 0.0000 4 135 1095 8280 6120 ap_ctx_get(...,"ssl")\001
+4 0 0 200 0 20 8 0.0000 4 120 1425 7740 2700 ap_get_module_config(...\001
+4 0 0 200 0 20 8 0.0000 4 135 1020 7740 2835 ->module_config,\001
+4 0 0 200 0 20 8 0.0000 4 120 750 7740 2970 &ssl_module)\001
+4 0 0 100 0 18 20 0.0000 4 270 1200 9000 8100 Chaining\001
+4 0 0 100 0 18 20 0.0000 4 210 1095 2745 8100 Lifetime\001
+4 0 0 100 0 18 12 0.0000 4 180 1215 810 6255 ap_global_ctx\001
+4 0 0 100 0 18 12 0.0000 4 180 1305 990 5805 SSLModConfig\001
+4 0 0 100 0 18 12 0.0000 4 180 840 4050 4455 SSL_CTX\001
+4 0 0 100 0 18 12 0.0000 4 150 975 4455 5355 server_rec\001
+4 0 0 100 0 18 12 0.0000 4 180 1260 3870 4905 SSLSrvConfig\001
+4 0 0 100 0 18 12 0.0000 4 135 480 1845 4005 BUFF\001
+4 0 0 100 0 18 12 0.0000 4 150 810 2070 3555 conn_rec\001
+4 0 0 100 0 18 12 0.0000 4 135 345 2295 3105 BIO\001
+4 0 0 100 0 18 12 0.0000 4 135 375 2565 2655 SSL\001
+4 0 0 100 0 18 12 0.0000 4 180 1185 3645 1620 SSLDirConfig\001
+4 0 0 100 0 18 12 0.0000 4 180 1065 3915 2070 request_rec\001
+4 0 0 200 0 0 8 0.0000 4 120 1440 900 7560 Startup, Runtime, Shutdown\001
+4 0 0 200 0 0 8 0.0000 4 105 975 1350 7335 Configuration Time\001
+4 0 0 200 0 0 8 0.0000 4 90 1050 2025 7110 Connection Duration\001
+4 0 0 200 0 0 8 0.0000 4 120 885 2835 6885 Request Duration\001
+4 0 0 200 0 18 20 0.0000 4 195 90 6345 6795 t\001
+4 0 0 200 0 20 8 0.0000 4 105 465 7110 5985 ->client\001
+4 0 0 100 0 18 12 0.0000 4 180 1305 6795 2430 SSLModConfig\001
+4 0 0 100 0 18 12 0.0000 4 180 1260 8865 2430 SSLSrvConfig\001
+4 0 0 100 0 18 12 0.0000 4 180 1215 6345 3555 ap_global_ctx\001
+4 0 0 100 0 18 12 0.0000 4 150 975 6345 4455 server_rec\001
+4 0 0 100 0 18 12 0.0000 4 150 810 6345 5355 conn_rec\001
+4 0 0 100 0 18 12 0.0000 4 135 375 9720 5355 SSL\001
+4 0 0 100 0 18 12 0.0000 4 180 1185 10665 2430 SSLDirConfig\001
+4 0 0 100 0 18 12 0.0000 4 135 480 7290 6255 BUFF\001
+4 0 0 100 0 18 12 0.0000 4 180 1305 11025 5355 SSL_METHOD\001
+4 0 0 100 0 18 12 0.0000 4 180 840 11475 4455 SSL_CTX\001
+4 0 0 100 0 18 24 0.0000 4 285 4365 3915 1080 Data Structure Overview\001
+4 0 0 200 0 20 8 0.0000 4 105 795 7065 5085 ->connection\001
+4 0 0 200 0 20 8 0.0000 4 75 510 7065 4770 ->server\001
+4 0 0 200 0 20 8 0.0000 4 120 1200 8010 5445 SSL_get_app_data()\001
+4 0 0 200 0 20 8 0.0000 4 120 705 10530 4050 ->pSSLCtx\001
+4 0 0 200 0 20 8 0.0000 4 120 1515 7875 4275 SSL_CTX_get_app_data()\001
+4 0 0 200 0 20 8 0.0000 4 120 1485 10305 5535 SSL_get_current_cipher()\001
+4 0 0 100 0 18 12 0.0000 4 180 1170 11025 5760 SSL_CIPHER\001
+4 0 0 100 0 18 12 0.0000 4 180 1350 10980 6165 SSL_SESSION\001
+4 0 0 200 0 20 8 0.0000 4 120 1095 10440 5940 SSL_get_session()\001
+4 0 0 100 0 18 12 0.0000 4 180 1665 10575 7110 X509_STORE_CTX\001
+4 0 0 100 0 18 12 0.0000 4 135 345 9720 7110 BIO\001
+4 0 0 200 0 20 8 0.0000 4 135 1080 9540 7335 SSL_get_{r,w}bio()\001
+4 0 0 100 0 18 12 0.0000 4 180 720 10935 7785 [Crypto]\001
+4 0 0 100 0 18 20 0.0000 4 270 1050 10935 7605 SSLeay\001
+4 0 0 100 0 18 20 0.0000 4 270 1050 11115 3645 SSLeay\001
+4 0 0 100 0 18 12 0.0000 4 180 495 11115 3825 [SSL]\001
+4 0 0 100 0 18 20 0.0000 4 270 1170 8730 3465 mod_ssl\001
+4 0 0 100 0 18 20 0.0000 4 270 1050 8145 6750 Apache\001
+4 0 0 200 0 20 8 0.0000 4 120 1245 10125 4680 SSL_get_SSL_CTX()\001
+4 0 0 200 0 20 8 0.0000 4 120 1530 10350 5175 SSL_get_SSL_METHOD()\001
+4 0 0 200 0 20 8 0.0000 4 105 585 11745 4770 ->method\001
+4 0 0 200 0 20 8 0.0000 4 120 2070 9945 6480 X509_STORE_CTX_get_app_data()\001
+4 0 0 200 0 20 8 0.0000 4 120 1560 10980 6705 SSL_CTX_get_cert_store()\001
+4 0 0 200 0 20 8 0.0000 4 120 1275 8280 5130 SSL_get_app_data2()\001
diff --git a/usr.sbin/httpd/src/modules/ssl/README.dsov.ps b/usr.sbin/httpd/src/modules/ssl/README.dsov.ps
new file mode 100644
index 00000000000..73ddf39aa2d
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/README.dsov.ps
@@ -0,0 +1,1138 @@
+%!PS-Adobe-2.0
+%%Title: README.dsov.ps
+%%Creator: fig2dev Version 3.2 Patchlevel 1
+%%CreationDate: Thu Jan 28 11:08:27 1999
+%%For: rse@en1.engelschall.com (Ralf S. Engelschall)
+%%Orientation: Landscape
+%%BoundingBox: 42 11 570 781
+%%Pages: 1
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+/col32 {0.380 0.396 0.380 srgb} bind def
+/col33 {0.714 0.698 0.714 srgb} bind def
+/col34 {0.969 0.953 0.969 srgb} bind def
+/col35 {0.812 0.812 0.812 srgb} bind def
+/col36 {1.000 1.000 1.000 srgb} bind def
+
+end
+save
+30.0 -15.0 translate
+ 90 rotate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Times-Roman /Times-Roman-iso isovec ReEncode
+/Helvetica-Bold /Helvetica-Bold-iso isovec ReEncode
+/Helvetica-Narrow /Helvetica-Narrow-iso isovec ReEncode
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n -1000 9572 m -1000 -1000 l 13622 -1000 l 13622 9572 l cp clip
+ 0.06299 0.06299 sc
+%%Page: 1 1
+% Polyline
+7.500 slw
+n 6413 2048 m 6380 2054 l 6348 2061 l 6315 2067 l 6283 2073 l 6250 2079 l
+ 6217 2084 l 6185 2090 l 6152 2095 l 6120 2101 l 6088 2107 l
+ 6057 2113 l 6027 2120 l 5998 2126 l 5970 2134 l 5943 2141 l
+ 5918 2149 l 5894 2158 l 5873 2167 l 5853 2177 l 5835 2187 l
+ 5819 2198 l 5805 2210 l 5793 2222 l 5782 2235 l 5774 2250 l
+ 5768 2265 l 5763 2281 l 5760 2299 l 5759 2318 l 5759 2339 l
+ 5761 2360 l 5764 2383 l 5768 2408 l 5774 2433 l 5780 2460 l
+ 5788 2488 l 5797 2516 l 5806 2546 l 5815 2575 l 5825 2606 l
+ 5836 2636 l 5846 2666 l 5856 2696 l 5866 2726 l 5875 2755 l
+ 5884 2784 l 5892 2812 l 5899 2839 l 5905 2866 l 5910 2891 l
+ 5915 2916 l 5918 2940 l 5919 2968 l 5920 2995 l 5919 3022 l
+ 5916 3048 l 5912 3075 l 5908 3101 l 5902 3127 l 5895 3153 l
+ 5887 3179 l 5880 3205 l 5871 3230 l 5863 3254 l 5855 3278 l
+ 5848 3302 l 5841 3324 l 5834 3346 l 5829 3367 l 5824 3388 l
+ 5821 3408 l 5819 3427 l 5819 3446 l 5820 3465 l 5823 3484 l
+ 5827 3503 l 5833 3522 l 5840 3542 l 5848 3562 l 5858 3582 l
+ 5868 3603 l 5880 3625 l 5891 3647 l 5904 3669 l 5916 3691 l
+ 5929 3713 l 5941 3736 l 5953 3758 l 5964 3779 l 5974 3801 l
+ 5983 3822 l 5991 3843 l 5997 3863 l 6002 3883 l 6006 3903 l
+ 6008 3923 l 6008 3942 l 6006 3962 l 6003 3983 l 5998 4004 l
+ 5992 4025 l 5985 4048 l 5977 4070 l 5968 4094 l 5958 4118 l
+ 5947 4142 l 5936 4167 l 5925 4192 l 5913 4216 l 5902 4241 l
+ 5892 4266 l 5882 4291 l 5872 4315 l 5864 4339 l 5857 4362 l
+ 5851 4386 l 5846 4409 l 5843 4433 l 5840 4456 l 5840 4480 l
+ 5840 4505 l 5842 4530 l 5845 4556 l 5849 4582 l 5854 4609 l
+ 5860 4636 l 5867 4664 l 5875 4692 l 5883 4720 l 5892 4747 l
+ 5901 4774 l 5910 4801 l 5920 4827 l 5929 4852 l 5938 4875 l
+ 5947 4898 l 5955 4920 l 5963 4941 l 5971 4961 l 5978 4980 l
+ 5985 5002 l 5992 5024 l 5999 5046 l 6005 5067 l 6010 5088 l
+ 6016 5109 l 6022 5129 l 6027 5150 l 6033 5170 l 6039 5190 l
+ 6045 5209 l 6052 5228 l 6059 5246 l 6067 5264 l 6075 5281 l
+ 6084 5298 l 6094 5315 l 6105 5333 l 6115 5347 l 6125 5361 l
+ 6137 5376 l 6149 5392 l 6162 5408 l 6176 5425 l 6191 5443 l
+ 6206 5461 l 6221 5480 l 6237 5499 l 6253 5519 l 6269 5539 l
+ 6284 5559 l 6299 5579 l 6313 5599 l 6327 5619 l 6340 5639 l
+ 6352 5659 l 6363 5679 l 6373 5698 l 6382 5718 l 6390 5738 l
+ 6398 5759 l 6404 5782 l 6410 5805 l 6415 5828 l 6420 5852 l
+ 6424 5877 l 6428 5902 l 6431 5927 l 6435 5952 l 6438 5977 l
+ 6442 6001 l 6446 6025 l 6450 6048 l 6455 6069 l 6461 6090 l
+ 6467 6109 l 6474 6127 l 6483 6143 l 6492 6159 l 6503 6173 l
+ 6515 6185 l 6528 6197 l 6543 6209 l 6560 6220 l 6578 6230 l
+ 6598 6240 l 6619 6250 l 6641 6260 l 6663 6270 l 6687 6281 l
+ 6710 6291 l 6733 6302 l 6757 6312 l 6779 6324 l 6801 6335 l
+ 6821 6348 l 6841 6361 l 6859 6374 l 6876 6389 l 6893 6405 l
+ 6906 6421 l 6919 6437 l 6932 6455 l 6944 6475 l 6955 6495 l
+ 6967 6516 l 6979 6538 l 6991 6561 l 7003 6584 l 7015 6608 l
+ 7027 6631 l 7040 6654 l 7053 6677 l 7067 6699 l 7081 6720 l
+ 7096 6739 l 7111 6758 l 7127 6774 l 7144 6789 l 7161 6803 l
+ 7180 6815 l 7200 6825 l 7220 6833 l 7240 6840 l 7263 6845 l
+ 7286 6850 l 7311 6854 l 7338 6857 l 7365 6859 l 7394 6861 l
+ 7424 6862 l 7454 6864 l 7485 6865 l 7516 6866 l 7547 6867 l
+ 7578 6868 l 7609 6870 l 7639 6872 l 7668 6875 l 7696 6879 l
+ 7723 6883 l 7748 6889 l 7773 6895 l 7795 6903 l 7817 6912 l
+ 7838 6923 l 7857 6934 l 7875 6948 l 7892 6963 l 7909 6980 l
+ 7926 6998 l 7941 7017 l 7957 7038 l 7972 7060 l 7987 7083 l
+ 8002 7106 l 8017 7130 l 8031 7154 l 8046 7178 l 8061 7202 l
+ 8075 7225 l 8090 7247 l 8105 7269 l 8120 7289 l 8135 7308 l
+ 8151 7326 l 8167 7342 l 8184 7356 l 8202 7369 l 8220 7380 l
+ 8239 7390 l 8260 7397 l 8282 7404 l 8305 7409 l 8330 7413 l
+ 8356 7416 l 8383 7418 l 8412 7420 l 8441 7420 l 8471 7419 l
+ 8502 7418 l 8534 7417 l 8565 7415 l 8597 7413 l 8629 7411 l
+ 8660 7409 l 8690 7407 l 8720 7405 l 8749 7404 l 8777 7404 l
+ 8804 7404 l 8830 7405 l 8856 7407 l 8880 7410 l 8906 7414 l
+ 8931 7420 l 8956 7427 l 8981 7435 l 9005 7444 l 9029 7455 l
+ 9053 7466 l 9077 7478 l 9100 7491 l 9123 7504 l 9146 7517 l
+ 9168 7531 l 9190 7544 l 9210 7557 l 9230 7570 l 9250 7582 l
+ 9268 7593 l 9286 7604 l 9304 7613 l 9320 7621 l 9336 7629 l
+ 9353 7635 l 9370 7641 l 9388 7645 l 9406 7648 l 9425 7650 l
+ 9444 7652 l 9464 7653 l 9485 7653 l 9508 7653 l 9531 7653 l
+ 9555 7653 l 9579 7653 l 9605 7654 l 9631 7655 l 9658 7656 l
+ 9685 7659 l 9713 7662 l 9742 7666 l 9771 7672 l 9801 7679 l
+ 9833 7688 l 9853 7694 l 9874 7700 l 9895 7708 l 9918 7716 l
+ 9941 7725 l 9966 7734 l 9991 7745 l 10017 7755 l 10045 7767 l
+ 10073 7779 l 10102 7791 l 10132 7804 l 10163 7818 l 10194 7831 l
+ 10227 7845 l 10259 7860 l 10293 7874 l 10326 7889 l 10360 7903 l
+ 10394 7918 l 10429 7932 l 10463 7947 l 10497 7961 l 10531 7974 l
+ 10565 7988 l 10599 8001 l 10633 8013 l 10667 8025 l 10700 8037 l
+ 10733 8049 l 10767 8059 l 10800 8070 l 10834 8080 l 10868 8090 l
+ 10902 8099 l 10937 8108 l 10973 8117 l 11009 8125 l 11045 8133 l
+ 11083 8141 l 11120 8148 l 11158 8155 l 11197 8161 l 11236 8167 l
+ 11275 8172 l 11313 8177 l 11352 8181 l 11391 8184 l 11429 8187 l
+ 11467 8190 l 11504 8191 l 11540 8192 l 11576 8192 l 11610 8192 l
+ 11644 8191 l 11676 8189 l 11707 8187 l 11738 8184 l 11767 8180 l
+ 11794 8176 l 11821 8171 l 11847 8165 l 11871 8159 l 11895 8153 l
+ 11923 8143 l 11950 8133 l 11976 8122 l 12001 8109 l 12025 8096 l
+ 12048 8081 l 12071 8065 l 12092 8048 l 12113 8031 l 12133 8012 l
+ 12153 7992 l 12171 7972 l 12188 7951 l 12205 7930 l 12220 7909 l
+ 12235 7887 l 12248 7865 l 12260 7843 l 12272 7822 l 12282 7800 l
+ 12292 7779 l 12301 7759 l 12309 7739 l 12316 7719 l 12323 7699 l
+ 12330 7680 l 12338 7655 l 12345 7631 l 12352 7607 l 12359 7582 l
+ 12365 7558 l 12371 7533 l 12377 7508 l 12382 7484 l 12388 7460 l
+ 12392 7436 l 12397 7414 l 12401 7391 l 12405 7370 l 12409 7350 l
+ 12412 7331 l 12415 7313 l 12418 7297 l 12421 7281 l 12424 7266 l
+ 12428 7253 l 12432 7234 l 12437 7216 l 12442 7199 l 12446 7183 l
+ 12451 7166 l 12456 7150 l 12460 7134 l 12463 7117 l 12466 7101 l
+ 12468 7086 l 12469 7070 l 12469 7054 l 12467 7037 l 12465 7020 l
+ 12462 7006 l 12459 6991 l 12455 6975 l 12450 6958 l 12445 6940 l
+ 12440 6921 l 12434 6901 l 12428 6880 l 12422 6859 l 12416 6838 l
+ 12411 6817 l 12406 6796 l 12401 6776 l 12397 6756 l 12394 6736 l
+ 12392 6718 l 12390 6700 l 12390 6683 l 12390 6665 l 12392 6649 l
+ 12394 6631 l 12397 6614 l 12401 6597 l 12406 6579 l 12411 6561 l
+ 12416 6542 l 12422 6524 l 12428 6505 l 12434 6487 l 12440 6468 l
+ 12445 6450 l 12450 6432 l 12455 6414 l 12459 6396 l 12462 6378 l
+ 12465 6360 l 12467 6343 l 12468 6326 l 12469 6308 l 12469 6289 l
+ 12468 6269 l 12468 6249 l 12466 6227 l 12464 6205 l 12462 6182 l
+ 12460 6159 l 12457 6135 l 12454 6111 l 12451 6087 l 12447 6063 l
+ 12444 6040 l 12441 6016 l 12437 5993 l 12434 5970 l 12431 5948 l
+ 12428 5925 l 12424 5902 l 12421 5879 l 12419 5855 l 12416 5831 l
+ 12413 5806 l 12411 5781 l 12408 5755 l 12406 5729 l 12404 5702 l
+ 12403 5676 l 12401 5651 l 12400 5625 l 12400 5601 l 12399 5578 l
+ 12399 5555 l 12400 5534 l 12401 5514 l 12402 5495 l 12403 5477 l
+ 12405 5460 l 12408 5440 l 12411 5421 l 12416 5402 l 12420 5384 l
+ 12426 5365 l 12431 5347 l 12437 5329 l 12444 5311 l 12450 5293 l
+ 12456 5275 l 12462 5258 l 12468 5240 l 12474 5222 l 12479 5205 l
+ 12483 5186 l 12488 5168 l 12490 5152 l 12493 5135 l 12496 5117 l
+ 12498 5099 l 12500 5079 l 12502 5058 l 12504 5036 l 12506 5014 l
+ 12507 4990 l 12509 4966 l 12510 4942 l 12512 4918 l 12513 4893 l
+ 12515 4869 l 12516 4845 l 12518 4822 l 12520 4799 l 12521 4776 l
+ 12523 4754 l 12525 4733 l 12527 4713 l 12529 4693 l 12531 4673 l
+ 12534 4653 l 12536 4632 l 12539 4610 l 12541 4588 l 12543 4566 l
+ 12546 4543 l 12548 4520 l 12550 4497 l 12552 4473 l 12553 4450 l
+ 12554 4426 l 12555 4403 l 12555 4380 l 12555 4357 l 12555 4334 l
+ 12554 4312 l 12552 4290 l 12550 4267 l 12548 4245 l 12545 4224 l
+ 12541 4203 l 12537 4181 l 12533 4159 l 12528 4136 l 12523 4112 l
+ 12517 4088 l 12510 4064 l 12503 4038 l 12496 4013 l 12488 3987 l
+ 12479 3961 l 12471 3935 l 12462 3909 l 12452 3884 l 12443 3859 l
+ 12434 3835 l 12424 3811 l 12415 3788 l 12405 3766 l 12396 3744 l
+ 12386 3723 l 12377 3702 l 12368 3683 l 12357 3661 l 12347 3640 l
+ 12336 3619 l 12325 3598 l 12314 3576 l 12303 3555 l 12291 3533 l
+ 12280 3511 l 12269 3489 l 12257 3467 l 12246 3446 l 12235 3424 l
+ 12225 3402 l 12215 3381 l 12206 3360 l 12197 3340 l 12189 3320 l
+ 12181 3301 l 12174 3281 l 12168 3262 l 12162 3244 l 12158 3225 l
+ 12153 3204 l 12149 3183 l 12145 3162 l 12142 3139 l 12140 3117 l
+ 12138 3094 l 12137 3071 l 12137 3047 l 12138 3024 l 12139 3001 l
+ 12141 2978 l 12143 2956 l 12146 2935 l 12150 2915 l 12154 2896 l
+ 12158 2879 l 12163 2862 l 12168 2847 l 12174 2833 l 12180 2820 l
+ 12188 2805 l 12197 2792 l 12206 2779 l 12216 2766 l 12227 2754 l
+ 12238 2742 l 12249 2730 l 12260 2717 l 12272 2704 l 12282 2691 l
+ 12292 2676 l 12302 2661 l 12310 2645 l 12318 2627 l 12324 2608 l
+ 12330 2588 l 12334 2571 l 12336 2553 l 12339 2534 l 12341 2513 l
+ 12342 2491 l 12343 2467 l 12343 2442 l 12342 2416 l 12340 2389 l
+ 12338 2360 l 12335 2332 l 12331 2303 l 12326 2273 l 12320 2244 l
+ 12314 2215 l 12307 2187 l 12299 2159 l 12290 2132 l 12280 2106 l
+ 12270 2081 l 12259 2056 l 12248 2033 l 12236 2011 l 12224 1990 l
+ 12210 1970 l 12196 1949 l 12181 1929 l 12164 1910 l 12147 1890 l
+ 12129 1871 l 12110 1853 l 12090 1835 l 12070 1818 l 12049 1802 l
+ 12027 1787 l 12005 1773 l 11983 1761 l 11961 1749 l 11939 1739 l
+ 11917 1730 l 11895 1722 l 11874 1716 l 11852 1710 l 11831 1707 l
+ 11811 1704 l 11790 1703 l 11769 1702 l 11748 1703 l 11727 1705 l
+ 11706 1708 l 11683 1711 l 11660 1716 l 11636 1721 l 11612 1727 l
+ 11587 1733 l 11560 1740 l 11534 1747 l 11506 1754 l 11479 1761 l
+ 11450 1768 l 11422 1774 l 11393 1780 l 11364 1786 l 11334 1791 l
+ 11305 1795 l 11275 1798 l 11245 1800 l 11215 1801 l 11184 1801 l
+ 11153 1800 l 11128 1798 l 11104 1796 l 11078 1793 l 11052 1790 l
+ 11025 1785 l 10997 1781 l 10968 1776 l 10939 1770 l 10908 1764 l
+ 10877 1758 l 10844 1751 l 10811 1744 l 10778 1737 l 10743 1730 l
+ 10708 1722 l 10673 1715 l 10637 1708 l 10601 1701 l 10565 1695 l
+ 10530 1688 l 10494 1682 l 10458 1677 l 10422 1672 l 10387 1668 l
+ 10352 1664 l 10318 1661 l 10284 1658 l 10250 1657 l 10216 1656 l
+ 10183 1655 l 10150 1656 l 10118 1658 l 10087 1660 l 10055 1663 l
+ 10024 1666 l 9992 1671 l 9960 1676 l 9927 1682 l 9894 1688 l
+ 9861 1695 l 9827 1703 l 9792 1711 l 9757 1720 l 9721 1729 l
+ 9685 1738 l 9649 1748 l 9613 1757 l 9576 1767 l 9539 1778 l
+ 9502 1788 l 9465 1798 l 9429 1807 l 9392 1817 l 9356 1826 l
+ 9320 1835 l 9285 1844 l 9250 1852 l 9216 1860 l 9182 1867 l
+ 9148 1873 l 9115 1879 l 9082 1884 l 9050 1889 l 9018 1892 l
+ 8987 1895 l 8955 1898 l 8919 1899 l 8883 1900 l 8847 1899 l
+ 8811 1898 l 8774 1896 l 8737 1893 l 8699 1889 l 8661 1884 l
+ 8623 1878 l 8585 1872 l 8546 1865 l 8508 1857 l 8470 1849 l
+ 8432 1840 l 8395 1830 l 8358 1821 l 8322 1811 l 8287 1801 l
+ 8254 1790 l 8221 1780 l 8189 1770 l 8159 1760 l 8130 1750 l
+ 8102 1740 l 8076 1730 l 8051 1721 l 8028 1712 l 8006 1703 l
+ 7985 1695 l 7965 1688 l 7931 1674 l 7899 1662 l 7871 1650 l
+ 7844 1640 l 7820 1631 l 7798 1623 l 7778 1617 l 7760 1611 l
+ 7743 1607 l 7728 1603 l 7715 1601 l 7702 1600 l 7691 1600 l
+ 7680 1601 l 7669 1603 l 7658 1605 l 7648 1607 l 7638 1610 l
+ 7627 1613 l 7615 1617 l 7601 1621 l 7587 1626 l 7571 1632 l
+ 7554 1638 l 7536 1645 l 7517 1653 l 7496 1661 l 7474 1670 l
+ 7452 1679 l 7428 1689 l 7403 1699 l 7378 1709 l 7352 1720 l
+ 7325 1731 l 7297 1743 l 7268 1755 l 7247 1763 l 7226 1772 l
+ 7204 1781 l 7182 1790 l 7158 1800 l 7133 1810 l 7108 1820 l
+ 7081 1831 l 7053 1842 l 7025 1853 l 6996 1864 l 6966 1875 l
+ 6935 1886 l 6904 1898 l 6873 1909 l 6841 1921 l 6809 1932 l
+ 6776 1943 l 6744 1954 l 6712 1964 l 6680 1974 l 6649 1984 l
+ 6618 1994 l 6587 2003 l 6557 2011 l 6527 2019 l 6498 2027 l
+ 6469 2034 l 6441 2041 l cp gs col34 1.00 shd ef gr gs col34 s gr
+% Polyline
+n 675 6525 m 5850 6525 l 5850 6075 l 5625 6075 l 5625 5625 l 900 5625 l
+ 900 6075 l 675 6075 l cp gs col7 1.00 shd ef gr gs col7 s gr
+% Polyline
+n 1125 6525 m 5355 6525 l 5400 5175 l 5175 5175 l 5175 4725 l 4950 4725 l
+ 4950 4275 l 1575 4275 l 1575 4725 l 1350 4725 l 1350 5175 l
+ 1125 5175 l cp gs col34 1.00 shd ef gr gs col34 s gr
+% Polyline
+75.000 slw
+n 9450 4500 m 12465 2205 l gs col7 s gr
+% Polyline
+n 9450 4500 m 9450 7785 l gs col7 s gr
+% Polyline
+n 9450 4500 m 6075 1935 l gs col7 s gr
+% Polyline
+n 12510 6435 m 9450 6435 l gs col7 s gr
+% Polyline
+7.500 slw
+n 1800 6525 m 4725 6525 l 4725 3825 l 4500 3825 l 4500 3375 l 4275 3375 l
+ 4275 2925 l 4050 2925 l 4050 2475 l 2475 2475 l 2475 2925 l
+ 2250 2925 l 2250 3375 l 2025 3375 l 2025 3825 l 1800 3825 l
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 2700 6525 m 3825 6525 l 3825 2025 l 3600 2025 l 3600 1575 l 2925 1575 l
+ 2925 2025 l 2700 2025 l cp gs col33 1.00 shd ef gr gs col33 s gr
+% Polyline
+gs clippath
+12068 6810 m 11970 6885 l 12022 6773 l 11937 6878 l 11984 6915 l cp
+clip
+n 12375 4455 m 12510 4635 l 12510 6210 l 11970 6885 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 12068 6810 m 11970 6885 l 12022 6773 l 12045 6791 l 12068 6810 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7113 6004 m 7155 6120 l 7063 6037 l 7138 6149 l 7188 6116 l cp
+clip
+n 6705 5445 m 7155 6120 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7113 6004 m 7155 6120 l 7063 6037 l 7088 6020 l 7113 6004 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7304 4656 m 7200 4590 l 7323 4599 l 7195 4557 l 7176 4614 l cp
+clip
+n 7875 4815 m 7200 4590 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7304 4656 m 7200 4590 l 7323 4599 l 7314 4628 l 7304 4656 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11405 4128 m 11475 4230 l 11365 4173 l 11466 4262 l 11506 4217 l cp
+clip
+n 9585 2565 m 11475 4230 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 11405 4128 m 11475 4230 l 11365 4173 l 11385 4151 l 11405 4128 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11712 4556 m 11835 4545 l 11732 4613 l 11859 4568 l 11839 4512 l cp
+clip
+n 10170 5130 m 11835 4545 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 11712 4556 m 11835 4545 l 11732 4613 l 11722 4585 l 11712 4556 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+9732 5411 m 9855 5400 l 9752 5468 l 9879 5423 l 9859 5367 l cp
+clip
+n 7920 6075 m 9855 5400 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 9732 5411 m 9855 5400 l 9752 5468 l 9742 5440 l 9732 5411 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10823 5573 m 10935 5625 l 10812 5632 l 10944 5657 l 10955 5598 l cp
+clip
+n 9990 5445 m 10935 5625 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 10823 5573 m 10935 5625 l 10812 5632 l 10817 5603 l 10823 5573 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10815 5280 m 10935 5310 l 10815 5340 l 10950 5340 l 10950 5280 l cp
+clip
+n 10215 5310 m 10935 5310 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 10815 5280 m 10935 5310 l 10815 5340 l 10815 5310 l 10815 5280 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+11955 4965 m 11925 5085 l 11895 4965 l 11895 5100 l 11955 5100 l cp
+clip
+n 11925 4590 m 11925 5085 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 11955 4965 m 11925 5085 l 11895 4965 l 11925 4965 l 11955 4965 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+9840 6720 m 9810 6840 l 9780 6720 l 9780 6855 l 9840 6855 l cp
+clip
+n 9810 5490 m 9810 6840 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 9840 6720 m 9810 6840 l 9780 6720 l 9810 6720 l 9840 6720 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10847 5943 m 10935 6030 l 10816 5995 l 10933 6063 l 10963 6012 l cp
+clip
+n 9945 5445 m 10935 6030 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 10847 5943 m 10935 6030 l 10816 5995 l 10832 5969 l 10847 5943 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+10698 2634 m 10800 2565 l 10742 2674 l 10832 2574 l 10788 2534 l cp
+clip
+n 8865 4725 m 10800 2565 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 10698 2634 m 10800 2565 l 10742 2674 l 10720 2654 l 10698 2634 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+30.000 slw
+n 675 6075 m 5850 6075 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+7.500 slw
+ [15 15] 15 sd
+gs clippath
+645 6195 m 675 6075 l 705 6195 l 705 6060 l 645 6060 l cp
+clip
+n 675 6525 m 675 6075 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 645 6195 m 675 6075 l 705 6195 l 675 6195 l 645 6195 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+5880 6405 m 5850 6525 l 5820 6405 l 5820 6540 l 5880 6540 l cp
+clip
+n 5850 6075 m 5850 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5880 6405 m 5850 6525 l 5820 6405 l 5850 6405 l 5880 6405 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+30.000 slw
+n 900 5625 m 5625 5625 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 1125 5175 m 5400 5175 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 1350 4725 m 5175 4725 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 1575 4275 m 4950 4275 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 1800 3825 m 4725 3825 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2025 3375 m 4500 3375 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2250 2925 m 4275 2925 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2475 2475 m 4050 2475 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2700 2025 m 3825 2025 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2925 1575 m 3600 1575 l gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+7.500 slw
+ [15 15] 15 sd
+gs clippath
+870 5745 m 900 5625 l 930 5745 l 930 5610 l 870 5610 l cp
+clip
+n 900 6075 m 900 5625 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 870 5745 m 900 5625 l 930 5745 l 900 5745 l 870 5745 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+1095 5295 m 1125 5175 l 1155 5295 l 1155 5160 l 1095 5160 l cp
+clip
+n 1125 6525 m 1125 5175 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 1095 5295 m 1125 5175 l 1155 5295 l 1125 5295 l 1095 5295 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+1320 4845 m 1350 4725 l 1380 4845 l 1380 4710 l 1320 4710 l cp
+clip
+n 1350 5175 m 1350 4725 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 1320 4845 m 1350 4725 l 1380 4845 l 1350 4845 l 1320 4845 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+1545 4395 m 1575 4275 l 1605 4395 l 1605 4260 l 1545 4260 l cp
+clip
+n 1575 4725 m 1575 4275 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 1545 4395 m 1575 4275 l 1605 4395 l 1575 4395 l 1545 4395 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+1770 3945 m 1800 3825 l 1830 3945 l 1830 3810 l 1770 3810 l cp
+clip
+n 1800 6525 m 1800 3825 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 1770 3945 m 1800 3825 l 1830 3945 l 1800 3945 l 1770 3945 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+1995 3495 m 2025 3375 l 2055 3495 l 2055 3360 l 1995 3360 l cp
+clip
+n 2025 3825 m 2025 3375 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 1995 3495 m 2025 3375 l 2055 3495 l 2025 3495 l 1995 3495 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+2220 3045 m 2250 2925 l 2280 3045 l 2280 2910 l 2220 2910 l cp
+clip
+n 2250 3375 m 2250 2925 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 2220 3045 m 2250 2925 l 2280 3045 l 2250 3045 l 2220 3045 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+2445 2595 m 2475 2475 l 2505 2595 l 2505 2460 l 2445 2460 l cp
+clip
+n 2475 2925 m 2475 2475 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 2445 2595 m 2475 2475 l 2505 2595 l 2475 2595 l 2445 2595 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+5655 5955 m 5625 6075 l 5595 5955 l 5595 6090 l 5655 6090 l cp
+clip
+n 5625 5625 m 5625 6075 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5655 5955 m 5625 6075 l 5595 5955 l 5625 5955 l 5655 5955 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+5430 6405 m 5400 6525 l 5370 6405 l 5370 6540 l 5430 6540 l cp
+clip
+n 5400 5175 m 5400 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5430 6405 m 5400 6525 l 5370 6405 l 5400 6405 l 5430 6405 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+5205 5055 m 5175 5175 l 5145 5055 l 5145 5190 l 5205 5190 l cp
+clip
+n 5175 4725 m 5175 5175 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 5205 5055 m 5175 5175 l 5145 5055 l 5175 5055 l 5205 5055 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+4980 4605 m 4950 4725 l 4920 4605 l 4920 4740 l 4980 4740 l cp
+clip
+n 4950 4275 m 4950 4725 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4980 4605 m 4950 4725 l 4920 4605 l 4950 4605 l 4980 4605 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+4755 6405 m 4725 6525 l 4695 6405 l 4695 6540 l 4755 6540 l cp
+clip
+n 4725 3825 m 4725 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4755 6405 m 4725 6525 l 4695 6405 l 4725 6405 l 4755 6405 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+4530 3705 m 4500 3825 l 4470 3705 l 4470 3840 l 4530 3840 l cp
+clip
+n 4500 3375 m 4500 3825 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4530 3705 m 4500 3825 l 4470 3705 l 4500 3705 l 4530 3705 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+4305 3255 m 4275 3375 l 4245 3255 l 4245 3390 l 4305 3390 l cp
+clip
+n 4275 2925 m 4275 3375 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4305 3255 m 4275 3375 l 4245 3255 l 4275 3255 l 4305 3255 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+4080 2805 m 4050 2925 l 4020 2805 l 4020 2940 l 4080 2940 l cp
+clip
+n 4050 2475 m 4050 2925 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 4080 2805 m 4050 2925 l 4020 2805 l 4050 2805 l 4080 2805 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+2670 2145 m 2700 2025 l 2730 2145 l 2730 2010 l 2670 2010 l cp
+clip
+n 2700 6525 m 2700 2025 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 2670 2145 m 2700 2025 l 2730 2145 l 2700 2145 l 2670 2145 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+3855 6405 m 3825 6525 l 3795 6405 l 3795 6540 l 3855 6540 l cp
+clip
+n 3825 2025 m 3825 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 3855 6405 m 3825 6525 l 3795 6405 l 3825 6405 l 3855 6405 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+3630 1905 m 3600 2025 l 3570 1905 l 3570 2040 l 3630 2040 l cp
+clip
+n 3600 1575 m 3600 2025 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 3630 1905 m 3600 2025 l 3570 1905 l 3600 1905 l 3630 1905 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+2895 1695 m 2925 1575 l 2955 1695 l 2955 1560 l 2895 1560 l cp
+clip
+n 2925 2025 m 2925 1575 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 2895 1695 m 2925 1575 l 2955 1695 l 2925 1695 l 2895 1695 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+45.000 slw
+gs clippath
+6087 6495 m 6207 6525 l 6087 6555 l 6360 6555 l 6360 6495 l cp
+clip
+n 540 6525 m 6300 6525 l gs 0.00 setgray ef gr gs col0 s gr gr
+
+% arrowhead
+n 6087 6495 m 6207 6525 l 6087 6555 l 6087 6525 l 6087 6495 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+7.500 slw
+gs clippath
+3681 6720 m 3825 6750 l 3681 6780 l 3840 6780 l 3840 6720 l cp
+2844 6780 m 2700 6750 l 2844 6720 l 2685 6720 l 2685 6780 l cp
+clip
+n 2700 6750 m 3825 6750 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 2844 6780 m 2700 6750 l 2844 6720 l 2820 6750 l 2844 6780 l cp gs col7 1.00 shd ef gr col0 s
+% arrowhead
+n 3681 6720 m 3825 6750 l 3681 6780 l 3705 6750 l 3681 6720 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+gs clippath
+5256 7170 m 5400 7200 l 5256 7230 l 5415 7230 l 5415 7170 l cp
+1269 7230 m 1125 7200 l 1269 7170 l 1110 7170 l 1110 7230 l cp
+clip
+n 1125 7200 m 5400 7200 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 1269 7230 m 1125 7200 l 1269 7170 l 1245 7200 l 1269 7230 l cp gs col7 1.00 shd ef gr col0 s
+% arrowhead
+n 5256 7170 m 5400 7200 l 5256 7230 l 5280 7200 l 5256 7170 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+gs clippath
+4581 6945 m 4725 6975 l 4581 7005 l 4740 7005 l 4740 6945 l cp
+1944 7005 m 1800 6975 l 1944 6945 l 1785 6945 l 1785 7005 l cp
+clip
+n 1800 6975 m 4725 6975 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 1944 7005 m 1800 6975 l 1944 6945 l 1920 6975 l 1944 7005 l cp gs col7 1.00 shd ef gr col0 s
+% arrowhead
+n 4581 6945 m 4725 6975 l 4581 7005 l 4605 6975 l 4581 6945 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+gs clippath
+5706 7395 m 5850 7425 l 5706 7455 l 5865 7455 l 5865 7395 l cp
+819 7455 m 675 7425 l 819 7395 l 660 7395 l 660 7455 l cp
+clip
+n 675 7425 m 5850 7425 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 819 7455 m 675 7425 l 819 7395 l 795 7425 l 819 7455 l cp gs col7 1.00 shd ef gr col0 s
+% arrowhead
+n 5706 7395 m 5850 7425 l 5706 7455 l 5730 7425 l 5706 7395 l cp gs col7 1.00 shd ef gr col0 s
+% Polyline
+1 slc
+ [15 45] 45 sd
+n 675 6570 m 675 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 1125 6570 m 1125 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 1800 6570 m 1800 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 2700 6570 m 2700 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 3825 6570 m 3825 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 4725 6570 m 4725 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5400 6570 m 5400 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 5850 6570 m 5850 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd
+% Polyline
+0 slc
+n 750 225 m 450 225 450 1050 300 arcto 4 {pop} repeat
+ 450 1350 12300 1350 300 arcto 4 {pop} repeat
+ 12600 1350 12600 525 300 arcto 4 {pop} repeat
+ 12600 225 750 225 300 arcto 4 {pop} repeat
+ cp gs col34 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 8835 2250 m 8775 2250 8775 2415 60 arcto 4 {pop} repeat
+ 8775 2475 10110 2475 60 arcto 4 {pop} repeat
+ 10170 2475 10170 2310 60 arcto 4 {pop} repeat
+ 10170 2250 8835 2250 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 10635 2250 m 10575 2250 10575 2415 60 arcto 4 {pop} repeat
+ 10575 2475 11865 2475 60 arcto 4 {pop} repeat
+ 11925 2475 11925 2310 60 arcto 4 {pop} repeat
+ 11925 2250 10635 2250 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 11490 4275 m 11430 4275 11430 4440 60 arcto 4 {pop} repeat
+ 11430 4500 12315 4500 60 arcto 4 {pop} repeat
+ 12375 4500 12375 4335 60 arcto 4 {pop} repeat
+ 12375 4275 11490 4275 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 11040 5175 m 10980 5175 10980 5340 60 arcto 4 {pop} repeat
+ 10980 5400 12315 5400 60 arcto 4 {pop} repeat
+ 12375 5400 12375 5235 60 arcto 4 {pop} repeat
+ 12375 5175 11040 5175 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 9735 5175 m 9675 5175 9675 5340 60 arcto 4 {pop} repeat
+ 9675 5400 10110 5400 60 arcto 4 {pop} repeat
+ 10170 5400 10170 5235 60 arcto 4 {pop} repeat
+ 10170 5175 9735 5175 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 7260 6075 m 7200 6075 7200 6240 60 arcto 4 {pop} repeat
+ 7200 6300 7815 6300 60 arcto 4 {pop} repeat
+ 7875 6300 7875 6135 60 arcto 4 {pop} repeat
+ 7875 6075 7260 6075 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 6810 2250 m 6750 2250 6750 2415 60 arcto 4 {pop} repeat
+ 6750 2475 8130 2475 60 arcto 4 {pop} repeat
+ 8190 2475 8190 2310 60 arcto 4 {pop} repeat
+ 8190 2250 6810 2250 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 6360 3375 m 6300 3375 6300 3540 60 arcto 4 {pop} repeat
+ 6300 3600 7545 3600 60 arcto 4 {pop} repeat
+ 7605 3600 7605 3435 60 arcto 4 {pop} repeat
+ 7605 3375 6360 3375 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 6360 4275 m 6300 4275 6300 4440 60 arcto 4 {pop} repeat
+ 6300 4500 7275 4500 60 arcto 4 {pop} repeat
+ 7335 4500 7335 4335 60 arcto 4 {pop} repeat
+ 7335 4275 6360 4275 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 6360 5175 m 6300 5175 6300 5340 60 arcto 4 {pop} repeat
+ 6300 5400 7140 5400 60 arcto 4 {pop} repeat
+ 7200 5400 7200 5235 60 arcto 4 {pop} repeat
+ 7200 5175 6360 5175 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+gs clippath
+7365 5340 m 7245 5310 l 7365 5280 l 7230 5280 l 7230 5340 l cp
+clip
+n 9630 5310 m 7245 5310 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7365 5340 m 7245 5310 l 7365 5280 l 7365 5310 l 7365 5340 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7500 4395 m 7380 4365 l 7500 4335 l 7365 4335 l 7365 4395 l cp
+clip
+n 11385 4365 m 7380 4365 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7500 4395 m 7380 4365 l 7500 4335 l 7500 4365 l 7500 4395 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 11040 5580 m 10980 5580 10980 5745 60 arcto 4 {pop} repeat
+ 10980 5805 12180 5805 60 arcto 4 {pop} repeat
+ 12240 5805 12240 5640 60 arcto 4 {pop} repeat
+ 12240 5580 11040 5580 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 11040 5985 m 10980 5985 10980 6150 60 arcto 4 {pop} repeat
+ 10980 6210 12315 6210 60 arcto 4 {pop} repeat
+ 12375 6210 12375 6045 60 arcto 4 {pop} repeat
+ 12375 5985 11040 5985 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+gs clippath
+9958 5554 m 9900 5445 l 10003 5514 l 9912 5414 l 9868 5454 l cp
+clip
+n 11205 6885 m 9900 5445 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 9958 5554 m 9900 5445 l 10003 5514 l 9981 5534 l 9958 5554 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 10590 6930 m 10530 6930 10530 7095 60 arcto 4 {pop} repeat
+ 10530 7155 12225 7155 60 arcto 4 {pop} repeat
+ 12285 7155 12285 6990 60 arcto 4 {pop} repeat
+ 12285 6930 10590 6930 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+n 9690 6930 m 9630 6930 9630 7095 60 arcto 4 {pop} repeat
+ 9630 7155 10110 7155 60 arcto 4 {pop} repeat
+ 10170 7155 10170 6990 60 arcto 4 {pop} repeat
+ 10170 6930 9690 6930 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+8280 5130 m
+gs 1 -1 sc (SSL_get_app_data2\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+6345 2970 m
+gs 1 -1 sc (ap_ctx_get\(...,) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10800 2745 m
+gs 1 -1 sc (ap_get_module_config\(...) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10800 2880 m
+gs 1 -1 sc (->per_dir_config,) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10800 3015 m
+gs 1 -1 sc (&ssl_module\)) col0 sh gr
+% Polyline
+n 7980 4770 m 7920 4770 7920 4935 60 arcto 4 {pop} repeat
+ 7920 4995 9075 4995 60 arcto 4 {pop} repeat
+ 9135 4995 9135 4830 60 arcto 4 {pop} repeat
+ 9135 4770 7980 4770 60 arcto 4 {pop} repeat
+ cp gs col35 1.00 shd ef gr gs col35 s gr
+% Polyline
+gs clippath
+7340 2610 m 7425 2520 l 7393 2639 l 7459 2521 l 7406 2492 l cp
+clip
+n 6975 3330 m 7425 2520 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7340 2610 m 7425 2520 l 7393 2639 l 7367 2625 l 7340 2610 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+9336 2569 m 9450 2520 l 9373 2616 l 9480 2535 l 9444 2487 l cp
+clip
+n 7200 4230 m 9450 2520 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 9336 2569 m 9450 2520 l 9373 2616 l 9354 2593 l 9336 2569 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7321 5196 m 7200 5220 l 7296 5142 l 7174 5199 l 7199 5254 l cp
+clip
+n 7875 4905 m 7200 5220 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 7321 5196 m 7200 5220 l 7296 5142 l 7309 5169 l 7321 5196 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6720 4665 m 6750 4545 l 6780 4665 l 6780 4530 l 6720 4530 l cp
+clip
+n 6750 5130 m 6750 4545 l gs col34 1.00 shd ef gr gs col0 s gr gr
+
+% arrowhead
+n 6720 4665 m 6750 4545 l 6780 4665 l 6750 4665 l 6720 4665 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [15 15] 15 sd
+gs clippath
+9279 4984 m 9175 4918 l 9298 4927 l 9170 4885 l 9151 4942 l cp
+clip
+n 9850 5143 m 9175 4918 l gs col34 1.00 shd ef gr gs col0 s gr gr
+ [] 0 sd
+% arrowhead
+n 9279 4984 m 9175 4918 l 9298 4927 l 9289 4956 l 9279 4984 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica-Narrow-iso ff 120.00 scf sf
+6210 4680 m
+gs 1 -1 sc (->server) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+8280 6120 m
+gs 1 -1 sc (ap_ctx_get\(...,"ssl"\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7740 2700 m
+gs 1 -1 sc (ap_get_module_config\(...) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7740 2835 m
+gs 1 -1 sc (->module_config,) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7740 2970 m
+gs 1 -1 sc (&ssl_module\)) col0 sh gr
+/Times-Roman-iso ff 120.00 scf sf
+900 7560 m
+gs 1 -1 sc (Startup, Runtime, Shutdown) col0 sh gr
+/Times-Roman-iso ff 120.00 scf sf
+1350 7335 m
+gs 1 -1 sc (Configuration Time) col0 sh gr
+/Times-Roman-iso ff 120.00 scf sf
+2025 7110 m
+gs 1 -1 sc (Connection Duration) col0 sh gr
+/Times-Roman-iso ff 120.00 scf sf
+2835 6885 m
+gs 1 -1 sc (Request Duration) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+6345 6795 m
+gs 1 -1 sc (t) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7110 5985 m
+gs 1 -1 sc (->client) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7065 5085 m
+gs 1 -1 sc (->connection) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7065 4770 m
+gs 1 -1 sc (->server) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+8010 5445 m
+gs 1 -1 sc (SSL_get_app_data\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10530 4050 m
+gs 1 -1 sc (->pSSLCtx) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+7875 4275 m
+gs 1 -1 sc (SSL_CTX_get_app_data\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10305 5535 m
+gs 1 -1 sc (SSL_get_current_cipher\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10440 5940 m
+gs 1 -1 sc (SSL_get_session\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+9540 7335 m
+gs 1 -1 sc (SSL_get_{r,w}bio\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10125 4680 m
+gs 1 -1 sc (SSL_get_SSL_CTX\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10350 5175 m
+gs 1 -1 sc (SSL_get_SSL_METHOD\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+11745 4770 m
+gs 1 -1 sc (->method) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+9945 6480 m
+gs 1 -1 sc (X509_STORE_CTX_get_app_data\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+10980 6705 m
+gs 1 -1 sc (SSL_CTX_get_cert_store\(\)) col0 sh gr
+/Helvetica-Narrow-iso ff 120.00 scf sf
+6345 3105 m
+gs 1 -1 sc ("ssl_module"\)) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+3645 1620 m
+gs 1 -1 sc (SSLDirConfig) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+11115 3645 m
+gs 1 -1 sc (SSLeay) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+11115 3825 m
+gs 1 -1 sc ([SSL]) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+11025 5760 m
+gs 1 -1 sc (SSL_CIPHER) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+10980 6165 m
+gs 1 -1 sc (SSL_SESSION) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+8730 3465 m
+gs 1 -1 sc (mod_ssl) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+10575 7110 m
+gs 1 -1 sc (X509_STORE_CTX) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+6795 2430 m
+gs 1 -1 sc (SSLModConfig) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8865 2430 m
+gs 1 -1 sc (SSLSrvConfig) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+6345 3555 m
+gs 1 -1 sc (ap_global_ctx) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+6345 4455 m
+gs 1 -1 sc (server_rec) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+6345 5355 m
+gs 1 -1 sc (conn_rec) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+9720 5355 m
+gs 1 -1 sc (SSL) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+10665 2430 m
+gs 1 -1 sc (SSLDirConfig) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+7290 6255 m
+gs 1 -1 sc (BUFF) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+11025 5355 m
+gs 1 -1 sc (SSL_METHOD) col0 sh gr
+% Polyline
+15.000 slw
+n 750 225 m 450 225 450 8250 300 arcto 4 {pop} repeat
+ 450 8550 12300 8550 300 arcto 4 {pop} repeat
+ 12600 8550 12600 525 300 arcto 4 {pop} repeat
+ 12600 225 750 225 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+11475 4455 m
+gs 1 -1 sc (SSL_CTX) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+8010 4950 m
+gs 1 -1 sc (request_rec) col0 sh gr
+/Times-Roman-iso ff 180.00 scf sf
+10575 675 m
+gs 1 -1 sc (Ralf S. Engelschall) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+4275 675 m
+gs 1 -1 sc (Apache+mod_ssl+SSLeay) col0 sh gr
+/Times-Roman-iso ff 150.00 scf sf
+10575 855 m
+gs 1 -1 sc (rse@engelschall.com) col0 sh gr
+/Times-Roman-iso ff 150.00 scf sf
+10575 1035 m
+gs 1 -1 sc (www.engelschall.com) col0 sh gr
+/Times-Roman-iso ff 180.00 scf sf
+900 675 m
+gs 1 -1 sc (Version 1.3) col0 sh gr
+/Times-Roman-iso ff 180.00 scf sf
+900 855 m
+gs 1 -1 sc (27-Jan-1998) col0 sh gr
+/Helvetica-Bold-iso ff 360.00 scf sf
+3915 1080 m
+gs 1 -1 sc (Data Structure Overview) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+9720 7110 m
+gs 1 -1 sc (BIO) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+8145 6750 m
+gs 1 -1 sc (Apache) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+10935 7785 m
+gs 1 -1 sc ([Crypto]) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+10935 7605 m
+gs 1 -1 sc (SSLeay) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+9000 8100 m
+gs 1 -1 sc (Chaining) col0 sh gr
+/Helvetica-Bold-iso ff 300.00 scf sf
+2745 8100 m
+gs 1 -1 sc (Lifetime) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+810 6255 m
+gs 1 -1 sc (ap_global_ctx) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+990 5805 m
+gs 1 -1 sc (SSLModConfig) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+4050 4455 m
+gs 1 -1 sc (SSL_CTX) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+4455 5355 m
+gs 1 -1 sc (server_rec) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+3870 4905 m
+gs 1 -1 sc (SSLSrvConfig) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+1845 4005 m
+gs 1 -1 sc (BUFF) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+2070 3555 m
+gs 1 -1 sc (conn_rec) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+2295 3105 m
+gs 1 -1 sc (BIO) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+2565 2655 m
+gs 1 -1 sc (SSL) col0 sh gr
+/Helvetica-Bold-iso ff 180.00 scf sf
+3915 2070 m
+gs 1 -1 sc (request_rec) col0 sh gr
+$F2psEnd
+rs
+showpage
diff --git a/usr.sbin/httpd/src/modules/ssl/libssl.module b/usr.sbin/httpd/src/modules/ssl/libssl.module
new file mode 100644
index 00000000000..a9bb26c49a8
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/libssl.module
@@ -0,0 +1,513 @@
+## _ _
+## _ __ ___ ___ __| | ___ ___| |
+## | '_ ` _ \ / _ \ / _` | / __/ __| |
+## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+## |_____|
+## libssl.module
+## Apache 1.3 Configuration mechanism module stub
+##
+
+##
+## ====================================================================
+## Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following
+## disclaimer in the documentation and/or other materials
+## provided with the distribution.
+##
+## 3. All advertising materials mentioning features or use of this
+## software must display the following acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## 4. The names "mod_ssl" must not be used to endorse or promote
+## products derived from this software without prior written
+## permission. For written permission, please contact
+## rse@engelschall.com.
+##
+## 5. Products derived from this software may not be called "mod_ssl"
+## nor may "mod_ssl" appear in their names without prior
+## written permission of Ralf S. Engelschall.
+##
+## 6. Redistributions of any form whatsoever must retain the following
+## acknowledgment:
+## "This product includes software developed by
+## Ralf S. Engelschall <rse@engelschall.com> for use in the
+## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+##
+## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+## HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+## OF THE POSSIBILITY OF SUCH DAMAGE.
+## ====================================================================
+##
+
+ # ``What you are missing, I suppose, is that I'm not
+ # prepared to give equal rights to Ralf on the basis
+ # that he's spent a few hours doing what he thinks is
+ # better than what I've spent the last 4 years on,
+ # and so he isn't prepared to cooperate with me.''
+ # -- Ben Laurie, Apache-SSL author
+
+Name: ssl_module
+ConfigStart
+
+ #
+ # interface to the src/Configure script
+ #
+ my_dir="`echo ${modfile} | sed -e 's:/[^/]*$::'`"
+ my_version="$my_dir/libssl.version"
+ my_outfile="Makefile.config"
+ my_prefix=" +"
+ my_prefixe=" "
+ SSL_CFLAGS=''
+ SSL_LDFLAGS=''
+ SSL_LIBS=''
+
+ #
+ # determine mod_ssl author version
+ #
+ A_ID=`cat $my_version | sed -e 's; .*;;'`
+ A_NAME=`echo $A_ID | sed -e 's;/.*;;'`
+ A_VER=`echo $A_ID | sed -e 's;.*/;;'`
+ A_VER_STR=`echo $A_VER | sed -e 's;-.*;;'`
+ case $A_VER_STR in
+ *.*b* )
+ A_VER_HEX=`echo "$A_VER_STR" | sed -e 's/b.*//' | awk -F. '{ printf("%d%02d", $1, $2); }' &&
+ echo "$A_VER_STR" | sed -e 's/.*b//' | awk '{ printf("0%02d", $1); }'`
+ ;;
+ *.*.* )
+ A_VER_HEX=`echo "$A_VER_STR" | awk -F. '{ printf("%d%02d1%02d", $1, $2, $3); }'`
+ ;;
+ esac
+ echo "$my_prefix SSL interface: $A_NAME/$A_VER_STR"
+ SSL_VERSION="-DMOD_SSL_VERSION=\\\"$A_VER_STR\\\""
+
+ #
+ # determine optional mod_ssl product version
+ #
+ if [ ".`egrep '.*/.* .*/.*' $my_version`" != . ]; then
+ P_ID=`cat $my_version | sed -e 's;.* ;;'`
+ P_NAME=`echo $P_ID | sed -e 's;/.*;;'`
+ P_VER=`echo $P_ID | sed -e 's;.*/;;'`
+ P_VER_STR=`echo $P_VER | sed -e 's;-.*;;'`
+ case $P_VER_STR in
+ *.*b* )
+ P_VER_HEX=`echo "$P_VER_STR" | sed -e 's/b.*//' | awk -F. '{ printf("%d%02d", $1, $2); }' &&
+ echo "$P_VER_STR" | sed -e 's/.*b//' | awk '{ printf("0%02d", $1); }'`
+ ;;
+ *.*.* )
+ P_VER_HEX=`echo "$P_VER_STR" | awk -F. '{ printf("%d%02d1%02d", $1, $2, $3); }'`
+ ;;
+ esac
+ echo "$my_prefix SSL product: $P_NAME/$P_VER_STR"
+ SSL_VERSION="$SSL_VERSION -DSSL_PRODUCT_NAME=\\\"$P_NAME\\\""
+ SSL_VERSION="$SSL_VERSION -DSSL_PRODUCT_VERSION=\\\"$P_VER_STR\\\""
+ fi
+
+ #
+ # determine object build type
+ #
+ case $modfile in
+ *.so ) my_buildtype="DSO" ;;
+ * ) my_buildtype="OBJ" ;;
+ esac
+ echo "$my_prefix SSL interface build type: $my_buildtype"
+
+ #
+ # determine SSL rules
+ #
+ if [ ".$APXS_MODE" = .YES ]; then
+ my_rule_SSL_COMPAT=$SSL_COMPAT
+ my_rule_SSL_SDBM=$SSL_SDBM
+ my_rule_SSL_EXPERIMENTAL=$SSL_EXPERIMENTAL
+ else
+ my_rule_SSL_COMPAT=`./helpers/CutRule SSL_COMPAT $file`
+ my_rule_SSL_SDBM=`./helpers/CutRule SSL_SDBM $file`
+ my_rule_SSL_EXPERIMENTAL=`./helpers/CutRule SSL_EXPERIMENTAL $file`
+ fi
+
+ #
+ # determine compatibility mode
+ #
+ if [ ".$my_rule_SSL_COMPAT" = .yes ]; then
+ echo "$my_prefix SSL interface compatibility: enabled"
+ SSL_CFLAGS="$SSL_CFLAGS -DSSL_COMPAT"
+ else
+ echo "$my_prefix SSL interface compatibility: disabled"
+ fi
+
+ #
+ # determine experimental mode
+ #
+ if [ ".$my_rule_SSL_EXPERIMENTAL" = .yes ]; then
+ echo "$my_prefix SSL interface experimental code: enabled"
+ SSL_CFLAGS="$SSL_CFLAGS -DSSL_EXPERIMENTAL"
+ else
+ echo "$my_prefix SSL interface experimental code: disabled"
+ fi
+
+ #
+ # determine DBM support library
+ # (src/Configure has DBM_LIB predefined for some platforms)
+ #
+ if [ ".$APXS_MODE" != .YES ]; then
+ SSL_DBM_NAME=''
+ # 1. check for predefined DBM lib
+ if [ ".$DBM_LIB" != . ]; then
+ LIBS_ORIG="$LIBS"
+ LIBS="$LIBS $DBM_LIB"
+ if ./helpers/TestCompile func dbm_open; then
+ SSL_DBM_NAME="Configured DBM ($DBM_LIB)"
+ SSL_DBM_FLAG="$DBM_LIB"
+ fi
+ LIBS="$LIBS_ORIG"
+ fi
+ # 2. check for various vendor DBM libs
+ if [ ".$SSL_DBM_NAME" = . ]; then
+ if ./helpers/TestCompile func dbm_open; then
+ SSL_DBM_NAME='Vendor DBM (libc)'
+ SSL_DBM_FLAG=''
+ elif ./helpers/TestCompile lib dbm dbm_open; then
+ SSL_DBM_NAME='Vendor DBM (libdbm)'
+ SSL_DBM_FLAG='-ldbm'
+ elif ./helpers/TestCompile lib ndbm dbm_open; then
+ SSL_DBM_NAME='Vendor DBM (libndbm)'
+ SSL_DBM_FLAG='-lndbm'
+ fi
+ fi
+ # 3. let the SSL_SDBM rule override decisions
+ if [ ".$my_rule_SSL_SDBM" = .yes ]; then
+ # force us to fallback to SDBM
+ SSL_DBM_NAME=''
+ fi
+ if [ ".$my_rule_SSL_SDBM" = .no ]; then
+ # for us to never use SDBM, but be
+ # careful when no DBM was found at all
+ if [ ".$SSL_DBM_NAME" = . ]; then
+ echo "Error: SDBM is needed, because no custom or vendor DBM library available!" 1>&2
+ echo "Hint: Allow us to choose SDBM by changing the rule SSL_SDBM, please." 1>&2
+ exit 1
+ fi
+ fi
+ # 4. finally configure the chosen DBM lib
+ if [ ".$SSL_DBM_NAME" != . ]; then
+ echo "$my_prefix SSL interface plugin: $SSL_DBM_NAME"
+ my_dbm_already_used=`echo $LIBS | grep -- " $SSL_DBM_FLAG"`
+ if [ ".$my_buildtype" = .OBJ -a ".$my_dbm_already_used" != . ]; then
+ :
+ else
+ SSL_LIBS="$SSL_LIBS $SSL_DBM_FLAG"
+ fi
+ else
+ echo "$my_prefix SSL interface plugin: Built-in SDBM"
+ SSL_CFLAGS="$SSL_CFLAGS -DSSL_USE_SDBM"
+ fi
+ fi
+
+ #
+ # determine SSL_BASE
+ #
+ if [ ".$SSL_BASE" = . ]; then
+ SSL_BASE=`egrep '^SSL_BASE=' $file | tail -1 | awk -F= '{print $2}'`
+ if [ ".$SSL_BASE" = . ]; then
+ SSL_BASE="/usr/local/ssl"
+ fi
+ fi
+ case $SSL_BASE in
+ SYSTEM ) ;;
+ /* ) ;;
+ * ) SSL_BASE="`cd ../$SSL_BASE; pwd`" ;;
+ esac
+ if [ ".$SSL_BASE" = .SYSTEM ]; then
+ echo "$my_prefix SSL library path: [SYSTEM]"
+ else
+ if [ ! -d "$SSL_BASE" ]; then
+ echo "Error: Cannot find SSL installation in $SSL_BASE" 1>&2
+ echo "Hint: Please provide us with the location of SSLeay" 1>&2
+ echo " via the environment variable SSL_BASE." 1>&2
+ exit 1
+ fi
+ echo "$my_prefix SSL library path: $SSL_BASE"
+ fi
+
+ #
+ # determine location of SSLeay binaries
+ #
+ SSL_BINDIR=""
+ if [ ".$SSL_BASE" = .SYSTEM ]; then
+ for name in openssl ssleay; do
+ for p in . `echo $PATH | sed -e 's/:/ /g'`; do
+ if [ -f "$p/$name" ]; then
+ SSL_PROGRAM="$p/$name"
+ SSL_BINDIR="$p"
+ break
+ fi
+ done
+ if [ ".$SSL_BINDIR" != . ]; then
+ break;
+ fi
+ done
+ if [ ".$SSL_BINDIR" = . ]; then
+ echo "Error: Cannot find SSL binaries in $PATH" 1>&2
+ exit 1
+ fi
+ else
+ for name in openssl ssleay; do
+ if [ -f "$SSL_BASE/bin/$name" ]; then
+ SSL_PROGRAM="$SSL_BASE/bin/$name"
+ SSL_BINDIR='$(SSL_BASE)/bin'
+ break;
+ fi
+ if [ -f "$SSL_BASE/apps/$name" ]; then
+ SSL_PROGRAM="$SSL_BASE/apps/$name"
+ SSL_BINDIR='$(SSL_BASE)/apps'
+ break;
+ fi
+ done
+ if [ ".$SSL_BINDIR" = . ]; then
+ echo "Error: Cannot find SSL binaries under $SSL_BASE" 1>&2
+ exit 1
+ fi
+ fi
+
+ #
+ # determine location of SSLeay headers
+ #
+ if [ ".$SSL_BASE" = .SYSTEM ]; then
+ SSL_INCDIR=""
+ for p in . /usr/include /usr/include/ssl/ /usr/local/include /usr/local/include/ssl; do
+ if [ -f "$p/ssl.h" ]; then
+ SSL_INCDIR="$p"
+ break
+ fi
+ done
+ if [ ".$SSL_INCDIR" = . ]; then
+ echo "Error: Cannot find SSL header files in any of the following dirs:" 1>&2
+ echo "Error: . /usr/include /usr/include/ssl/ /usr/local/include /usr/local/include/ssl" 1>&2
+ exit 1
+ fi
+ else
+ if [ -f "$SSL_BASE/include/ssl.h" ]; then
+ SSL_INCDIR='$(SSL_BASE)/include'
+ else
+ if [ -f "$SSL_BASE/ssl.h" ]; then
+ SSL_INCDIR='$(SSL_BASE)'
+ else
+ echo "Error: Cannot find SSL header files under $SSL_BASE" 1>&2
+ exit 1
+ fi
+ fi
+ fi
+ SSL_CFLAGS="$SSL_CFLAGS -I\$(SSL_INCDIR)"
+
+ #
+ # determine location of SSLeay libraries
+ #
+ if [ ".$SSL_BASE" = .SYSTEM ]; then
+ SSL_LIBDIR=""
+ for p in . /lib /usr/lib /usr/local/lib; do
+ if [ -f "$p/libssl.a" -o -f "$p/libssl.so" ]; then
+ SSL_LIBDIR="$p"
+ my_real_ssl_libdir="$p"
+ break
+ fi
+ done
+ if [ ".$SSL_LIBDIR" = . ]; then
+ echo "Error: Cannot find SSL library files in any of the following dirs:" 1>&2
+ echo "Error: . /lib /usr/lib /usr/local/lib" 1>&2
+ exit 1
+ fi
+ else
+ if [ -f "$SSL_BASE/lib/libssl.a" ]; then
+ SSL_LIBDIR='$(SSL_BASE)/lib'
+ my_real_ssl_libdir="$SSL_BASE/lib"
+ else
+ if [ -f "$SSL_BASE/libssl.a" ]; then
+ SSL_LIBDIR='$(SSL_BASE)'
+ my_real_ssl_libdir="$SSL_BASE"
+ else
+ echo "Error: Cannot find SSL library files under $SSL_BASE" 1>&2
+ exit 1
+ fi
+ fi
+ fi
+ SSL_LDFLAGS="$SSL_LDFLAGS -L\$(SSL_LIBDIR)"
+ SSL_LIBS="$SSL_LIBS -lssl -lcrypto"
+
+ #
+ # SSL installation type
+ #
+ case $SSL_BINDIR in
+ */apps ) my_type="source tree only" ;;
+ * ) my_type="installed package" ;;
+ esac
+ case $SSL_BASE in
+ SYSTEM ) my_note="(system-wide)" ;;
+ * ) my_note="(stand-alone)" ;;
+ esac
+ echo "$my_prefix SSL library type: $my_type $my_note"
+
+ #
+ # SSL version
+ #
+ SSLEAY_VERSION="`$SSL_PROGRAM version`"
+ echo "$my_prefix SSL library version: $SSLEAY_VERSION"
+ case $SSLEAY_VERSION in
+ *0.[5678].* )
+ echo "$my_prefixe WARNING: THE SSLeay VERSIONS BELOW 0.9.0 ARE NO LONGER SUPPORTED."
+ echo "$my_prefixe Hint: Use SSLeay version 0.9.0b or any OpenSSL version."
+ exit 1
+ ;;
+ esac
+
+ #
+ # support for RSAref library
+ #
+ if [ ".$RSA_BASE" = . ]; then
+ RSA_BASE=`egrep '^RSA_BASE=' $file | tail -1 | awk -F= '{print $2}'`
+ fi
+ if [ ".$RSA_BASE" != . ]; then
+ if [ ! -f "$my_real_ssl_libdir/libRSAglue.a" ]; then
+ echo "Error: Cannot find SSLeay's RSAglue library under $my_real_ssl_libdir" 1>&2
+ exit 1
+ else
+ SSL_LIBS="$SSL_LIBS -lRSAglue"
+ fi
+ case $RSA_BASE in
+ SYSTEM ) ;;
+ /* ) ;;
+ * ) RSA_BASE="`cd ../$RSA_BASE; pwd`" ;;
+ esac
+ echo "$my_prefix SSL library plugin mode: RSAref (explicitly configured)"
+ else
+ if [ -f "$my_real_ssl_libdir/libRSAglue.a" ]; then
+ if [ ".`$SSL_PROGRAM version -f | grep -- -DRSAref`" != . ]; then
+ SSL_LIBS="$SSL_LIBS -lRSAglue"
+ if [ -f "$SSL_BASE/Makefile.ssl" ]; then
+ if [ ".`egrep -- '-L[^ ]*/rsaref' $SSL_BASE/Makefile.ssl`" != . ]; then
+ RSA_BASE=`egrep -- '-L[^ ]*/rsaref' $SSL_BASE/Makefile.ssl |\
+ head -1 | sed -e 's;.*-L\([^ ]*/rsaref[^ ]*\).*;\1;'`
+ fi
+ fi
+ if [ ".$RSA_BASE" = . ]; then
+ RSA_BASE='SYSTEM'
+ fi
+ fi
+ fi
+ if [ ".$RSA_BASE" != . ]; then
+ echo "$my_prefix SSL library plugin mode: RSAref (implicitly configured)"
+ else
+ echo "$my_prefix SSL library plugin mode: none"
+ fi
+ fi
+ if [ ".$RSA_BASE" != . ]; then
+ if [ ".$RSA_BASE" = .SYSTEM ]; then
+ my_found=no
+ for p in . /lib /usr/lib /usr/local/lib; do
+ if [ -f "$p/librsaref.a" -o -f "$p/librsaref.so" ]; then
+ SSL_LDFLAGS="$SSL_LDFLAGS -L$p"
+ SSL_LIBS="$SSL_LIBS -lrsaref"
+ echo "$my_prefix SSL library plugin path: $p/librsaref.a"
+ my_found=yes
+ break
+ fi
+ done
+ if [ .$my_found = .no ]; then
+ echo "Error: Cannot find RSAref library in any of the following dirs:" 1>&2
+ echo "Error: . /lib /usr/lib /usr/local/lib" 1>&2
+ exit 1
+ fi
+ else
+ my_found=no
+ if [ -f "$RSA_BASE/librsaref.a" ]; then
+ SSL_LDFLAGS="$SSL_LDFLAGS -L$RSA_BASE"
+ SSL_LIBS="$SSL_LIBS -lrsaref"
+ echo "$my_prefix SSL library plugin path: $RSA_BASE/librsaref.a"
+ my_found=yes
+ else
+ if [ -f "$RSA_BASE/rsaref.a" ]; then
+ SSL_LIBS="$SSL_LIBS $RSA_BASE/rsaref.a"
+ echo "$my_prefix SSL library plugin path: $RSA_BASE/rsaref.a"
+ my_found=yes
+ else
+ wild="`echo $RSA_BASE/*/rsaref.a`"
+ if [ -f "$wild" ]; then
+ SSL_LIBS="$SSL_LIBS $wild"
+ echo "$my_prefix SSL library plugin path: $wild"
+ my_found=yes
+ fi
+ fi
+ fi
+ if [ .$my_found = .no ]; then
+ echo "Error: Cannot find RSAref library under $RSA_BASE" 1>&2
+ exit 1
+ fi
+ fi
+ fi
+
+ #
+ # Special GCC/DSO support
+ #
+ # Under some platforms where GCC is used we have to link the DSO
+ # (libssl.so) explicitly against the GCC library (libgcc) to avoid
+ # problems with missing symbols like __umoddi3, etc.
+ #
+ # Notice: When GCC is installed as "cc" we assume it's really
+ # well incorporated into the system and no hack is
+ # needed (like on FreeBSD, Linux, etc.)
+ #
+ if [ ".$my_buildtype" = .DSO ]; then
+ case $CC in
+ gcc|*/gcc|egcs|*/egcs|egcc|*/egcc|pgcc|*/pgcc )
+ gcclibdir="`$CC --print-libgcc-file-name | sed -e 's;/[^/]*$;;'`"
+ SSL_LIBS="$SSL_LIBS -L$gcclibdir -lgcc"
+ ;;
+ esac
+ fi
+
+ #
+ # adjust the Apache build environment
+ #
+ echo "SSL_BASE=$SSL_BASE" >>$my_outfile
+ echo "SSL_BINDIR=$SSL_BINDIR" >>$my_outfile
+ echo "SSL_INCDIR=$SSL_INCDIR" >>$my_outfile
+ echo "SSL_LIBDIR=$SSL_LIBDIR" >>$my_outfile
+ echo "SSL_PROGRAM=$SSL_PROGRAM" >>$my_outfile
+ echo "SSL_VERSION=$SSL_VERSION" >>$my_outfile
+ echo "SSL_CFLAGS=$SSL_CFLAGS" >>$my_outfile
+ if [ ".$my_buildtype" = .DSO ]; then
+ # under DSO we link ourself
+ echo "SSL_LIBS=$SSL_LIBS" >>$my_outfile
+ echo "SSL_LDFLAGS=$SSL_LDFLAGS" >>$my_outfile
+ else
+ # else we are linked with httpd
+ LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
+ LIBS="$LIBS $SSL_LIBS"
+ fi
+ CFLAGS="$CFLAGS -DMOD_SSL=$A_VER_HEX"
+ if [ ".$P_ID" != . ]; then
+ CFLAGS="$CFLAGS -DSSL_PRODUCT=$P_VER_HEX"
+ fi
+ RULE_EAPI=yes
+
+ConfigEnd
+
diff --git a/usr.sbin/httpd/src/modules/ssl/libssl.version b/usr.sbin/httpd/src/modules/ssl/libssl.version
new file mode 100644
index 00000000000..851544d6678
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/libssl.version
@@ -0,0 +1 @@
+mod_ssl/2.2.3-1.3.4
diff --git a/usr.sbin/httpd/src/modules/ssl/mod_ssl.c b/usr.sbin/httpd/src/modules/ssl/mod_ssl.c
new file mode 100644
index 00000000000..d0c0ae10d3b
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/mod_ssl.c
@@ -0,0 +1,204 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** mod_ssl.c
+** Apache API interface structures
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``I'll be surprised if
+ others think that what you
+ are doing is honourable.''
+ -- Ben Laurie, Apache-SSL author */
+#include "mod_ssl.h"
+
+/* _________________________________________________________________
+**
+** Apache API glue structures
+** _________________________________________________________________
+*/
+
+/*
+ * identify the module to SCCS `what' and RCS `ident' commands
+ */
+static char const sccsid[] = "@(#) mod_ssl/" MOD_SSL_VERSION " >";
+static char const rcsid[] = "$Id: mod_ssl.c,v 1.1 1999/03/01 04:28:50 beck Exp $";
+
+/*
+ * the table of configuration directives we provide
+ */
+static command_rec ssl_config_cmds[] = {
+ /*
+ * Global (main-server) context configuration directives
+ */
+ AP_SRV_CMD(Mutex, TAKE1,
+ "SSL lock for handling internal mutual exclusions "
+ "(`none', `file:/path/to/file')")
+ AP_SRV_CMD(PassPhraseDialog, TAKE1,
+ "SSL dialog mechanism for the pass phrase query "
+ "(`builtin', `exec:/path/to/program')")
+ AP_SRV_CMD(SessionCache, TAKE1,
+ "SSL Session Cache storage "
+ "(`none', `dbm:/path/to/file')")
+ AP_SRV_CMD(RandomSeed, TAKE23,
+ "SSL Pseudo Random Number Generator (PRNG) seeding source "
+ "(`startup|connect builtin|file:/path|exec:/path [bytes]')")
+
+ /*
+ * Per-server context configuration directives
+ */
+ AP_SRV_CMD(Engine, FLAG,
+ "SSL switch for the protocol engine "
+ "(`on', `off')")
+ AP_ALL_CMD(CipherSuite, TAKE1,
+ "Colon-delimited list of permitted SSL Ciphers "
+ "(`XXX:...:XXX' - see manual)")
+ AP_SRV_CMD(CertificateFile, TAKE1,
+ "SSL Server Certificate file "
+ "(`/path/to/file' - PEM encoded)")
+ AP_SRV_CMD(CertificateKeyFile, TAKE1,
+ "SSL Server Private Key file "
+ "(`/path/to/file' - PEM encoded)")
+#ifdef SSL_EXPERIMENTAL
+ AP_ALL_CMD(CACertificatePath, TAKE1,
+ "SSL CA Certificate path "
+ "(`/path/to/dir' - contains PEM encoded files)")
+ AP_ALL_CMD(CACertificateFile, TAKE1,
+ "SSL CA Certificate file "
+ "(`/path/to/file' - PEM encoded)")
+#else
+ AP_SRV_CMD(CACertificatePath, TAKE1,
+ "SSL CA Certificate path "
+ "(`/path/to/dir' - contains PEM encoded files)")
+ AP_SRV_CMD(CACertificateFile, TAKE1,
+ "SSL CA Certificate file "
+ "(`/path/to/file' - PEM encoded)")
+#endif
+ AP_ALL_CMD(VerifyClient, TAKE1,
+ "SSL Client verify type "
+ "(`none', `optional', `require', `optional_no_ca')")
+ AP_ALL_CMD(VerifyDepth, TAKE1,
+ "SSL Client verify depth "
+ "(`N' - number of intermediate certifcates)")
+ AP_SRV_CMD(SessionCacheTimeout, TAKE1,
+ "SSL Session Cache object lifetime "
+ "(`N' - number of seconds)")
+ AP_SRV_CMD(Log, TAKE1,
+ "SSL logfile for SSL-related messages "
+ "(`/path/to/file', `|/path/to/program')")
+ AP_SRV_CMD(LogLevel, TAKE1,
+ "SSL logfile verbosity level "
+ "(`none', `error', `warn', `info', `debug')")
+ AP_SRV_CMD(Protocol, RAW_ARGS,
+ "Enable or disable various SSL protocols"
+ "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+
+ /*
+ * Per-directory context configuration directives
+ */
+ AP_DIR_CMD(Options, OPTIONS, RAW_ARGS,
+ "Set one of more options to configure the SSL engine"
+ "(`[+-]option[=value] ...' - see manual)")
+ AP_DIR_CMD(RequireSSL, AUTHCFG, NO_ARGS,
+ "Require the SSL protocol for the per-directory context "
+ "(no arguments)")
+ AP_DIR_CMD(Require, AUTHCFG, RAW_ARGS,
+ "Require a boolean expresion to evaluate to true for granting access"
+ "(arbitraty complex boolean expression - see manual)")
+
+ AP_END_CMD
+};
+
+static const handler_rec ssl_config_handler[] = {
+ { "mod_ssl:content-handler", ssl_hook_Handler },
+ { NULL, NULL }
+};
+
+/*
+ * the main Apache API config structure
+ */
+module MODULE_VAR_EXPORT ssl_module = {
+ STANDARD_MODULE_STUFF,
+
+ /* Standard API (always present) */
+
+ ssl_init_Module, /* module initializer */
+ ssl_config_perdir_create, /* create per-dir config structures */
+ ssl_config_perdir_merge, /* merge per-dir config structures */
+ ssl_config_server_create, /* create per-server config structures */
+ ssl_config_server_merge, /* merge per-server config structures */
+ ssl_config_cmds, /* table of config file commands */
+ ssl_config_handler, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ ssl_hook_Auth, /* [#4] validate user id from request */
+ NULL, /* [#5] check if the user is ok _here_ */
+ ssl_hook_Access, /* [#3] check access by host address */
+ NULL, /* [#6] determine MIME type */
+ ssl_hook_Fixup, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ NULL, /* [#2] header parser */
+ ssl_init_Child, /* child_init */
+ NULL, /* child_exit */
+ ssl_hook_ReadReq, /* [#0] post read-request */
+
+ /* Extended API (forced to be enabled with mod_ssl) */
+
+ ssl_hook_AddModule, /* after modules was added to core */
+ ssl_hook_RemoveModule, /* before module is removed from core */
+ ssl_hook_RewriteCommand, /* configuration command rewriting */
+ ssl_hook_NewConnection /* configuration command rewriting */
+};
+
+
diff --git a/usr.sbin/httpd/src/modules/ssl/mod_ssl.h b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h
new file mode 100644
index 00000000000..d1481b83de1
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h
@@ -0,0 +1,659 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** mod_ssl.h
+** Global header
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``The Apache Group: a collection
+ of talented individuals who are
+ trying to perfect the art of
+ never finishing something.''
+ -- Rob Hartill */
+#ifndef MOD_SSL_H
+#define MOD_SSL_H 1
+
+/*
+ * Power up our brain...
+ */
+
+/* OS headers */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+/* SSLeay headers */
+#include <ssl.h>
+#include <err.h>
+#include <x509.h>
+#include <pem.h>
+#include <crypto.h>
+#include <evp.h>
+#include <rand.h>
+
+/* Apache headers */
+#define CORE_PRIVATE
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_conf_globals.h"
+#include "http_protocol.h"
+#include "http_main.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "scoreboard.h"
+#include "fnmatch.h"
+#undef CORE_PRIVATE
+
+/* mod_ssl headers */
+#include "ssl_expr.h"
+#include "ssl_util_ssl.h"
+
+/*
+ * Provide reasonable default for some defines
+ */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+#ifndef UNSET
+#define UNSET -1
+#endif
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+/*
+ * Provide reasonable defines for some types
+ */
+#ifndef BOOL
+#define BOOL unsigned int
+#endif
+#ifndef UCHAR
+#define UCHAR unsigned char
+#endif
+
+/*
+ * Provide useful shorthands
+ */
+#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
+#define strNE(s1,s2) (strcmp(s1,s2) != 0)
+#define strEQn(s1,s2,n) (strncmp(s1,s2,n) == 0)
+#define strNEn(s1,s2,n) (strncmp(s1,s2,n) != 0)
+
+#define strcEQ(s1,s2) (strcasecmp(s1,s2) == 0)
+#define strcNE(s1,s2) (strcasecmp(s1,s2) != 0)
+#define strcEQn(s1,s2,n) (strncasecmp(s1,s2,n) == 0)
+#define strcNEn(s1,s2,n) (strncasecmp(s1,s2,n) != 0)
+
+#define strIsEmpty(s) (s == NULL || s[0] == NUL)
+
+#define cfgMerge(el,unset) new->el = add->el == unset ? base->el : add->el
+#define cfgMergeArray(el) new->el = ap_append_arrays(p, add->el, base->el)
+#define cfgMergeTable(el) new->el = ap_overlay_tables(p, add->el, base->el)
+#define cfgMergeString(el) cfgMerge(el, NULL)
+#define cfgMergeBool(el) cfgMerge(el, UNSET)
+#define cfgMergeInt(el) cfgMerge(el, UNSET)
+
+#define myModConfig() (SSLModConfigRec *)ap_ctx_get(ap_global_ctx, "ssl_module")
+#define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config, &ssl_module)
+#define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module)
+
+#define myCtxVarSet(mc,num,val) mc->rCtx.pV##num = val
+#define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num)
+
+#define AP_ALL_CMD(name, args, desc) \
+ { "SSL"#name, ssl_cmd_SSL##name, NULL, RSRC_CONF|OR_AUTHCFG, args, desc },
+#define AP_SRV_CMD(name, args, desc) \
+ { "SSL"#name, ssl_cmd_SSL##name, NULL, RSRC_CONF, args, desc },
+#define AP_DIR_CMD(name, type, args, desc) \
+ { "SSL"#name, ssl_cmd_SSL##name, NULL, OR_##type, args, desc },
+#define AP_END_CMD \
+ { NULL }
+
+/*
+ * SSL Logging
+ */
+#define SSL_LOG_NONE (1<<0)
+#define SSL_LOG_ERROR (1<<1)
+#define SSL_LOG_WARN (1<<2)
+#define SSL_LOG_INFO (1<<3)
+#define SSL_LOG_TRACE (1<<4)
+#define SSL_LOG_DEBUG (1<<5)
+#define SSL_LOG_MASK (SSL_LOG_ERROR|SSL_LOG_WARN|SSL_LOG_INFO|SSL_LOG_TRACE|SSL_LOG_DEBUG)
+
+#define SSL_ADD_NONE (1<<8)
+#define SSL_ADD_ERRNO (1<<9)
+#define SSL_ADD_SSLERR (1<<10)
+#define SSL_NO_TIMESTAMP (1<<11)
+#define SSL_NO_LEVELID (1<<12)
+#define SSL_NO_NEWLINE (1<<13)
+
+/*
+ * Defaults for the configuration
+ */
+
+#ifndef SSL_SESSION_CACHE_TIMEOUT
+#define SSL_SESSION_CACHE_TIMEOUT 300
+#endif
+
+/*
+ * Support for file locking: Try to determine whether we should use fcntl() or
+ * flock(). Would be better ap_config.h could provide this... :-(
+ */
+#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#define SSL_USE_FCNTL 1
+#include <fcntl.h>
+#endif
+#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
+#define SSL_USE_FLOCK 1
+#include <sys/file.h>
+#endif
+#if !defined(SSL_USE_FCNTL) && !defined(SSL_USE_FLOCK)
+#define SSL_USE_FLOCK 1
+#if !defined(MPE) && !defined(WIN32)
+#include <sys/file.h>
+#endif
+#ifndef LOCK_UN
+#undef SSL_USE_FLOCK
+#define SSL_USE_FCNTL 1
+#include <fcntl.h>
+#endif
+#endif
+#ifdef AIX
+#undef SSL_USE_FLOCK
+#define SSL_USE_FCNTL 1
+#include <fcntl.h>
+#endif
+
+/*
+ * Support for Mutex
+ */
+#ifndef WIN32
+#define SSL_MUTEX_LOCK_MODE ( S_IRUSR|S_IWUSR )
+#else
+#define SSL_MUTEX_LOCK_MODE (_S_IREAD|_S_IWRITE )
+#endif
+#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
+#define SSL_CAN_USE_SEM
+#define SSL_HAVE_IPCSEM
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#endif
+#ifdef WIN32
+#define SSL_CAN_USE_SEM
+#define SSL_HAVE_W32SEM
+#include "multithread.h"
+#include <process.h>
+#endif
+
+/*
+ * Support for DBM library
+ */
+#ifndef WIN32
+#define SSL_DBM_FILE_MODE ( S_IRUSR|S_IWUSR )
+#else
+#define SSL_USE_SDBM
+#define SSL_DBM_FILE_MODE ( _S_IREAD|_S_IWRITE )
+#endif
+
+#ifdef SSL_USE_SDBM
+#include "ssl_util_sdbm.h"
+#define ssl_dbm_open sdbm_open
+#define ssl_dbm_close sdbm_close
+#define ssl_dbm_store sdbm_store
+#define ssl_dbm_fetch sdbm_fetch
+#define ssl_dbm_delete sdbm_delete
+#define ssl_dbm_firstkey sdbm_firstkey
+#define ssl_dbm_nextkey sdbm_nextkey
+#define SSL_DBM_FILE_SUFFIX_DIR ".dir"
+#define SSL_DBM_FILE_SUFFIX_PAG ".pag"
+#else
+#include <ndbm.h>
+#define ssl_dbm_open dbm_open
+#define ssl_dbm_close dbm_close
+#define ssl_dbm_store dbm_store
+#define ssl_dbm_fetch dbm_fetch
+#define ssl_dbm_delete dbm_delete
+#define ssl_dbm_firstkey dbm_firstkey
+#define ssl_dbm_nextkey dbm_nextkey
+#if defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
+#define SSL_DBM_FILE_SUFFIX_DIR ".db"
+#define SSL_DBM_FILE_SUFFIX_PAG ".db"
+#else
+#define SSL_DBM_FILE_SUFFIX_DIR ".dir"
+#define SSL_DBM_FILE_SUFFIX_PAG ".pag"
+#endif
+#endif
+
+/*
+ * Check for SSLeay 0.9.0 and below
+ * and enabled Extended API (EAPI)
+ */
+#if SSL_LIBRARY_VERSION < 0x0900
+#error "SSLeay versions below 0.9.0 are no longer supported"
+#endif
+#ifndef EAPI
+#error "mod_ssl requires Extended API (EAPI)"
+#endif
+
+/*
+ * The own data structures
+ */
+typedef struct {
+ pool *pPool;
+ pool *pSubPool;
+ array_header *aData;
+} ssl_ds_array;
+
+typedef struct {
+ pool *pPool;
+ pool *pSubPool;
+ array_header *aKey;
+ array_header *aData;
+} ssl_ds_table;
+
+/*
+ * Define the SSL options
+ */
+#define SSL_OPT_NONE (0)
+#define SSL_OPT_RELSET (1<<0)
+#define SSL_OPT_COMPATENVVARS (1<<1)
+#define SSL_OPT_EXPORTCERTDATA (1<<2)
+#define SSL_OPT_FAKEBASICAUTH (1<<3)
+#define SSL_OPT_ALL (SSL_OPT_COMPATENVVAR|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH)
+typedef int ssl_opt_t;
+
+/*
+ * Define the SSL Protocol options
+ */
+
+#define SSL_PROTOCOL_NONE (0)
+#define SSL_PROTOCOL_SSLV2 (1<<0)
+#define SSL_PROTOCOL_SSLV3 (1<<1)
+#define SSL_PROTOCOL_TLSV1 (1<<2)
+#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
+typedef int ssl_proto_t;
+
+/*
+ * Define the SSL verify levels
+ */
+typedef enum {
+ SSL_CVERIFY_UNSET = UNSET,
+ SSL_CVERIFY_NONE = 0,
+ SSL_CVERIFY_OPTIONAL = 1,
+ SSL_CVERIFY_REQUIRE = 2,
+ SSL_CVERIFY_OPTIONAL_NO_CA = 3
+} ssl_verify_t;
+
+/*
+ * Define the SSL pass phrase dialog types
+ */
+typedef enum {
+ SSL_PPTYPE_UNSET = UNSET,
+ SSL_PPTYPE_BUILTIN = 0,
+ SSL_PPTYPE_FILTER = 1
+} ssl_pphrase_t;
+
+/*
+ * Define the Path Checking modes
+ */
+#define SSL_PCM_EXISTS 1
+#define SSL_PCM_ISREG 2
+#define SSL_PCM_ISDIR 4
+#define SSL_PCM_ISNONZERO 8
+typedef unsigned int ssl_pathcheck_t;
+
+/*
+ * Define the SSL session cache modes and structures
+ */
+typedef enum {
+ SSL_SCMODE_UNSET = UNSET,
+ SSL_SCMODE_NONE = 0,
+ SSL_SCMODE_DBM = 1,
+ SSL_SCMODE_SHM = 2
+} ssl_scmode_t;
+
+typedef struct {
+ UCHAR *ucaKey;
+ int nKey;
+ UCHAR *ucaData;
+ int nData;
+ time_t tExpiresAt;
+} ssl_scinfo_t;
+
+/*
+ * Define the SSL mutex modes
+ */
+typedef enum {
+ SSL_MUTEXMODE_UNSET = UNSET,
+ SSL_MUTEXMODE_NONE = 0,
+ SSL_MUTEXMODE_FILE = 1,
+ SSL_MUTEXMODE_SEM = 2
+} ssl_mutexmode_t;
+
+/*
+ * Define the SSL requirement structure
+ */
+typedef struct {
+ char *cpExpr;
+ ssl_expr *mpExpr;
+} ssl_require_t;
+
+/*
+ * Define the SSL random number generator seeding source
+ */
+typedef enum {
+ SSL_RSCTX_STARTUP = 1,
+ SSL_RSCTX_CONNECT = 2
+} ssl_rsctx_t;
+typedef enum {
+ SSL_RSSRC_BUILTIN = 1,
+ SSL_RSSRC_FILE = 2,
+ SSL_RSSRC_EXEC = 3
+} ssl_rssrc_t;
+typedef struct {
+ ssl_rsctx_t nCtx;
+ ssl_rssrc_t nSrc;
+ char *cpPath;
+ int nBytes;
+} ssl_randseed_t;
+
+/*
+ * Define the structure of an ASN.1 anything
+ */
+typedef struct {
+ long int nData;
+ unsigned char *cpData;
+} ssl_asn1_t;
+
+/*
+ * Define the mod_ssl per-module configuration structure
+ * (i.e. the global configuration for each httpd process)
+ */
+
+typedef struct {
+ pool *pPool;
+ BOOL bFixed;
+
+ /*
+ * global config data
+ */
+ int nInitCount;
+
+ RSA *pRSATmpKey;
+ int nSessionCacheMode;
+ char *szSessionCacheDataFile;
+ ssl_mutexmode_t nMutexMode;
+ char *szMutexFile;
+ int nMutexFD;
+ int nMutexSEMID;
+ array_header *aRandSeed;
+
+ ssl_ds_table *tPublicCert;
+ ssl_ds_table *tPrivateKey;
+
+ /*
+ * arbitrary global context data
+ */
+ struct {
+ void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9;
+ } rCtx;
+} SSLModConfigRec;
+
+/*
+ * Define the mod_ssl per-server configuration structure
+ * (i.e. the configuration for the main server
+ * and all <VirtualHost> contexts)
+ */
+typedef struct {
+ BOOL bEnabled;
+ char *szCertificateFile;
+ char *szKeyFile;
+ char *szCACertificatePath;
+ char *szCACertificateFile;
+ char *szLogFile;
+ char *szCipherSuite;
+ FILE *fileLogFile;
+ int nLogLevel;
+ int nVerifyDepth;
+ ssl_verify_t nVerifyClient;
+ X509 *px509Certificate;
+ RSA *prsaKey;
+ SSL_CTX *pSSLCtx;
+ int nSessionCacheTimeout;
+ int nPassPhraseDialogType;
+ char *szPassPhraseDialogPath;
+ ssl_proto_t nProtocol;
+} SSLSrvConfigRec;
+
+/*
+ * Define the mod_ssl per-directory configuration structure
+ * (i.e. the local configuration for all <Directory>
+ * and .htaccess contexts)
+ */
+typedef struct {
+ BOOL bSSLRequired;
+ array_header *aRequirement;
+ ssl_opt_t nOptions;
+ ssl_opt_t nOptionsAdd;
+ ssl_opt_t nOptionsDel;
+ char *szCipherSuite;
+ ssl_verify_t nVerifyClient;
+ int nVerifyDepth;
+#ifdef SSL_EXPERIMENTAL
+ char *szCACertificatePath;
+ char *szCACertificateFile;
+#endif
+} SSLDirConfigRec;
+
+/*
+ * function prototypes
+ */
+
+/* API glue structures */
+extern module MODULE_VAR_EXPORT ssl_module;
+
+/* configuration handling */
+void ssl_config_global_create(void);
+void ssl_config_global_fix(void);
+BOOL ssl_config_global_isfixed(void);
+void *ssl_config_server_create(pool *, server_rec *);
+void *ssl_config_server_merge(pool *, void *, void *);
+void *ssl_config_perdir_create(pool *, char *);
+void *ssl_config_perdir_merge(pool *, void *, void *);
+const char *ssl_cmd_SSLMutex(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLRandomSeed(cmd_parms *, char *, char *, char *, char *);
+const char *ssl_cmd_SSLEngine(cmd_parms *, char *, int flag);
+const char *ssl_cmd_SSLCipherSuite(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLCertificateFile(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLVerifyClient(cmd_parms *, SSLDirConfigRec *, char *level);
+const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLSessionCache(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLLog(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLLogLevel(cmd_parms *, char *, char *);
+const char *ssl_cmd_SSLProtocol(cmd_parms *, char *, const char *);
+const char *ssl_cmd_SSLOptions(cmd_parms *, SSLDirConfigRec *, const char *);
+const char *ssl_cmd_SSLRequireSSL(cmd_parms *, SSLDirConfigRec *, char *);
+const char *ssl_cmd_SSLRequire(cmd_parms *, SSLDirConfigRec *, char *);
+
+/* module initialization */
+void ssl_init_Module(server_rec *, pool *);
+void ssl_init_SSLLibrary(server_rec *);
+void ssl_init_GetCertAndKey(server_rec *, pool *, SSLSrvConfigRec *);
+STACK *ssl_init_FindCAList(server_rec *, pool *, char *, char *);
+void ssl_init_Child(server_rec *, pool *);
+
+/* Apache API hooks */
+void ssl_hook_AddModule(module *);
+void ssl_hook_RemoveModule(module *);
+char *ssl_hook_RewriteCommand(cmd_parms *, void *config, const char *);
+void ssl_hook_NewConnection(conn_rec *);
+void ssl_hook_TimeoutConnection(int);
+void ssl_hook_CloseConnection(void *);
+int ssl_hook_Auth(request_rec *);
+int ssl_hook_Access(request_rec *);
+int ssl_hook_Fixup(request_rec *);
+int ssl_hook_ReadReq(request_rec *);
+int ssl_hook_Handler(request_rec *);
+
+/* SSLeay callbacks */
+RSA *ssl_callback_TmpRSA(SSL *, int);
+int ssl_callback_SSLVerify(int, X509_STORE_CTX *);
+int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *);
+SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
+void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
+void ssl_callback_LogTracingState(SSL *, int, int);
+
+/* Session Cache Support */
+void ssl_scache_init(server_rec *, pool *);
+void ssl_scache_store(server_rec *, SSL_SESSION *, int);
+SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int);
+void ssl_scache_remove(server_rec *, SSL_SESSION *);
+void ssl_scache_expire(server_rec *);
+char *ssl_scache_id2sz(UCHAR *, int);
+void ssl_scache_dbm_init(server_rec *, pool *);
+void ssl_scache_dbm_store(server_rec *, ssl_scinfo_t *);
+void ssl_scache_dbm_retrieve(server_rec *, ssl_scinfo_t *);
+void ssl_scache_dbm_remove(server_rec *, ssl_scinfo_t *);
+void ssl_scache_dbm_expire(server_rec *);
+
+/* Pass Phrase Support */
+void ssl_pphrase_Handle(server_rec *, pool *);
+int ssl_pphrase_Handle_CB(char *, int, int);
+
+/* Data Structures */
+ssl_ds_array *ssl_ds_array_make(pool *, int);
+BOOL ssl_ds_array_isempty(ssl_ds_array *);
+void *ssl_ds_array_push(ssl_ds_array *);
+void *ssl_ds_array_get(ssl_ds_array *, int);
+void ssl_ds_array_wipeout(ssl_ds_array *);
+void ssl_ds_array_kill(ssl_ds_array *);
+ssl_ds_table *ssl_ds_table_make(pool *, int);
+BOOL ssl_ds_table_isempty(ssl_ds_table *);
+void *ssl_ds_table_push(ssl_ds_table *, char *);
+void *ssl_ds_table_get(ssl_ds_table *, char *);
+void ssl_ds_table_wipeout(ssl_ds_table *);
+void ssl_ds_table_kill(ssl_ds_table *);
+
+/* Mutex Support */
+void ssl_mutex_init(server_rec *, pool *);
+void ssl_mutex_open(server_rec *, pool *);
+void ssl_mutex_on(void);
+void ssl_mutex_off(void);
+void ssl_mutex_file_create(server_rec *, pool *);
+void ssl_mutex_file_open(server_rec *, pool *);
+void ssl_mutex_file_remove(void *);
+BOOL ssl_mutex_file_acquire(void);
+BOOL ssl_mutex_file_release(void);
+void ssl_mutex_sem_create(server_rec *, pool *);
+void ssl_mutex_sem_open(server_rec *, pool *);
+void ssl_mutex_sem_remove(void *);
+BOOL ssl_mutex_sem_acquire(void);
+BOOL ssl_mutex_sem_release(void);
+
+/* Logfile Support */
+void ssl_log_open(server_rec *, pool *);
+void ssl_log(server_rec *, int, const char *, ...);
+void ssl_die(void);
+
+/* Variables */
+void ssl_var_register(void);
+void ssl_var_unregister(void);
+char *ssl_var_lookup(pool *, server_rec *, conn_rec *, request_rec *, char *);
+
+/* I/O */
+void ssl_io_register(void);
+void ssl_io_unregister(void);
+long ssl_io_data_cb(BIO *, int, char *, int, long, long);
+
+/* PRNG */
+int ssl_rand_seed(server_rec *, pool *, ssl_rsctx_t);
+
+/* Extensions */
+void ssl_ext_register(void);
+void ssl_ext_unregister(void);
+
+/* Compatibility */
+#ifdef SSL_COMPAT
+char *ssl_compat_directive(server_rec *, pool *, const char *);
+void ssl_compat_variables(request_rec *);
+#endif
+
+/* Utility Functions */
+char *ssl_util_vhostid(pool *, server_rec *);
+void ssl_util_strupper(char *);
+void ssl_util_uuencode(char *, const char *, BOOL);
+void ssl_util_uuencode_binary(unsigned char *, const unsigned char *, int, BOOL);
+FILE *ssl_util_ppopen(server_rec *, pool *, char *);
+int ssl_util_ppopen_child(void *, child_info *);
+void ssl_util_ppclose(server_rec *, pool *, FILE *);
+char *ssl_util_readfilter(server_rec *, pool *, char *);
+BOOL ssl_util_path_check(ssl_pathcheck_t, char *);
+char *ssl_util_ptxtsub(pool *, const char *, const char *, char *);
+void ssl_util_thread_setup(void);
+
+#endif /* MOD_SSL_H */
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c
new file mode 100644
index 00000000000..967fb206bad
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c
@@ -0,0 +1,430 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_compat.c
+** Backward Compatibility
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+ /* ``Backward compatibility is for
+ users who don't want to live
+ on the bleeding edge.''
+ -- Unknown */
+#ifdef SSL_COMPAT
+
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Backward Compatibility
+** _________________________________________________________________
+*/
+
+/*
+ * The mapping of obsolete directives to official ones...
+ */
+
+static char *ssl_compat_SSLRequireCipher(pool *p, const char *, const char *, const char *);
+static char *ssl_compat_SSLBanCipher(pool *p, const char *, const char *, const char *);
+static char *ssl_compat_words2list(pool *p, const char *);
+
+#define CRM_BEGIN /* nop */
+#define CRM_ENTRY(what,action) { what, action },
+#define CRM_END { NULL, NULL, NULL, NULL, NULL, NULL }
+#define CRM_CMD(cmd) cmd, NULL, NULL
+#define CRM_STR(str) NULL, str, NULL
+#define CRM_PAT(cmd) NULL, NULL, pat
+#define CRM_LOG(msg) msg, NULL, NULL
+#define CRM_SUB(new) NULL, new, NULL
+#define CRM_CAL(fct) NULL, NULL, fct
+
+static struct {
+ char *cpCommand;
+ char *cpSubstring;
+ char *cpPattern;
+ char *cpMessage;
+ char *cpSubst;
+ char *(*fpSubst)(pool *, const char *, const char *, const char *);
+} ssl_cmd_rewrite_map[] = {
+ CRM_BEGIN
+
+ /*
+ * Apache-SSL 1.x & mod_ssl 2.0.x backward compatibility
+ */
+ CRM_ENTRY( CRM_CMD("SSLEnable"), CRM_SUB("SSLEngine on") )
+ CRM_ENTRY( CRM_CMD("SSLDisable"), CRM_SUB("SSLEngine off") )
+ CRM_ENTRY( CRM_CMD("SSLLogFile"), CRM_SUB("SSLLog") )
+ CRM_ENTRY( CRM_CMD("SSLRequiredCiphers"), CRM_SUB("SSLCipherSuite") )
+ CRM_ENTRY( CRM_CMD("SSLRequireCipher"), CRM_CAL(ssl_compat_SSLRequireCipher) )
+ CRM_ENTRY( CRM_CMD("SSLBanCipher"), CRM_CAL(ssl_compat_SSLBanCipher) )
+ CRM_ENTRY( CRM_CMD("SSLFakeBasicAuth"), CRM_SUB("SSLOptions +FakeBasicAuth") )
+ CRM_ENTRY( CRM_CMD("SSLCacheServerPath"), CRM_LOG("Use SSLSessionCache instead") )
+ CRM_ENTRY( CRM_CMD("SSLCacheServerPort"), CRM_LOG("Use SSLSessionCache instead") )
+
+ /*
+ * Apache-SSL 1.x backward compatibility
+ */
+ CRM_ENTRY( CRM_CMD("SSLExportClientCertificates"), CRM_SUB("SSLOptions +ExportCertData") )
+ CRM_ENTRY( CRM_CMD("SSLCacheServerRunDir"), CRM_LOG("Not needed for mod_ssl") )
+
+ /*
+ * Sioux 1.x backward compatibility
+ */
+ CRM_ENTRY( CRM_CMD("SSL_CertFile"), CRM_SUB("SSLCertificateFile") )
+ CRM_ENTRY( CRM_CMD("SSL_KeyFile"), CRM_SUB("SSLCertificateKeyFile") )
+ CRM_ENTRY( CRM_CMD("SSL_CipherSuite"), CRM_SUB("SSLCipherSuite") )
+ CRM_ENTRY( CRM_CMD("SSL_X509VerifyDir"), CRM_SUB("SSLCACertificatePath") )
+ CRM_ENTRY( CRM_CMD("SSL_Log"), CRM_SUB("SSLLogFile") )
+ CRM_ENTRY( CRM_CMD("SSL_Connect"), CRM_SUB("SSLEngine") )
+ CRM_ENTRY( CRM_CMD("SSL_ClientAuth"), CRM_SUB("SSLVerifyClient") )
+ CRM_ENTRY( CRM_CMD("SSL_X509VerifyDepth"), CRM_SUB("SSLVerifyDepth") )
+ CRM_ENTRY( CRM_CMD("SSL_FetchKeyPhraseFrom"), CRM_LOG("Use SSLPassPhraseDialog instead") )
+ CRM_ENTRY( CRM_CMD("SSL_SessionDir"), CRM_LOG("Use SSLSessionCache instead") )
+ CRM_ENTRY( CRM_CMD("SSL_Require"), CRM_LOG("Use SSLRequire instead (Syntax!)"))
+ CRM_ENTRY( CRM_CMD("SSL_CertFileType"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSL_KeyFileType"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSL_X509VerifyPolicy"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSL_LogX509Attributes"), CRM_LOG("Not supported by mod_ssl") )
+
+ /*
+ * Stronghold 2.x backward compatibility
+ */
+ CRM_ENTRY( CRM_CMD("SSLFlag"), CRM_SUB("SSLEngine") )
+ CRM_ENTRY( CRM_CMD("SSLSessionLockFile"), CRM_SUB("SSLMutex") )
+ CRM_ENTRY( CRM_CMD("RequireSSL"), CRM_SUB("SSLRequireSSL") )
+ CRM_ENTRY( CRM_CMD("SSLCipherList"), CRM_SUB("SSLCipherSuite") )
+ CRM_ENTRY( CRM_CMD("SSLErrorFile"), CRM_LOG("Not needed for mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLRoot"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSL_CertificateLogDir"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("AuthCertDir"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSL_Group"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyMachineCertPath"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyMachineCertFile"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyCACertificatePath"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyCACertificateFile"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyVerifyDepth"), CRM_LOG("Not supported by mod_ssl") )
+ CRM_ENTRY( CRM_CMD("SSLProxyCipherList"), CRM_LOG("Not supported by mod_ssl") )
+
+ CRM_END
+};
+
+static char *ssl_compat_SSLRequireCipher(pool *p, const char *oline, const char *cmd, const char *args)
+{
+ return ap_pstrcat(p, "SSLRequire %{SSL_CIPHER} in {",
+ ssl_compat_words2list(p, args),
+ "}", NULL);
+}
+
+static char *ssl_compat_SSLBanCipher(pool *p, const char *oline, const char *cmd, const char *args)
+{
+ return ap_pstrcat(p, "SSLRequire not (%{SSL_CIPHER} in {",
+ ssl_compat_words2list(p, args),
+ "})", NULL);
+}
+
+static char *ssl_compat_words2list(pool *p, const char *oline)
+{
+ char *line;
+ char *cpB;
+ char *cpE;
+ char *cpI;
+ char *cpO;
+ char n;
+
+ /*
+ * Step 1: Determine borders
+ */
+ cpB = (char *)oline;
+ while (*cpB == ' ' || *cpB == '\t')
+ cpB++;
+ cpE = cpB+strlen(cpB);
+ while (cpE > cpB && (*(cpE-1) == ' ' || *(cpE-1) == '\t'))
+ cpE--;
+
+ /*
+ * Step 2: Determine final size and allocate buffer
+ */
+ for (cpI = cpB, n = 1; cpI < cpE; cpI++)
+ if ((*cpI == ' ' || *cpI == '\t') &&
+ (cpI > cpB && *(cpI-1) != ' ' && *(cpI-1) != '\t'))
+ n++;
+ line = ap_palloc(p, (cpE-cpB)+(n*2)+n+1);
+ cpI = cpB;
+ cpO = line;
+ while (cpI < cpE) {
+ if ( (*cpI != ' ' && *cpI != '\t')
+ && ( cpI == cpB
+ || ( cpI > cpB
+ && (*(cpI-1) == ' ' || *(cpI-1) == '\t')))) {
+ *cpO++ = '"';
+ *cpO++ = *cpI++;
+ }
+ else if ( (*cpI == ' ' || *cpI == '\t')
+ && ( cpI > cpB
+ && (*(cpI-1) != ' ' && *(cpI-1) != '\t'))) {
+ *cpO++ = '"';
+ *cpO++ = ',';
+ *cpO++ = *cpI++;
+ }
+ else {
+ *cpO++ = *cpI++;
+ }
+ }
+ if (cpI > cpB && (*(cpI-1) != ' ' && *(cpI-1) != '\t'))
+ *cpO++ = '"';
+ *cpO++ = NUL;
+ return line;
+}
+
+char *ssl_compat_directive(server_rec *s, pool *p, const char *oline)
+{
+ int i;
+ char *line;
+ char *cp;
+ char caCmd[1024];
+ char *cpArgs;
+ int match;
+
+ /*
+ * Skip comment lines
+ */
+ cp = (char *)oline;
+ while ((*cp == ' ' || *cp == '\t' || *cp == '\n') && (*cp != NUL))
+ cp++;
+ if (*cp == '#' || *cp == NUL)
+ return NULL;
+
+ /*
+ * Extract directive name
+ */
+ cp = (char *)oline;
+ for (i = 0; *cp != ' ' && *cp != '\t' && *cp != NUL && i < 1024; )
+ caCmd[i++] = *cp++;
+ caCmd[i] = NUL;
+ cpArgs = cp;
+
+ /*
+ * Apply rewriting map
+ */
+ line = NULL;
+ for (i = 0; !(ssl_cmd_rewrite_map[i].cpCommand == NULL &&
+ ssl_cmd_rewrite_map[i].cpPattern == NULL ); i++) {
+ /*
+ * Matching
+ */
+ match = FALSE;
+ if (ssl_cmd_rewrite_map[i].cpCommand != NULL) {
+ if (strcEQ(ssl_cmd_rewrite_map[i].cpCommand, caCmd))
+ match = TRUE;
+ }
+ else if (ssl_cmd_rewrite_map[i].cpSubstring != NULL) {
+ if (strstr(oline, ssl_cmd_rewrite_map[i].cpSubstring) != NULL)
+ match = TRUE;
+ }
+ else if (ssl_cmd_rewrite_map[i].cpPattern != NULL) {
+ if (ap_fnmatch(ssl_cmd_rewrite_map[i].cpPattern, oline, 0))
+ match = TRUE;
+ }
+
+ /*
+ * Action Processing
+ */
+ if (match) {
+ if (ssl_cmd_rewrite_map[i].cpMessage != NULL) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, s,
+ "mod_ssl:Compat: OBSOLETE '%s' => %s",
+ oline, ssl_cmd_rewrite_map[i].cpMessage);
+ line = "";
+ break;
+ }
+ else if (ssl_cmd_rewrite_map[i].cpSubst != NULL) {
+ if (ssl_cmd_rewrite_map[i].cpCommand != NULL)
+ line = ap_pstrcat(p, ssl_cmd_rewrite_map[i].cpSubst,
+ cpArgs, NULL);
+ else if (ssl_cmd_rewrite_map[i].cpSubstring != NULL)
+ line = ssl_util_ptxtsub(p, oline, ssl_cmd_rewrite_map[i].cpSubstring,
+ ssl_cmd_rewrite_map[i].cpSubst);
+ else
+ line = ssl_cmd_rewrite_map[i].cpSubst;
+ break;
+ }
+ else if (ssl_cmd_rewrite_map[i].fpSubst != NULL) {
+ line = ((char *(*)(pool *, const char *, const char *, const char *))
+ (ssl_cmd_rewrite_map[i].fpSubst))(p, oline, caCmd, cpArgs);
+ break;
+ }
+ }
+ }
+ if (line != NULL && line[0] != NUL)
+ ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s,
+ "mod_ssl:Compat: MAPPED '%s' => '%s'", oline, line);
+ return line;
+}
+
+/*
+ * The mapping of obsolete environment variables to official ones...
+ */
+
+#define VRM_BEGIN /* nop */
+#define VRM_ENTRY(var,action) { var, action },
+#define VRM_END { NULL, NULL, NULL }
+#define VRM_VAR(old) old
+#define VRM_SUB(new) new, NULL
+#define VRM_LOG(msg) NULL, msg
+
+static struct {
+ char *cpOld;
+ char *cpNew;
+ char *cpMsg;
+} ssl_var_rewrite_map[] = {
+ VRM_BEGIN
+
+ /*
+ * Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.x
+ * and Stronghold 2.x backward compatibility
+ */
+ VRM_ENTRY( VRM_VAR("SSL_PROTOCOL_VERSION"), VRM_SUB("SSL_PROTOCOL") )
+ VRM_ENTRY( VRM_VAR("SSLEAY_VERSION"), VRM_SUB("SSL_VERSION_LIBRARY") )
+ VRM_ENTRY( VRM_VAR("HTTPS_SECRETKEYSIZE"), VRM_SUB("SSL_CIPHER_USEKEYSIZE") )
+ VRM_ENTRY( VRM_VAR("HTTPS_KEYSIZE"), VRM_SUB("SSL_CIPHER_ALGKEYSIZE") )
+ VRM_ENTRY( VRM_VAR("HTTPS_CIPHER"), VRM_SUB("SSL_CIPHER") )
+ VRM_ENTRY( VRM_VAR("HTTPS_EXPORT"), VRM_SUB("SSL_CIPHER_EXPORT") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_SIZE"), VRM_SUB("SSL_CIPHER_ALGKEYSIZE") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTIFICATE"), VRM_SUB("SSL_SERVER_CERT") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CERT_START"), VRM_SUB("SSL_SERVER_V_START") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CERT_END"), VRM_SUB("SSL_SERVER_V_END") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_DN"), VRM_SUB("SSL_SERVER_S_DN") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CN"), VRM_SUB("SSL_SERVER_S_DN_CN") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_EMAIL"), VRM_SUB("SSL_SERVER_S_DN_Email") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_O"), VRM_SUB("SSL_SERVER_S_DN_O") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_OU"), VRM_SUB("SSL_SERVER_S_DN_OU") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_C"), VRM_SUB("SSL_SERVER_S_DN_C") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_SP"), VRM_SUB("SSL_SERVER_S_DN_SP") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_L"), VRM_SUB("SSL_SERVER_S_DN_L") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IDN"), VRM_SUB("SSL_SERVER_I_DN") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_ICN"), VRM_SUB("SSL_SERVER_I_DN_CN") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IEMAIL"), VRM_SUB("SSL_SERVER_I_DN_Email") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IO"), VRM_SUB("SSL_SERVER_I_DN_O") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IOU"), VRM_SUB("SSL_SERVER_I_DN_OU") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IC"), VRM_SUB("SSL_SERVER_I_DN_C") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_ISP"), VRM_SUB("SSL_SERVER_I_DN_SP") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_IL"), VRM_SUB("SSL_SERVER_I_DN_L") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERTIFICATE"), VRM_SUB("SSL_CLIENT_CERT") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERT_START"), VRM_SUB("SSL_CLIENT_V_START") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERT_END"), VRM_SUB("SSL_CLIENT_V_END") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_DN"), VRM_SUB("SSL_CLIENT_S_DN") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_CN"), VRM_SUB("SSL_CLIENT_S_DN_CN") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_EMAIL"), VRM_SUB("SSL_CLIENT_S_DN_Email") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_O"), VRM_SUB("SSL_CLIENT_S_DN_O") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_OU"), VRM_SUB("SSL_CLIENT_S_DN_OU") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_C"), VRM_SUB("SSL_CLIENT_S_DN_C") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_SP"), VRM_SUB("SSL_CLIENT_S_DN_SP") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_L"), VRM_SUB("SSL_CLIENT_S_DN_L") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IDN"), VRM_SUB("SSL_CLIENT_I_DN") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_ICN"), VRM_SUB("SSL_CLIENT_I_DN_CN") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IEMAIL"), VRM_SUB("SSL_CLIENT_I_DN_Email") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IO"), VRM_SUB("SSL_CLIENT_I_DN_O") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IOU"), VRM_SUB("SSL_CLIENT_I_DN_OU") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IC"), VRM_SUB("SSL_CLIENT_I_DN_C") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_ISP"), VRM_SUB("SSL_CLIENT_I_DN_SP") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_IL"), VRM_SUB("SSL_CLIENT_I_DN_L") )
+
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_EXP"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_ALGORITHM"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_SIGNATURE_ALGORITHM"),VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_SESSIONDIR"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTIFICATELOGDIR"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTFILE"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_KEYFILE"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_SERVER_KEYFILETYPE"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_EXP"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_ALGORITHM"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_SIZE"), VRM_LOG("Not supported by mod_ssl") )
+ VRM_ENTRY( VRM_VAR("SSL_CLIENT_SIGNATURE_ALGORITHM"),VRM_LOG("Not supported by mod_ssl") )
+
+ VRM_END
+};
+
+void ssl_compat_variables(request_rec *r)
+{
+ char *cpOld;
+ char *cpNew;
+ char *cpMsg;
+ char *cpVal;
+ int i;
+
+ for (i = 0; ssl_var_rewrite_map[i].cpOld != NULL; i++) {
+ cpOld = ssl_var_rewrite_map[i].cpOld;
+ cpMsg = ssl_var_rewrite_map[i].cpMsg;
+ cpNew = ssl_var_rewrite_map[i].cpNew;
+ if (cpNew != NULL) {
+ cpVal = ssl_var_lookup(r->pool, r->server, r->connection, r, cpNew);
+ if (!strIsEmpty(cpVal))
+ ap_table_set(r->subprocess_env, cpOld, cpVal);
+ }
+ else if (cpMsg != NULL) {
+ /*
+ * we cannot print a message, so we at least the
+ * variables contents to the message
+ */
+ ap_table_set(r->subprocess_env, cpOld, cpMsg);
+ }
+ }
+ return;
+}
+
+#endif /* SSL_COMPAT */
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c
new file mode 100644
index 00000000000..3adf553c20d
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c
@@ -0,0 +1,722 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_config.c
+** Apache Configuration Directives
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+ /* ``Damned if you do,
+ damned if you don't.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Support for Global Configuration
+** _________________________________________________________________
+*/
+
+void ssl_hook_AddModule(module *m)
+{
+ if (m == &ssl_module) {
+ /*
+ * Announce us for the configuration files
+ */
+ ap_add_config_define("MOD_SSL");
+
+ /*
+ * Link ourself into the Apache kernel
+ */
+ ssl_var_register();
+ ssl_ext_register();
+ ssl_io_register();
+ }
+ return;
+}
+
+void ssl_hook_RemoveModule(module *m)
+{
+ if (m == &ssl_module) {
+ /*
+ * Unlink ourself from the Apache kernel
+ */
+ ssl_var_unregister();
+ ssl_ext_unregister();
+ ssl_io_unregister();
+ }
+ return;
+}
+
+void ssl_config_global_create(void)
+{
+ pool *pPool;
+ SSLModConfigRec *mc;
+
+ mc = ap_ctx_get(ap_global_ctx, "ssl_module");
+ if (mc == NULL) {
+ /*
+ * allocate an own subpool which survives server restarts
+ */
+ pPool = ap_make_sub_pool(NULL);
+ mc = (SSLModConfigRec *)ap_palloc(pPool, sizeof(SSLModConfigRec));
+ mc->pPool = pPool;
+ mc->bFixed = FALSE;
+
+ /*
+ * initialize per-module configuration
+ */
+ mc->nInitCount = 0;
+ mc->pRSATmpKey = NULL;
+ mc->nSessionCacheMode = SSL_SCMODE_UNSET;
+ mc->szSessionCacheDataFile = NULL;
+ mc->nMutexMode = SSL_MUTEXMODE_UNSET;
+ mc->szMutexFile = NULL;
+ mc->nMutexFD = -1;
+ mc->nMutexSEMID = -1;
+ mc->aRandSeed = ap_make_array(pPool, 4, sizeof(ssl_randseed_t));
+
+ mc->tPrivateKey = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
+ mc->tPublicCert = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
+
+ /*
+ * And push it into Apache's global context
+ */
+ ap_ctx_set(ap_global_ctx, "ssl_module", mc);
+ }
+ return;
+}
+
+void ssl_config_global_fix(void)
+{
+ SSLModConfigRec *mc = myModConfig();
+ mc->bFixed = TRUE;
+ return;
+}
+
+BOOL ssl_config_global_isfixed(void)
+{
+ SSLModConfigRec *mc = myModConfig();
+ return (mc->bFixed);
+}
+
+
+/* _________________________________________________________________
+**
+** Configuration handling
+** _________________________________________________________________
+*/
+
+/*
+ * Create per-server SSL configuration
+ */
+void *ssl_config_server_create(pool *p, server_rec *s)
+{
+ SSLSrvConfigRec *sc;
+
+ ssl_config_global_create();
+
+ sc = ap_palloc(p, sizeof(SSLSrvConfigRec));
+ sc->bEnabled = UNSET;
+ sc->szCertificateFile = NULL;
+ sc->szKeyFile = NULL;
+ sc->szCACertificatePath = NULL;
+ sc->szCACertificateFile = NULL;
+ sc->szLogFile = NULL;
+ sc->szCipherSuite = NULL;
+ sc->nLogLevel = SSL_LOG_NONE;
+ sc->nVerifyDepth = UNSET;
+ sc->nVerifyClient = SSL_CVERIFY_UNSET;
+ sc->nSessionCacheTimeout = UNSET;
+ sc->nPassPhraseDialogType = SSL_PPTYPE_UNSET;
+ sc->szPassPhraseDialogPath = NULL;
+ sc->nProtocol = SSL_PROTOCOL_ALL;
+ sc->fileLogFile = NULL;
+ sc->px509Certificate = NULL;
+ sc->prsaKey = NULL;
+ sc->pSSLCtx = NULL;
+
+ return sc;
+}
+
+/*
+ * Merge per-server SSL configurations
+ */
+void *ssl_config_server_merge(pool *p, void *basev, void *addv)
+{
+ SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
+ SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
+ SSLSrvConfigRec *new = (SSLSrvConfigRec *)ap_palloc(p, sizeof(SSLSrvConfigRec));
+
+ cfgMergeBool(bEnabled);
+ cfgMergeString(szCertificateFile);
+ cfgMergeString(szKeyFile);
+ cfgMergeString(szCACertificatePath);
+ cfgMergeString(szCACertificateFile);
+ cfgMergeString(szLogFile);
+ cfgMergeString(szCipherSuite);
+ cfgMerge(nLogLevel, SSL_LOG_NONE);
+ cfgMergeInt(nVerifyDepth);
+ cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
+ cfgMergeInt(nSessionCacheTimeout);
+ cfgMerge(nPassPhraseDialogType, SSL_PPTYPE_UNSET);
+ cfgMergeString(szPassPhraseDialogPath);
+ cfgMerge(nProtocol, SSL_PROTOCOL_ALL);
+ cfgMerge(fileLogFile, NULL);
+ cfgMerge(px509Certificate, NULL);
+ cfgMerge(prsaKey, NULL);
+ cfgMerge(pSSLCtx, NULL);
+
+ return new;
+}
+
+/*
+ * Create per-directory SSL configuration
+ */
+void *ssl_config_perdir_create(pool *p, char *dir)
+{
+ SSLDirConfigRec *dc = ap_palloc(p, sizeof(SSLDirConfigRec));
+
+ dc->bSSLRequired = FALSE;
+ dc->aRequirement = ap_make_array(p, 4, sizeof(ssl_require_t));
+ dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
+ dc->nOptionsAdd = SSL_OPT_NONE;
+ dc->nOptionsDel = SSL_OPT_NONE;
+
+ dc->szCipherSuite = NULL;
+ dc->nVerifyClient = SSL_CVERIFY_UNSET;
+ dc->nVerifyDepth = UNSET;
+#ifdef SSL_EXPERIMENTAL
+ dc->szCACertificatePath = NULL;
+ dc->szCACertificateFile = NULL;
+#endif
+
+ return dc;
+}
+
+/*
+ * Merge per-directory SSL configurations
+ */
+void *ssl_config_perdir_merge(pool *p, void *basev, void *addv)
+{
+ SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
+ SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
+ SSLDirConfigRec *new = (SSLDirConfigRec *)ap_palloc(p,
+ sizeof(SSLDirConfigRec));
+
+ cfgMerge(bSSLRequired, FALSE);
+ cfgMergeArray(aRequirement);
+
+ if (add->nOptions & SSL_OPT_RELSET) {
+ new->nOptionsAdd = (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
+ new->nOptionsDel = (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
+ new->nOptions = (base->nOptions & ~(new->nOptionsDel)) | new->nOptionsAdd;
+ }
+ else {
+ new->nOptions = add->nOptions;
+ new->nOptionsAdd = add->nOptionsAdd;
+ new->nOptionsDel = add->nOptionsDel;
+ }
+
+ cfgMergeString(szCipherSuite);
+ cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
+ cfgMergeInt(nVerifyDepth);
+#ifdef SSL_EXPERIMENTAL
+ cfgMergeString(szCACertificatePath);
+ cfgMergeString(szCACertificateFile);
+#endif
+
+ return new;
+}
+
+/*
+ * Directive Rewriting
+ */
+
+char *ssl_hook_RewriteCommand(cmd_parms *cmd, void *config, const char *cmd_line)
+{
+#ifdef SSL_COMPAT
+ return ssl_compat_directive(cmd->server, cmd->pool, cmd_line);
+#else
+ return NULL;
+#endif
+}
+
+/*
+ * Configuration functions for particular directives
+ */
+
+const char *ssl_cmd_SSLMutex(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ const char *err;
+ SSLModConfigRec *mc = myModConfig();
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
+ return err;
+ if (ssl_config_global_isfixed())
+ return NULL;
+ if (strcEQ(arg, "none")) {
+ mc->nMutexMode = SSL_MUTEXMODE_NONE;
+ }
+ else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
+ mc->nMutexMode = SSL_MUTEXMODE_FILE;
+ mc->szMutexFile = ap_psprintf(mc->pPool, "%s.%lu",
+ ap_server_root_relative(cmd->pool, arg+5),
+ (unsigned long)getpid());
+ }
+ else if (strcEQ(arg, "sem")) {
+#ifdef SSL_CAN_USE_SEM
+ mc->nMutexMode = SSL_MUTEXMODE_SEM;
+#else
+ return "SSLMutex: Semaphores not available on this platform";
+#endif
+ }
+ else
+ return "SSLMutex: Invalid argument";
+ return NULL;
+}
+
+const char *ssl_cmd_SSLPassPhraseDialog(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
+ return err;
+ if (strcEQ(arg, "builtin")) {
+ sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN;
+ sc->szPassPhraseDialogPath = NULL;
+ }
+ else if (strlen(arg) > 5 && strEQn(arg, "exec:", 5)) {
+ sc->nPassPhraseDialogType = SSL_PPTYPE_FILTER;
+ sc->szPassPhraseDialogPath = ap_server_root_relative(cmd->pool, arg+5);
+ if (!ssl_util_path_check(SSL_PCM_EXISTS, sc->szPassPhraseDialogPath))
+ return ap_pstrcat(cmd->pool, "SSLPassPhraseDialog: file '",
+ sc->szPassPhraseDialogPath, "' not exists", NULL);
+ }
+ else
+ return "SSLPassPhraseDialog: Invalid argument";
+ return NULL;
+}
+
+const char *ssl_cmd_SSLRandomSeed(
+ cmd_parms *cmd, char *struct_ptr, char *arg1, char *arg2, char *arg3)
+{
+ SSLModConfigRec *mc = myModConfig();
+ const char *err;
+ ssl_randseed_t *pRS;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
+ return err;
+ if (ssl_config_global_isfixed())
+ return NULL;
+ pRS = ap_push_array(mc->aRandSeed);
+ if (strcEQ(arg1, "startup"))
+ pRS->nCtx = SSL_RSCTX_STARTUP;
+ else if (strcEQ(arg1, "connect"))
+ pRS->nCtx = SSL_RSCTX_CONNECT;
+ else
+ return ap_pstrcat(cmd->pool, "SSLRandomSeed: "
+ "invalid context: `", arg1, "'");
+ if (strlen(arg2) > 5 && strEQn(arg2, "file:", 5)) {
+ pRS->nSrc = SSL_RSSRC_FILE;
+ pRS->cpPath = ap_pstrdup(mc->pPool, ap_server_root_relative(cmd->pool, arg2+5));
+ }
+ else if (strlen(arg2) > 5 && strEQn(arg2, "exec:", 5)) {
+ pRS->nSrc = SSL_RSSRC_EXEC;
+ pRS->cpPath = ap_pstrdup(mc->pPool, ap_server_root_relative(cmd->pool, arg2+5));
+ }
+ else if (strcEQ(arg2, "builtin")) {
+ pRS->nSrc = SSL_RSSRC_BUILTIN;
+ pRS->cpPath = NULL;
+ }
+ else {
+ pRS->nSrc = SSL_RSSRC_FILE;
+ pRS->cpPath = ap_pstrdup(mc->pPool, ap_server_root_relative(cmd->pool, arg2));
+ }
+ if (pRS->nSrc != SSL_RSSRC_BUILTIN)
+ if (!ssl_util_path_check(SSL_PCM_EXISTS, pRS->cpPath))
+ return ap_pstrcat(cmd->pool, "SSLRandomSeed: source path '",
+ pRS->cpPath, "' not exists", NULL);
+ if (arg3 == NULL)
+ pRS->nBytes = 0; /* read whole file */
+ else {
+ if (pRS->nSrc == SSL_RSSRC_BUILTIN)
+ return "SSLRandomSeed: byte specification not "
+ "allowd for builtin seed source";
+ pRS->nBytes = atoi(arg3);
+ if (pRS->nBytes < 0)
+ return "SSLRandomSeed: invalid number of bytes specified";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLEngine(
+ cmd_parms *cmd, char *struct_ptr, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->bEnabled = (flag ? TRUE : FALSE);
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCipherSuite(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ if (cmd->path == NULL || dc == NULL)
+ sc->szCipherSuite = arg;
+ else
+ dc->szCipherSuite = arg;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCertificateFile(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ char *cpPath;
+
+ cpPath = ap_server_root_relative(cmd->pool, arg);
+ if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
+ return ap_pstrcat(cmd->pool, "SSLCertificateFile: file '",
+ cpPath, "' not exists or empty", NULL);
+ sc->szCertificateFile = cpPath;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCertificateKeyFile(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ char *cpPath;
+
+ cpPath = ap_server_root_relative(cmd->pool, arg);
+ if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
+ return ap_pstrcat(cmd->pool, "SSLCertificateKeyFile: file '",
+ cpPath, "' not exists or empty", NULL);
+ sc->szKeyFile = cpPath;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCACertificatePath(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ char *cpPath;
+
+ cpPath = ap_server_root_relative(cmd->pool, arg);
+ if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
+ return ap_pstrcat(cmd->pool, "SSLCACertificatePath: directory '",
+ cpPath, "' not exists", NULL);
+#ifdef SSL_EXPERIMENTAL
+ if (cmd->path == NULL || dc == NULL)
+ sc->szCACertificatePath = cpPath;
+ else
+ dc->szCACertificatePath = cpPath;
+#else
+ sc->szCACertificatePath = cpPath;
+#endif
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCACertificateFile(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ char *cpPath;
+
+ cpPath = ap_server_root_relative(cmd->pool, arg);
+ if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
+ return ap_pstrcat(cmd->pool, "SSLCACertificateKeyFile: file '",
+ cpPath, "' not exists or empty", NULL);
+#ifdef SSL_EXPERIMENTAL
+ if (cmd->path == NULL || dc == NULL)
+ sc->szCACertificateFile = cpPath;
+ else
+ dc->szCACertificateFile = cpPath;
+#else
+ sc->szCACertificateFile = cpPath;
+#endif
+ return NULL;
+}
+
+const char *ssl_cmd_SSLVerifyClient(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *level)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ int id;
+
+ if (strEQ(level, "0") || strcEQ(level, "none"))
+ id = SSL_CVERIFY_NONE;
+ else if (strEQ(level, "1") || strcEQ(level, "optional"))
+ id = SSL_CVERIFY_OPTIONAL;
+ else if (strEQ(level, "2") || strcEQ(level, "require"))
+ id = SSL_CVERIFY_REQUIRE;
+ else if (strEQ(level, "3") || strcEQ(level, "optional_no_ca"))
+ id = SSL_CVERIFY_OPTIONAL_NO_CA;
+ else
+ return "SSLVerifyClient: Invalid argument";
+ if (cmd->path == NULL || dc == NULL)
+ sc->nVerifyClient = id;
+ else
+ dc->nVerifyClient = id;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLVerifyDepth(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ int d;
+
+ d = atoi(arg);
+ if (d < 0)
+ return "SSLVerifyDepth: Invalid argument";
+ if (cmd->path == NULL || dc == NULL)
+ sc->nVerifyDepth = d;
+ else
+ dc->nVerifyDepth = d;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLSessionCache(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ const char *err;
+ SSLModConfigRec *mc = myModConfig();
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
+ return err;
+ if (ssl_config_global_isfixed())
+ return NULL;
+ if (strcEQ(arg, "none")) {
+ mc->nSessionCacheMode = SSL_SCMODE_NONE;
+ mc->szSessionCacheDataFile = NULL;
+ }
+ else if (strlen(arg) > 4 && strcEQn(arg, "dbm:", 4)) {
+ mc->nSessionCacheMode = SSL_SCMODE_DBM;
+ mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
+ ap_server_root_relative(cmd->pool, arg+4));
+ }
+ else
+ return "SSLSessionCache: Invalid argument";
+ return NULL;
+}
+
+const char *ssl_cmd_SSLSessionCacheTimeout(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->nSessionCacheTimeout = atoi(arg);
+ if (sc->nSessionCacheTimeout < 0)
+ return "SSLSessionCacheTimeout: Invalid argument";
+ return NULL;
+}
+
+const char *ssl_cmd_SSLLog(
+ cmd_parms *cmd, char *struct_ptr, char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_DIRECTORY
+ |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
+ return err;
+ sc->szLogFile = arg;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLLogLevel(
+ cmd_parms *cmd, char *struct_ptr, char *level)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_DIRECTORY
+ |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
+ return err;
+ if (strcEQ(level, "none"))
+ sc->nLogLevel = SSL_LOG_NONE;
+ else if (strcEQ(level, "error"))
+ sc->nLogLevel = SSL_LOG_ERROR;
+ else if (strcEQ(level, "warn"))
+ sc->nLogLevel = SSL_LOG_WARN;
+ else if (strcEQ(level, "info"))
+ sc->nLogLevel = SSL_LOG_INFO;
+ else if (strcEQ(level, "trace"))
+ sc->nLogLevel = SSL_LOG_TRACE;
+ else if (strcEQ(level, "debug"))
+ sc->nLogLevel = SSL_LOG_DEBUG;
+ else
+ return "SSLLogLevel: Invalid argument";
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOptions(
+ cmd_parms *cmd, SSLDirConfigRec *dc, const char *cpLine)
+{
+ ssl_opt_t opt;
+ int first;
+ char action;
+ char *w;
+
+ first = TRUE;
+ while (cpLine[0] != NUL) {
+ w = ap_getword_conf(cmd->pool, &cpLine);
+ action = NUL;
+
+ if (*w == '+' || *w == '-') {
+ action = *(w++);
+ }
+ else if (first) {
+ dc->nOptions = SSL_OPT_NONE;
+ first = FALSE;
+ }
+
+ if (strcEQ(w, "CompatEnvVars"))
+ opt = SSL_OPT_COMPATENVVARS;
+ else if (strcEQ(w, "ExportCertData"))
+ opt = SSL_OPT_EXPORTCERTDATA;
+ else if (strcEQ(w, "FakeBasicAuth"))
+ opt = SSL_OPT_FAKEBASICAUTH;
+ else
+ return ap_pstrcat(cmd->pool, "SSLOptions: Illegal option '", w, "'", NULL);
+
+ if (action == '-') {
+ dc->nOptionsAdd &= ~opt;
+ dc->nOptionsDel |= opt;
+ dc->nOptions &= ~opt;
+ }
+ else if (action == '+') {
+ dc->nOptionsAdd |= opt;
+ dc->nOptionsDel &= ~opt;
+ dc->nOptions |= opt;
+ }
+ else {
+ dc->nOptions = opt;
+ dc->nOptionsAdd = opt;
+ dc->nOptionsDel = SSL_OPT_NONE;
+ }
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLRequireSSL(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *cipher)
+{
+ dc->bSSLRequired = TRUE;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLRequire(
+ cmd_parms *cmd, SSLDirConfigRec *dc, char *cpExpr)
+{
+ ssl_expr *mpExpr;
+ ssl_require_t *pReqRec;
+
+ if ((mpExpr = ssl_expr_comp(cmd->pool, cpExpr)) == NULL)
+ return ap_pstrcat(cmd->pool, "SSLRequire: ", ssl_expr_get_error(), NULL);
+ pReqRec = ap_push_array(dc->aRequirement);
+ pReqRec->cpExpr = ap_pstrdup(cmd->pool, cpExpr);
+ pReqRec->mpExpr = mpExpr;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLProtocol(
+ cmd_parms *cmd, char *struct_ptr, const char *opt)
+{
+ SSLSrvConfigRec *sc;
+ ssl_proto_t options, thisopt;
+ char action;
+ char *w;
+
+ sc = mySrvConfig(cmd->server);
+ options = SSL_PROTOCOL_NONE;
+ while (opt[0] != NUL) {
+ w = ap_getword_conf(cmd->pool, &opt);
+
+ action = NUL;
+ if (*w == '+' || *w == '-')
+ action = *(w++);
+
+ if (strcEQ(w, "SSLv2"))
+ thisopt = SSL_PROTOCOL_SSLV2;
+ else if (strcEQ(w, "SSLv3"))
+ thisopt = SSL_PROTOCOL_SSLV3;
+ else if (strcEQ(w, "TLSv1"))
+ thisopt = SSL_PROTOCOL_TLSV1;
+ else if (strcEQ(w, "all"))
+ thisopt = SSL_PROTOCOL_ALL;
+ else
+ return ap_pstrcat(cmd->pool, "SSLProtocol: Illegal protocol '", w, "'", NULL);
+
+ if (action == '-')
+ options &= ~thisopt;
+ else if (action == '+')
+ options |= thisopt;
+ else
+ options = thisopt;
+ }
+ sc->nProtocol = options;
+ return NULL;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c
new file mode 100644
index 00000000000..04d8c0bd38c
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c
@@ -0,0 +1,195 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_ds.c
+** Additional Data Structures
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``If you can't do it in
+ C or assembly language,
+ it isn't worth doing.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Data Structures which store _arbitrary_ data
+** _________________________________________________________________
+*/
+
+ssl_ds_array *ssl_ds_array_make(pool *p, int size)
+{
+ ssl_ds_array *a;
+
+ if ((a = (ssl_ds_array *)ap_palloc(p, sizeof(ssl_ds_array))) == NULL)
+ return NULL;
+ a->pPool = p;
+ if ((a->pSubPool = ap_make_sub_pool(p)) == NULL)
+ return NULL;
+ a->aData = ap_make_array(a->pSubPool, 2, size);
+ return a;
+}
+
+BOOL ssl_ds_array_isempty(ssl_ds_array *a)
+{
+ if (a == NULL || a->aData == NULL || a->aData->nelts == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void *ssl_ds_array_push(ssl_ds_array *a)
+{
+ void *d;
+
+ d = (void *)ap_push_array(a->aData);
+ return d;
+}
+
+void *ssl_ds_array_get(ssl_ds_array *a, int n)
+{
+ void *d;
+
+ if (n < 0 || n >= a->aData->nelts)
+ return NULL;
+ d = (void *)(a->aData->elts+(a->aData->elt_size*n));
+ return d;
+}
+
+void ssl_ds_array_wipeout(ssl_ds_array *a)
+{
+ if (a->aData->nelts > 0)
+ memset(a->aData->elts, 0, a->aData->elt_size*a->aData->nelts);
+ return;
+}
+
+void ssl_ds_array_kill(ssl_ds_array *a)
+{
+ ap_destroy_pool(a->pSubPool);
+ a->pSubPool = NULL;
+ a->aData = NULL;
+ return;
+}
+
+ssl_ds_table *ssl_ds_table_make(pool *p, int size)
+{
+ ssl_ds_table *t;
+
+ if ((t = (ssl_ds_table *)ap_palloc(p, sizeof(ssl_ds_table))) == NULL)
+ return NULL;
+ t->pPool = p;
+ if ((t->pSubPool = ap_make_sub_pool(p)) == NULL)
+ return NULL;
+ t->aKey = ap_make_array(t->pSubPool, 2, MAX_STRING_LEN);
+ t->aData = ap_make_array(t->pSubPool, 2, size);
+ return t;
+}
+
+BOOL ssl_ds_table_isempty(ssl_ds_table *t)
+{
+ if (t == NULL || t->aKey == NULL || t->aKey->nelts == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void *ssl_ds_table_push(ssl_ds_table *t, char *key)
+{
+ char *k;
+ void *d;
+
+ k = (char *)ap_push_array(t->aKey);
+ d = (void *)ap_push_array(t->aData);
+ ap_cpystrn(k, key, t->aKey->elt_size);
+ return d;
+}
+
+void *ssl_ds_table_get(ssl_ds_table *t, char *key)
+{
+ char *k;
+ void *d;
+ int i;
+
+ d = NULL;
+ for (i = 0; i < t->aKey->nelts; i++) {
+ k = (t->aKey->elts+(t->aKey->elt_size*i));
+ if (strEQ(k, key)) {
+ d = (void *)(t->aData->elts+(t->aData->elt_size*i));
+ break;
+ }
+ }
+ return d;
+}
+
+void ssl_ds_table_wipeout(ssl_ds_table *t)
+{
+ if (t->aKey->nelts > 0) {
+ memset(t->aKey->elts, 0, t->aKey->elt_size*t->aKey->nelts);
+ memset(t->aData->elts, 0, t->aData->elt_size*t->aData->nelts);
+ }
+ return;
+}
+
+void ssl_ds_table_kill(ssl_ds_table *t)
+{
+ ap_destroy_pool(t->pSubPool);
+ t->pSubPool = NULL;
+ t->aKey = NULL;
+ t->aData = NULL;
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
new file mode 100644
index 00000000000..dab6fd269f6
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
@@ -0,0 +1,346 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_ext.c
+** Extensions to other Apache parts
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Only those who attempt the absurd
+ can achieve the impossible.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** SSL Extensions
+** _________________________________________________________________
+*/
+
+static void ssl_ext_mlc_register(void);
+static void ssl_ext_mlc_unregister(void);
+static void ssl_ext_mr_register(void);
+static void ssl_ext_mr_unregister(void);
+static void ssl_ext_mp_register(void);
+static void ssl_ext_mp_unregister(void);
+
+void ssl_ext_register(void)
+{
+ ssl_ext_mlc_register();
+ ssl_ext_mr_register();
+ ssl_ext_mp_register();
+ return;
+}
+
+void ssl_ext_unregister(void)
+{
+ ssl_ext_mlc_unregister();
+ ssl_ext_mr_unregister();
+ ssl_ext_mp_unregister();
+ return;
+}
+
+/* _________________________________________________________________
+**
+** SSL Extension to mod_log_config
+** _________________________________________________________________
+*/
+
+static char *ssl_ext_mlc_log_c(request_rec *r, char *a);
+static char *ssl_ext_mlc_log_x(request_rec *r, char *a);
+
+/*
+ * register us for the mod_log_config function registering phase
+ * to establish %{...}c and to be able to expand %{...}x variables.
+ */
+static void ssl_ext_mlc_register(void)
+{
+ ap_hook_register("ap::mod_log_config::log_c",
+ ssl_ext_mlc_log_c, AP_HOOK_NOCTX);
+ ap_hook_register("ap::mod_log_config::log_x",
+ ssl_ext_mlc_log_x, AP_HOOK_NOCTX);
+ return;
+}
+
+static void ssl_ext_mlc_unregister(void)
+{
+ ap_hook_unregister("ap::mod_log_config::log_c",
+ ssl_ext_mlc_log_c);
+ ap_hook_unregister("ap::mod_log_config::log_x",
+ ssl_ext_mlc_log_x);
+ return;
+}
+
+/*
+ * implement the %{..}c log function
+ * (we are the only function)
+ */
+static char *ssl_ext_mlc_log_c(request_rec *r, char *a)
+{
+ char *result;
+
+ if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL)
+ return NULL;
+ result = NULL;
+ if (strcmp(a, "version") == 0)
+ result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_PROTOCOL");
+ else if (strcmp(a, "cipher") == 0)
+ result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");
+ else if (strcmp(a, "subjectdn") == 0 || strcmp(a, "clientcert") == 0)
+ result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_S_DN");
+ else if (strcmp(a, "issuerdn") == 0 || strcmp(a, "cacert") == 0)
+ result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_I_DN");
+ else if (strcmp(a, "errcode") == 0)
+ result = "-";
+ else if (strcmp(a, "errstr") == 0)
+ result = ap_ctx_get(r->connection->client->ctx, "ssl::verify::error");
+ if (result != NULL && result[0] == NUL)
+ result = NULL;
+ return result;
+}
+
+/*
+ * extend the implementation of the %{..}x log function
+ * (there can be more functions)
+ */
+static char *ssl_ext_mlc_log_x(request_rec *r, char *a)
+{
+ char *result;
+
+ result = NULL;
+ if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL)
+ result = ssl_var_lookup(r->pool, r->server, r->connection, r, a);
+ if (result != NULL && result[0] == NUL)
+ result = NULL;
+ return result;
+}
+
+/* _________________________________________________________________
+**
+** SSL Extension to mod_rewrite
+** _________________________________________________________________
+*/
+
+static char *ssl_ext_mr_lookup_variable(request_rec *r, char *var);
+
+/*
+ * register us for the mod_rewrite lookup_variable() function
+ */
+static void ssl_ext_mr_register(void)
+{
+ ap_hook_register("ap::mod_rewrite::lookup_variable",
+ ssl_ext_mr_lookup_variable, AP_HOOK_NOCTX);
+ return;
+}
+
+static void ssl_ext_mr_unregister(void)
+{
+ ap_hook_unregister("ap::mod_rewrite::lookup_variable",
+ ssl_ext_mr_lookup_variable);
+ return;
+}
+
+static char *ssl_ext_mr_lookup_variable(request_rec *r, char *var)
+{
+ char *val;
+
+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
+ if (val[0] == NUL)
+ val = NULL;
+ return val;
+}
+
+/* _________________________________________________________________
+**
+** SSL Extension to mod_proxy
+** _________________________________________________________________
+*/
+
+static int ssl_ext_mp_canon(request_rec *r, char *url);
+static int ssl_ext_mp_handler(request_rec *r, void *cr, char *url, char *proxyhost, int proxyport, char *protocol);
+static int ssl_ext_mp_set_destport(request_rec *r);
+static char *ssl_ext_mp_new_connection(request_rec *r, BUFF *fb);
+static void ssl_ext_mp_close_connection(void *_fb);
+static int ssl_ext_mp_write_host_header(request_rec *r, BUFF *fb, char *host, int port, char *portstr);
+
+/*
+ * register us ...
+ */
+static void ssl_ext_mp_register(void)
+{
+ ap_hook_register("ap::mod_proxy::canon",
+ ssl_ext_mp_canon, AP_HOOK_NOCTX);
+ ap_hook_register("ap::mod_proxy::handler",
+ ssl_ext_mp_handler, AP_HOOK_NOCTX);
+ ap_hook_register("ap::mod_proxy::http::handler::set_destport",
+ ssl_ext_mp_set_destport, AP_HOOK_NOCTX);
+ ap_hook_register("ap::mod_proxy::http::handler::new_connection",
+ ssl_ext_mp_new_connection, AP_HOOK_NOCTX);
+ ap_hook_register("ap::mod_proxy::http::handler::write_host_header",
+ ssl_ext_mp_write_host_header, AP_HOOK_NOCTX);
+ return;
+}
+
+static void ssl_ext_mp_unregister(void)
+{
+ ap_hook_unregister("ap::mod_proxy::canon", ssl_ext_mp_canon);
+ ap_hook_unregister("ap::mod_proxy::handler", ssl_ext_mp_handler);
+ ap_hook_unregister("ap::mod_proxy::http::handler::set_destport",
+ ssl_ext_mp_set_destport);
+ ap_hook_unregister("ap::mod_proxy::http::handler::new_connection",
+ ssl_ext_mp_new_connection);
+ ap_hook_unregister("ap::mod_proxy::http::handler::write_host_header",
+ ssl_ext_mp_write_host_header);
+ return;
+}
+
+static int ssl_ext_mp_canon(request_rec *r, char *url)
+{
+ int rc;
+
+ if (strncasecmp(url, "https:", 6) == 0) {
+ rc = OK;
+ ap_hook_call("ap::mod_proxy::http::canon",
+ &rc, r, url+6, "https", DEFAULT_HTTPS_PORT);
+ return rc;
+ }
+ return DECLINED;
+}
+
+static int ssl_ext_mp_handler(
+ request_rec *r, void *cr, char *url, char *proxyhost, int proxyport, char *protocol)
+{
+ int rc;
+
+ if (strcasecmp(protocol, "https") == 0) {
+ ap_ctx_set(r->ctx, "ssl_enabled", (void *)1);
+ ap_hook_call("ap::mod_proxy::http::handler",
+ &rc, r, cr, url, proxyhost, proxyport);
+ return rc;
+ }
+ return DECLINED;
+}
+
+static int ssl_ext_mp_set_destport(request_rec *r)
+{
+ if (ap_ctx_get(r->ctx, "ssl_enabled") == (void *)1)
+ return DEFAULT_HTTPS_PORT;
+ else
+ return DEFAULT_HTTP_PORT;
+}
+
+static char *ssl_ext_mp_new_connection(request_rec *r, BUFF *fb)
+{
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+ char *errmsg;
+ int rc;
+
+ if (ap_ctx_get(r->ctx, "ssl_enabled") != (void *)1)
+ return NULL;
+
+ /*
+ * Create a SSL context and handle
+ */
+ ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+ ssl = SSL_new(ssl_ctx);
+ SSL_clear(ssl);
+ SSL_set_fd(ssl, fb->fd);
+ ap_ctx_set(fb->ctx, "ssl", ssl);
+ ap_register_cleanup(r->pool, (void *)fb,
+ ssl_ext_mp_close_connection, ssl_ext_mp_close_connection);
+
+ /*
+ * Establish the SSL connection
+ */
+ if ((rc = SSL_connect(ssl)) <= 0) {
+ errmsg = ap_pstrcat(r->pool, "SSL connect failed: ",
+ ERR_reason_error_string(ERR_get_error()), NULL);
+ SSL_free(ssl);
+ return errmsg;
+ }
+
+ return NULL;
+}
+
+static void ssl_ext_mp_close_connection(void *_fb)
+{
+ BUFF *fb = _fb;
+ SSL *ssl;
+
+ ssl = ap_ctx_get(fb->ctx, "ssl");
+ if (ssl != NULL) {
+ SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ }
+ return;
+}
+
+static int ssl_ext_mp_write_host_header(
+ request_rec *r, BUFF *fb, char *host, int port, char *portstr)
+{
+ if (ap_ctx_get(r->ctx, "ssl_enabled") != (void *)1)
+ return DECLINED;
+
+ if (portstr != NULL && port != DEFAULT_HTTPS_PORT) {
+ ap_bvputs(fb, "Host: ", host, ":", portstr, "\r\n", NULL);
+ return OK;
+ }
+ return DECLINED;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c
new file mode 100644
index 00000000000..7df32b19af9
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c
@@ -0,0 +1,550 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_init.c
+** Initialization of Servers
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/* ====================================================================
+ * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * 4. The name "Apache-SSL Server" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN LAURIE OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Recursive, adj.;
+ see Recursive.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Module Initialization
+** _________________________________________________________________
+*/
+
+/*
+ * Per-module initialization
+ */
+void ssl_init_Module(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+ SSLSrvConfigRec *sc;
+ server_rec *s2;
+ char *cp;
+ int n;
+
+ mc->nInitCount++;
+
+ /*
+ * Any init round fixes the global config
+ */
+ ssl_config_global_create(); /* just to avoid problems */
+ ssl_config_global_fix();
+
+ /*
+ * try to fix the configuration and open the dedicated SSL
+ * logfile as early as possible
+ */
+ for (s2 = s; s2 != NULL; s2 = s2->next) {
+ sc = mySrvConfig(s2);
+
+ /* Fix up stuff that may not have been set */
+ if (sc->bEnabled == UNSET)
+ sc->bEnabled = FALSE;
+ if (sc->nVerifyClient == SSL_CVERIFY_UNSET)
+ sc->nVerifyClient = SSL_CVERIFY_NONE;
+ if (sc->nVerifyDepth == UNSET)
+ sc->nVerifyDepth = 1;
+ if (sc->nSessionCacheTimeout == UNSET)
+ sc->nSessionCacheTimeout = SSL_SESSION_CACHE_TIMEOUT;
+ if (sc->nPassPhraseDialogType == SSL_PPTYPE_UNSET)
+ sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN;
+
+ /* Open the dedicated SSL logfile */
+ ssl_log_open(s2, p);
+ }
+
+ if (mc->nInitCount == 1)
+ ssl_log(s, SSL_LOG_INFO, "Init: 1st startup round (still not detached)");
+ else if (mc->nInitCount == 2)
+ ssl_log(s, SSL_LOG_INFO, "Init: 2nd startup round (already detached)");
+ else
+ ssl_log(s, SSL_LOG_INFO, "Init: %d%s restart round (already detached)",
+ mc->nInitCount-2, (mc->nInitCount-2) == 1 ? "st" : "nd");
+
+ /*
+ * The initialization phase inside the Apache API is totally bogus.
+ * We actually have three non-trivial problems:
+ *
+ * 1. Under Unix the API does a 2-round initialization of modules while
+ * under Win32 it doesn't. This means we have to make sure that at
+ * least the pass phrase dialog doesn't occur twice. We overcome this
+ * problem by using a counter (mc->nInitCount) which has to
+ * survive the init rounds.
+ *
+ * 2. Between the first and the second round Apache detaches from
+ * the terminal under Unix. This means that our pass phrase dialog
+ * _has_ to be done in the first round and _cannot_ be done in the
+ * second round.
+ *
+ * 3. When Dynamic Shared Object (DSO) mechanism is used under Unix the
+ * module segment (code & data) gets unloaded and re-loaded between
+ * the first and the second round. This means no global data survives
+ * between first and the second init round. We overcome this by using
+ * an entry ("ssl_module") inside the ap_global_ctx.
+ *
+ * The situation as a table:
+ *
+ * Unix/static Unix/DSO Win32 Action Required
+ * (-DSHARED_MODULE) (-DWIN32)
+ * ----------- ----------------- --------- -----------------------------------
+ * - load module - -
+ * init init init SSL library init, Pass Phrase Dialog
+ * detach detach - -
+ * - reload module - -
+ * init init - SSL library init, mod_ssl init
+ *
+ * Ok, now try to solve this totally ugly situation...
+ */
+
+#ifdef SHARED_MODULE
+ ssl_init_SSLLibrary(s);
+#else
+ if (mc->nInitCount <= 2)
+ ssl_init_SSLLibrary(s);
+#endif
+ if (mc->nInitCount == 1) {
+ ssl_pphrase_Handle(s, p);
+#ifndef WIN32
+ return;
+#endif
+ }
+
+ /*
+ * Warn the user that he should use the session cache.
+ * But we can operate without it, of course.
+ */
+ if (mc->nSessionCacheMode == SSL_SCMODE_UNSET) {
+ ssl_log(s, SSL_LOG_WARN,
+ "Init: Session Cache is not configured [hint: SSLSessionCache]");
+ mc->nSessionCacheMode = SSL_SCMODE_NONE;
+ }
+
+ /*
+ * initialize the mutex handling and session caching
+ */
+ ssl_mutex_init(s, p);
+ ssl_scache_init(s, p);
+
+ /*
+ * Seed the Pseudo Random Number Generator (PRNG)
+ */
+ n = ssl_rand_seed(s, p, SSL_RSCTX_STARTUP);
+ ssl_log(s, SSL_LOG_INFO, "Init: Seeding PRNG with %d bytes of entropy", n);
+
+ /*
+ * pre-generate the temporary RSA key
+ */
+ if (mc->pRSATmpKey == NULL) {
+ ssl_log(s, SSL_LOG_INFO, "Init: Generating temporary (512 bit) RSA private key");
+ mc->pRSATmpKey = RSA_generate_key(512, RSA_F4, NULL, NULL);
+ if (mc->pRSATmpKey == NULL) {
+ ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary (512 bit) RSA private key");
+ ssl_die();
+ }
+ }
+
+ /*
+ * initialize servers
+ */
+ ssl_log(s, SSL_LOG_INFO, "Init: Initializing (virtual) servers for SSL");
+ for (; s != NULL; s = s->next) {
+ sc = mySrvConfig(s);
+
+ /*
+ * Give out warnings when HTTPS is configured for
+ * the HTTP port or vice versa
+ */
+ if (sc->bEnabled && s->port == DEFAULT_HTTP_PORT)
+ ssl_log(s, SSL_LOG_WARN,
+ "Init: You configured HTTPS(%d) on the standard HTTP(%d) port!",
+ DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
+ if (!sc->bEnabled && s->port == DEFAULT_HTTPS_PORT)
+ ssl_log(s, SSL_LOG_WARN,
+ "Init: You configured HTTP(%d) on the standard HTTPS(%d) port!",
+ DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
+
+ /*
+ * Either now skip this server when SSL is disabled for
+ * it or give out some information about what we're
+ * configuring.
+ */
+ if (!sc->bEnabled)
+ continue;
+ ssl_log(s, SSL_LOG_INFO,
+ "Init: Configuring server %s for SSL protocol",
+ ssl_util_vhostid(p, s));
+
+ /*
+ * Read the server certificate and key
+ */
+ ssl_init_GetCertAndKey(s, p, sc);
+ }
+
+ /*
+ * Announce mod_ssl and SSL library in HTTP Server field
+ * as ``mod_ssl/X.X.X OpenSSL/X.X.X''
+ */
+ if ((cp = ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_PRODUCT")) != NULL && cp[0] != NUL)
+ ap_add_version_component(cp);
+ ap_add_version_component(ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_INTERFACE"));
+ ap_add_version_component(ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_LIBRARY"));
+
+ return;
+}
+
+/*
+ * Initialize SSL library (also already needed for the pass phrase dialog)
+ */
+void ssl_init_SSLLibrary(server_rec *s)
+{
+ ssl_log(s, SSL_LOG_INFO, "Init: Initializing %s library", SSL_LIBRARY_NAME);
+#ifdef WIN32
+ CRYPTO_malloc_init();
+#endif
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+ ssl_util_thread_setup();
+ return;
+}
+
+/*
+ * Read the SSL Server Certificate and Key
+ */
+void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc)
+{
+ SSLModConfigRec *mc = myModConfig();
+ int nVerify;
+ char *cpVHostID;
+ SSL_CTX *ctx;
+ STACK *skCAList;
+ ssl_asn1_t *asn1;
+ char *cp;
+
+ /*
+ * Create the server host:port string because we need it a lot
+ */
+ cpVHostID = ssl_util_vhostid(p, s);
+
+ /*
+ * Now check for important parameters and the
+ * possibility that the user forgot to set them.
+ */
+ if (sc->szCertificateFile == NULL) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) No SSL Certificate set [hint: SSLCertificateFile]",
+ cpVHostID);
+ ssl_die();
+ }
+
+ /*
+ * Check for problematic re-initializations
+ */
+ if (sc->px509Certificate) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) Illegal attempt to re-initialise SSL for server "
+ "(theoretically shouldn't happen!)", cpVHostID);
+ ssl_die();
+ }
+
+ /*
+ * Create the new per-server SSL context
+ */
+ if (sc->nProtocol == SSL_PROTOCOL_NONE) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) No SSL protocols available [hint: SSLProtocol]",
+ cpVHostID);
+ ssl_die();
+ }
+ cp = ap_pstrcat(p, (sc->nProtocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
+ (sc->nProtocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
+ (sc->nProtocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), NULL);
+ cp[strlen(cp)-2] = NUL;
+ ssl_log(s, SSL_LOG_TRACE,
+ "Init: (%s) Creating new SSL context (protocols: %s)", cpVHostID, cp);
+ if (sc->nProtocol == SSL_PROTOCOL_SSLV2)
+ ctx = SSL_CTX_new(SSLv2_server_method()); /* only SSLv2 is left */
+ else
+ ctx = SSL_CTX_new(SSLv23_server_method()); /* be more flexible */
+ if (!(sc->nProtocol & SSL_PROTOCOL_SSLV2))
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+ if (!(sc->nProtocol & SSL_PROTOCOL_SSLV3))
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
+ if (!(sc->nProtocol & SSL_PROTOCOL_TLSV1))
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
+ SSL_CTX_set_app_data(ctx, s);
+ sc->pSSLCtx = ctx;
+
+ /*
+ * Configure callbacks for SSL context
+ */
+ nVerify = SSL_VERIFY_NONE;
+ if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE)
+ nVerify |= SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ if ( (sc->nVerifyClient == SSL_CVERIFY_OPTIONAL)
+ || (sc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) )
+ nVerify |= SSL_VERIFY_PEER;
+ SSL_CTX_set_verify(ctx, nVerify, ssl_callback_SSLVerify);
+ SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
+ SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
+ SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
+ SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
+ SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState);
+
+ /*
+ * Configure SSL Cipher Suite
+ */
+ ssl_log(s, SSL_LOG_TRACE,
+ "Init: (%s) Configuring permitted SSL ciphers", cpVHostID);
+ if (sc->szCipherSuite != NULL) {
+ if (!SSL_CTX_set_cipher_list(sc->pSSLCtx, sc->szCipherSuite)) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Init: (%s) Unable to configure permitted SSL ciphers",
+ cpVHostID);
+ ssl_die();
+ }
+ }
+
+ /*
+ * Configure Client Authentication details
+ */
+ if (sc->szCACertificateFile != NULL || sc->szCACertificatePath != NULL) {
+ ssl_log(s, SSL_LOG_TRACE,
+ "Init: (%s) Configuring client authentication", cpVHostID);
+ if (!SSL_CTX_load_verify_locations(sc->pSSLCtx,
+ sc->szCACertificateFile,
+ sc->szCACertificatePath)) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Init: (%s) Unable to configure verify locations "
+ "for client authentication", cpVHostID);
+ ssl_die();
+ }
+ if ((skCAList = ssl_init_FindCAList(s, p, sc->szCACertificateFile,
+ sc->szCACertificatePath)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) Unable to determine list of available "
+ "CA certificates for client authentication", cpVHostID);
+ ssl_die();
+ }
+ SSL_CTX_set_client_CA_list(sc->pSSLCtx, skCAList);
+ }
+
+ /*
+ * Give a warning when no CAs were configured but client authentication
+ * should take place. This cannot work.
+ */
+ if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
+ skCAList = SSL_CTX_get_client_CA_list(sc->pSSLCtx);
+ if (sk_num(skCAList) == 0)
+ ssl_log(s, SSL_LOG_WARN,
+ "Init: Ops, you want to request client authentication, "
+ "but no CAs are known for verification!? "
+ "[Hint: SSLCACertificate*]");
+ }
+
+ /*
+ * Configure server certificate
+ */
+ ssl_log(s, SSL_LOG_TRACE,
+ "Init: (%s) Configuring server certificate", cpVHostID);
+ if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cpVHostID)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) Ops, can't find server certificate?!", cpVHostID);
+ ssl_die();
+ }
+ sc->px509Certificate = d2i_X509(NULL, &(asn1->cpData), asn1->nData);
+
+ /*
+ * Configure server private key
+ */
+ ssl_log(s, SSL_LOG_TRACE,
+ "Init: (%s) Configuring server private key", cpVHostID);
+ if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cpVHostID)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Init: (%s) Ops, can't find server private key?!", cpVHostID);
+ ssl_die();
+ }
+ sc->prsaKey = d2i_RSAPrivateKey(NULL, &(asn1->cpData), asn1->nData);
+
+ return;
+}
+
+static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b)
+{
+ return(X509_NAME_cmp(*a, *b));
+}
+
+STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApath)
+{
+ STACK *skCAList;
+ STACK *sk;
+ DIR *dir;
+ struct DIR_TYPE *direntry;
+ char *cp;
+ pool *p;
+ int n;
+
+ /*
+ * Use a subpool so we don't bloat up the server pool which
+ * is remains in memory for the complete operation time of
+ * the server.
+ */
+ p = ap_make_sub_pool(pp);
+
+ /*
+ * Start with a empty stack/list where new
+ * entries get added in sorted order.
+ */
+ skCAList = sk_new(ssl_init_FindCAList_X509NameCmp);
+
+ /*
+ * Process CA certificate bundle file
+ */
+ if (cpCAfile != NULL) {
+ sk = SSL_load_client_CA_file(cpCAfile);
+ for(n = 0; sk != NULL && n < sk_num(sk); n++) {
+ ssl_log(s, SSL_LOG_TRACE,
+ "CA certificate: %s",
+ X509_NAME_oneline((X509_NAME *)sk_value(sk, n), NULL, 0));
+ if (sk_find(skCAList, sk_value(sk, n)) < 0)
+ sk_push(skCAList, sk_value(sk, n));
+ }
+ }
+
+ /*
+ * Process CA certificate path files
+ */
+ if (cpCApath != NULL) {
+ dir = ap_popendir(p, cpCApath);
+ while ((direntry = readdir(dir)) != NULL) {
+ cp = ap_pstrcat(p, cpCApath, "/", direntry->d_name, NULL);
+ sk = SSL_load_client_CA_file(cp);
+ for(n = 0; sk != NULL && n < sk_num(sk); n++) {
+ ssl_log(s, SSL_LOG_TRACE,
+ "CA certificate: %s",
+ X509_NAME_oneline((X509_NAME *)sk_value(sk, n), NULL, 0));
+ if (sk_find(skCAList, sk_value(sk, n)) < 0)
+ sk_push(skCAList, sk_value(sk, n));
+ }
+ }
+ ap_pclosedir(p, dir);
+ }
+
+ /*
+ * Cleanup
+ */
+ sk_set_cmp_func(skCAList, NULL);
+ ap_destroy_pool(p);
+
+ return skCAList;
+}
+
+void ssl_init_Child(server_rec *s, pool *p)
+{
+ /* open the mutex lockfile */
+ ssl_mutex_open(s, p);
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c
new file mode 100644
index 00000000000..851c937ab21
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c
@@ -0,0 +1,486 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_io.c
+** I/O Functions
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``MY HACK: This universe.
+ Just one little problem:
+ core keeps dumping.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** I/O Hooks
+** _________________________________________________________________
+*/
+
+#ifndef NO_WRITEV
+#include <sys/types.h>
+#include <sys/uio.h>
+#endif
+
+static int ssl_io_hook_read(BUFF *fb, char *buf, int len);
+static int ssl_io_hook_write(BUFF *fb, char *buf, int len);
+#ifndef NO_WRITEV
+static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt);
+#endif
+#ifdef WIN32
+static int ssl_io_hook_recvwithtimeout(BUFF *fb, char *buf, int len);
+static int ssl_io_hook_sendwithtimeout(BUFF *fb, const char *buf, int len);
+#endif /* WIN32 */
+
+void ssl_io_register(void)
+{
+ ap_hook_register("ap::buff::read", ssl_io_hook_read, AP_HOOK_NOCTX);
+ ap_hook_register("ap::buff::write", ssl_io_hook_write, AP_HOOK_NOCTX);
+#ifndef NO_WRITEV
+ ap_hook_register("ap::buff::writev", ssl_io_hook_writev, AP_HOOK_NOCTX);
+#endif
+#ifdef WIN32
+ ap_hook_register("ap::buff::recvwithtimeout",
+ ssl_io_hook_recvwithtimeout, AP_HOOK_NOCTX);
+ ap_hook_register("ap::buff::sendwithtimeout",
+ ssl_io_hook_sendwithtimeout, AP_HOOK_NOCTX);
+#endif
+ return;
+}
+
+void ssl_io_unregister(void)
+{
+ ap_hook_unregister("ap::buff::read", ssl_io_hook_read);
+ ap_hook_unregister("ap::buff::write", ssl_io_hook_write);
+#ifndef NO_WRITEV
+ ap_hook_unregister("ap::buff::writev", ssl_io_hook_writev);
+#endif
+#ifdef WIN32
+ ap_hook_unregister("ap::buff::recvwithtimeout", ssl_io_hook_recvwithtimeout);
+ ap_hook_unregister("ap::buff::sendwithtimeout", ssl_io_hook_sendwithtimeout);
+#endif
+ return;
+}
+
+static int ssl_io_hook_read(BUFF *fb, char *buf, int len)
+{
+ SSL *ssl;
+ conn_rec *c;
+ int rc;
+
+ if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
+ rc = SSL_read(ssl, buf, len);
+ /*
+ * Simulate an EINTR in case SSLeay wants to read more.
+ * (This is usually the case when the client forces an SSL
+ * renegotation which is handled implicitly by SSLeay.)
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)
+ errno = EINTR;
+ /*
+ * Log SSL errors
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
+ c = (conn_rec *)SSL_get_app_data(ssl);
+ ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "SSL error on reading data");
+ }
+ /*
+ * read(2) returns only the generic error number -1
+ */
+ if (rc < 0)
+ rc = -1;
+ }
+ else
+ rc = read(fb->fd_in, buf, len);
+ return rc;
+}
+
+static int ssl_io_hook_write(BUFF *fb, char *buf, int len)
+{
+ SSL *ssl;
+ conn_rec *c;
+ int rc;
+
+ if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
+ rc = SSL_write(ssl, buf, len);
+ /*
+ * Simulate an EINTR in case SSLeay wants to write more.
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE)
+ errno = EINTR;
+ /*
+ * Log SSL errors
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
+ c = (conn_rec *)SSL_get_app_data(ssl);
+ ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "SSL error on writing data");
+ }
+ /*
+ * write(2) returns only the generic error number -1
+ */
+ if (rc < 0)
+ rc = -1;
+ }
+ else
+ rc = write(fb->fd, buf, len);
+ return rc;
+}
+
+#ifndef NO_WRITEV
+/* the prototype for our own SSL_writev() */
+static int SSL_writev(SSL *, const struct iovec *, int);
+
+static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt)
+{
+ SSL *ssl;
+ conn_rec *c;
+ int rc;
+
+ if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) {
+ rc = SSL_writev(ssl, iov, iovcnt);
+ /*
+ * Simulate an EINTR in case SSLeay wants to write more.
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE)
+ errno = EINTR;
+ /*
+ * Log SSL errors
+ */
+ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) {
+ c = (conn_rec *)SSL_get_app_data(ssl);
+ ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "SSL error on writing data");
+ }
+ /*
+ * writev(2) returns only the generic error number -1
+ */
+ if (rc < 0)
+ rc = -1;
+ }
+ else
+ rc = writev(fb->fd, iov, iovcnt);
+ return rc;
+}
+#endif
+
+#ifdef WIN32
+
+/* these two functions are exported from buff.c under WIN32 */
+API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags);
+API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags);
+
+/* and the prototypes for our SSL_xxx variants */
+static int SSL_sendwithtimeout(BUFF *fb, const char *buf, int len);
+static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len);
+
+static int ssl_io_hook_recvwithtimeout(BUFF *fb, char *buf, int len)
+{
+ SSL *ssl;
+ int rc;
+
+ if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL)
+ rc = SSL_recvwithtimeout(fb, buf, len);
+ else
+ rc = recvwithtimeout(fb->fd, buf, len, 0);
+ return rc;
+}
+
+static int ssl_io_hook_sendwithtimeout(BUFF *fb, const char *buf, int len)
+{
+ SSL *ssl;
+ int rc;
+
+ if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL)
+ rc = SSL_sendwithtimeout(fb, buf, len);
+ else
+ rc = sendwithtimeout(fb->fd, buf, len, 0);
+ return rc;
+}
+
+#endif /* WIN32 */
+
+/* _________________________________________________________________
+**
+** Special Functions for SSLeay
+** _________________________________________________________________
+*/
+
+#ifdef WIN32
+
+static int SSL_sendwithtimeout(BUFF *fb, const char *buf, int len)
+{
+ int iostate = 1;
+ fd_set fdset;
+ struct timeval tv;
+ int err = WSAEWOULDBLOCK;
+ int rv;
+ int retry;
+ int sock = fb->fd;
+ SSL *ssl;
+
+ ssl = ap_ctx_get(fb->ctx, "ssl");
+
+ if (!(tv.tv_sec = ap_check_alarm()))
+ return (SSL_write(ssl, (char*)buf, len));
+
+ rv = ioctlsocket(sock, FIONBIO, &iostate);
+ iostate = 0;
+ if (rv) {
+ err = WSAGetLastError();
+ ap_assert(0);
+ }
+ rv = SSL_write(ssl, (char*)buf, len);
+ if (rv <= 0) {
+ if (BIO_sock_should_retry(rv)) {
+ do {
+ retry=0;
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ rv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
+ if (rv == SOCKET_ERROR)
+ err = WSAGetLastError();
+ else if (rv == 0) {
+ ioctlsocket(sock, FIONBIO, &iostate);
+ if(ap_check_alarm() < 0) {
+ WSASetLastError(EINTR); /* Simulate an alarm() */
+ return (SOCKET_ERROR);
+ }
+ }
+ else {
+ rv = SSL_write(ssl, (char*)buf, len);
+ if (BIO_sock_should_retry(rv)) {
+ ap_log_error(APLOG_MARK,APLOG_DEBUG, NULL,
+ "select claimed we could write, "
+ "but in fact we couldn't. "
+ "This is a bug in Windows.");
+ retry=1;
+ Sleep(100);
+ }
+ }
+ } while(retry);
+ }
+ }
+ ioctlsocket(sock, FIONBIO, &iostate);
+ if (rv == SOCKET_ERROR)
+ WSASetLastError(err);
+ return (rv);
+}
+
+static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len)
+{
+ int iostate = 1;
+ fd_set fdset;
+ struct timeval tv;
+ int err = WSAEWOULDBLOCK;
+ int rv;
+ int sock = fb->fd_in;
+ SSL *ssl;
+
+ ssl = ap_ctx_get(fb->ctx, "ssl");
+
+ if (!(tv.tv_sec = ap_check_alarm()))
+ return (SSL_read(ssl, buf, len));
+
+ rv = ioctlsocket(sock, FIONBIO, &iostate);
+ iostate = 0;
+ ap_assert(!rv);
+ rv = SSL_read(ssl, buf, len);
+ if (rv <= 0) {
+ if (BIO_sock_should_retry(rv)) {
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ rv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
+ if (rv == SOCKET_ERROR)
+ err = WSAGetLastError();
+ else if (rv == 0) {
+ ioctlsocket(sock, FIONBIO, &iostate);
+ ap_check_alarm();
+ WSASetLastError(WSAEWOULDBLOCK);
+ return (SOCKET_ERROR);
+ }
+ else {
+ rv = SSL_read(ssl, buf, len);
+ if (rv == SOCKET_ERROR)
+ err = WSAGetLastError();
+ }
+ }
+ }
+ ioctlsocket(sock, FIONBIO, &iostate);
+ if (rv == SOCKET_ERROR)
+ WSASetLastError(err);
+ return (rv);
+}
+
+#endif /*WIN32*/
+
+/*
+ * There is no SSL_writev() provided by SSLeay. The reason is mainly because
+ * SSLeay has to fragment the data itself again for the SSL record layer, so a
+ * writev() like interface makes not much sense. What we do is to emulate it
+ * to at least being able to use the write() like interface. But keep in mind
+ * that the network I/O performance is not write() like, of course.
+ */
+#ifndef NO_WRITEV
+static int SSL_writev(SSL *ssl, const struct iovec *iov, int iovcnt)
+{
+ int i;
+ int n;
+ int rc;
+
+ rc = 0;
+ for (i = 0; i < iovcnt; i++) {
+ if ((n = SSL_write(ssl, iov[i].iov_base, iov[i].iov_len)) == -1) {
+ rc = -1;
+ break;
+ }
+ rc += n;
+ }
+ return rc;
+}
+#endif
+
+/* _________________________________________________________________
+**
+** I/O Data Debugging
+** _________________________________________________________________
+*/
+
+#define DUMP_WIDTH 16
+
+static void ssl_io_data_dump(server_rec *srvr, char *s, long len)
+{
+ char buf[256];
+ char tmp[64];
+ int i, j, rows, trunc;
+ unsigned char ch;
+
+ trunc = 0;
+ for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
+ trunc++;
+ rows = (len / DUMP_WIDTH);
+ if ((rows * DUMP_WIDTH) < len)
+ rows++;
+ ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
+ "+-------------------------------------------------------------------------+");
+ for(i = 0 ; i< rows; i++) {
+ ap_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH);
+ ap_cpystrn(buf, tmp, sizeof(buf));
+ for (j = 0; j < DUMP_WIDTH; j++) {
+ if (((i * DUMP_WIDTH) + j) >= len)
+ ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
+ else {
+ ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
+ ap_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' ');
+ ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
+ }
+ }
+ ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
+ for (j = 0; j < DUMP_WIDTH; j++) {
+ if (((i * DUMP_WIDTH) + j) >= len)
+ ap_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
+ else {
+ ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
+ ap_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.');
+ ap_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
+ }
+ }
+ ap_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf));
+ ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID, "%s", buf);
+ }
+ if (trunc > 0)
+ ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
+ "| %04x - <SPACES/NULS>", len + trunc);
+ ssl_log(srvr, SSL_LOG_DEBUG|SSL_NO_TIMESTAMP|SSL_NO_LEVELID,
+ "+-------------------------------------------------------------------------+");
+ return;
+}
+
+long ssl_io_data_cb(BIO *bio, int cmd, char *argp, int argi, long argl, long len)
+{
+ SSL *ssl;
+ conn_rec *c;
+ server_rec *s;
+
+ if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
+ return len;
+ if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
+ return len;
+ s = c->server;
+
+ if (len >= 0) {
+ ssl_log(s, SSL_LOG_DEBUG,
+ "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s",
+ SSL_LIBRARY_NAME, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
+ len, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
+ bio, argp, (argp != NULL ? "(BIO dump follows)" : "(Ops, no memory buffer?)"));
+ if (argp != NULL)
+ ssl_io_data_dump(s, argp, len);
+ }
+ else {
+ ssl_log(s, SSL_LOG_DEBUG,
+ "%s: I/O error, %d bytes expected to %s on BIO#%08X [mem: %08lX]",
+ SSL_LIBRARY_NAME, argi,
+ (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
+ bio, argp);
+ }
+ return len;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c
new file mode 100644
index 00000000000..99b19843c07
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c
@@ -0,0 +1,1268 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_kernel.c
+** The SSL engine kernel
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/* ====================================================================
+ * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * 4. The name "Apache-SSL Server" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN LAURIE OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``It took me fifteen years to discover
+ I had no talent for programming, but
+ I couldn't give it up because by that
+ time I was too famous.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** SSL Engine Kernel
+** _________________________________________________________________
+*/
+
+/*
+ * Connect Handler:
+ * Connect SSL to the accepted socket
+ *
+ * Usually we would need an Apache API hook which is triggered right after
+ * the socket is accepted for handling a new request. But Apache 1.3 doesn't
+ * provide such a hook, so we have to patch http_main.c and call this
+ * function directly.
+ */
+void ssl_hook_NewConnection(conn_rec *conn)
+{
+ server_rec *srvr;
+ BUFF *fb;
+ SSLSrvConfigRec *sc;
+ SSL *ssl;
+ char *cp;
+ int rc;
+ int n;
+
+ /*
+ * Get context
+ */
+ srvr = conn->server;
+ fb = conn->client;
+ sc = mySrvConfig(srvr);
+
+ /*
+ * Create SSL context
+ */
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+
+ /*
+ * Immediately stop processing if SSL
+ * is disabled for this connection
+ */
+ if (sc == NULL || !sc->bEnabled)
+ return;
+
+ /*
+ * Remember the connection information for
+ * later access inside callback functions
+ */
+ ssl_log(srvr, SSL_LOG_INFO, "Connection to child %d established (server %s)",
+ conn->child_num, ssl_util_vhostid(conn->pool, srvr));
+
+ /*
+ * Seed the Pseudo Random Number Generator (PRNG)
+ */
+ n = ssl_rand_seed(srvr, conn->pool, SSL_RSCTX_CONNECT);
+ ssl_log(srvr, SSL_LOG_TRACE, "Seeding PRNG with %d bytes of entropy", n);
+
+ /*
+ * Create a new SSL connection with the configured server SSL context and
+ * attach this to the socket. Additionally we register this attachment
+ * so we can detach later.
+ */
+ ssl = SSL_new(sc->pSSLCtx);
+ SSL_set_app_data(ssl, conn); /* conn_rec (available now) */
+ SSL_set_app_data2(ssl, NULL); /* request_rec (available later) */
+ SSL_set_fd(ssl, fb->fd);
+ ap_ctx_set(fb->ctx, "ssl", ssl);
+ ap_register_cleanup(conn->pool, (void *)conn,
+ ssl_hook_CloseConnection, ssl_hook_CloseConnection);
+
+ /*
+ * Configure SSLeay BIO Data Logging
+ */
+ if (sc->nLogLevel >= SSL_LOG_DEBUG) {
+ BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
+ BIO_set_callback_arg(SSL_get_rbio(ssl), ssl);
+ }
+
+ /*
+ * Configure the server certificate and private key
+ * which should be used for this connection.
+ */
+ if (sc->szCertificateFile != NULL) {
+ if (SSL_use_certificate(ssl, sc->px509Certificate) <= 0) {
+ ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Unable to configure server certificate for connection");
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ if (SSL_use_RSAPrivateKey(ssl, sc->prsaKey) <= 0) {
+ ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Unable to configure server private key for connection");
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ }
+
+ /*
+ * Predefine some client verification results
+ */
+ ap_ctx_set(fb->ctx, "ssl::client::dn", NULL);
+ ap_ctx_set(fb->ctx, "ssl::verify::error", NULL);
+
+ /*
+ * We have to manage a I/O timeout ourself, because Apache
+ * does it the first time when reading the request, but we're
+ * working some time before this happens.
+ */
+ ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)FALSE);
+ ap_set_callback_and_alarm(ssl_hook_TimeoutConnection, srvr->timeout);
+
+ /*
+ * Now enter the SSL Handshake Phase
+ */
+ while (!SSL_is_init_finished(ssl)) {
+
+ if ((rc = SSL_accept(ssl)) <= 0) {
+
+ if (SSL_get_error(ssl, rc) == SSL_ERROR_ZERO_RETURN) {
+ /*
+ * The case where the connection was closed before any data
+ * was transferred. That's not a real error and can occur
+ * sporadically with some clients.
+ */
+ ssl_log(srvr, SSL_LOG_INFO,
+ "SSL handshake stopped: connection was closed");
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ else if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
+ /*
+ * The case where SSLeay has recognized a HTTP request:
+ * This means the client speaks plain HTTP on our HTTPS
+ * port. Hmmmm... At least for this error we can be more friendly
+ * and try to provide him with a HTML error page. We have only one
+ * problem: SSLeay has already read some bytes from the HTTP
+ * request. So we have to skip the request line manually and
+ * instead provide a faked one in order to continue the internal
+ * Apache processing.
+ *
+ * (This feature is only available for SSLeay 0.9.0 and higher)
+ */
+ char ca[2];
+ int rv;
+
+ /* log the situation */
+ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "SSL handshake failed: HTTP spoken on HTTPS port; "
+ "trying to send HTML error page");
+
+ /* first: skip the remaining bytes of the request line */
+ do {
+ do {
+ rv = read(fb->fd, ca, 1);
+ } while (rv == -1 && errno == EINTR);
+ } while (rv > 0 && ca[0] != '\012' /*LF*/);
+
+ /* second: fake the request line */
+ fb->inbase = ap_palloc(fb->pool, fb->bufsiz);
+ ap_cpystrn((char *)fb->inbase, "GET /mod_ssl:error:HTTP-request HTTP/1.0\r\n",
+ fb->bufsiz);
+ fb->inptr = fb->inbase;
+ fb->incnt = strlen((char *)fb->inptr);
+
+ /* third: kick away the SSL stuff */
+ SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+
+ /* finally: let Apache go on with processing */
+ return;
+ }
+ else if (ap_ctx_get(ap_global_ctx, "ssl::handshake::timeout") == (void *)TRUE) {
+ ssl_log(srvr, SSL_LOG_ERROR,
+ "SSL handshake timed out (client %s, server %s)",
+ conn->remote_ip, ssl_util_vhostid(conn->pool, srvr));
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ else if (SSL_get_error(ssl, rc) == SSL_ERROR_SYSCALL) {
+ if (errno == EINTR)
+ continue;
+ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "SSL handshake interrupted by system");
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ else {
+ /*
+ * Ok, anything else is a fatal error
+ */
+ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR|SSL_ADD_ERRNO,
+ "SSL handshake failed (client %s, server %s)",
+ conn->remote_ip, ssl_util_vhostid(conn->pool, srvr));
+
+ /*
+ * try to gracefully shutdown the connection:
+ * - send an own shutdown message (be gracefully)
+ * - don't wait for peer's shutdown message (deadloop)
+ * - kick away the SSL stuff immediately
+ * - block the socket, so Apache cannot operate any more
+ */
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ }
+
+ /*
+ * Check for failed client authentication
+ */
+ if ((cp = (char *)ap_ctx_get(fb->ctx, "ssl::verify::error")) != NULL) {
+ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "SSL client authentication failed: %s", cp);
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+
+ /*
+ * Remember the peer certificate when
+ * client authentication was done
+ */
+ if (sc->nVerifyClient != SSL_CVERIFY_NONE) {
+ char *s;
+ X509 *xs;
+ if ((xs = SSL_get_peer_certificate(ssl)) != NULL) {
+ s = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0);
+ ap_ctx_set(fb->ctx, "ssl::client::dn", ap_pstrdup(conn->pool, s));
+ free(s);
+ }
+ }
+
+ /*
+ * Make really sure that when a peer certificate
+ * is required we really got one... (be paranoid)
+ */
+ if ( sc->nVerifyClient == SSL_CVERIFY_REQUIRE
+ && ap_ctx_get(fb->ctx, "ssl::client::dn") == NULL) {
+ ssl_log(srvr, SSL_LOG_ERROR,
+ "No acceptable peer certificate available");
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(fb->ctx, "ssl", NULL);
+ ap_bsetflag(fb, B_EOF|B_EOUT, 1);
+ conn->aborted = 1;
+ return;
+ }
+ }
+
+ /*
+ * Remove the timeout handling
+ */
+ ap_set_callback_and_alarm(NULL, 0);
+ ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)FALSE);
+
+ /*
+ * Improve I/O throughput by using
+ * SSLeay's read-ahead functionality
+ * (don't used under Win32, because
+ * there we use select())
+ */
+#ifndef WIN32
+ SSL_set_read_ahead(ssl, TRUE);
+#endif
+
+ return;
+}
+
+/*
+ * Signal handler function for the SSL handshake phase
+ */
+void ssl_hook_TimeoutConnection(int sig)
+{
+ /* we just set a flag for the handshake processing loop */
+ ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)TRUE);
+ return;
+}
+
+/*
+ * Close the SSL part of the socket connection
+ */
+void ssl_hook_CloseConnection(void *_conn)
+{
+ conn_rec *conn = _conn;
+ SSL *ssl;
+
+ /*
+ * Optionally shutdown the SSL session
+ */
+ ssl = ap_ctx_get(conn->client->ctx, "ssl");
+ if (ssl != NULL) {
+ SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+ while (!SSL_shutdown(ssl));
+ SSL_free(ssl);
+ ap_ctx_set(conn->client->ctx, "ssl", NULL);
+ }
+
+ /*
+ * And finally log the connection close
+ */
+ ssl_log(conn->server, SSL_LOG_INFO, "Connection to child %d closed (server %s)",
+ conn->child_num, ssl_util_vhostid(conn->pool, conn->server));
+
+ return;
+}
+
+/*
+ * Post Read Request Handler
+ */
+int ssl_hook_ReadReq(request_rec *r)
+{
+ SSL *ssl;
+
+ /*
+ * Get the SSL connection structure and perform the
+ * delayed interlinking from SSL back to request_rec
+ */
+ ssl = ap_ctx_get(r->connection->client->ctx, "ssl");
+ if (ssl != NULL)
+ SSL_set_app_data2(ssl, r);
+
+ /*
+ * Force the mod_ssl content handler when URL indicates this
+ */
+ if (strEQn(r->uri, "/mod_ssl:", 9))
+ r->handler = "mod_ssl:content-handler";
+ if (ssl != NULL) {
+ ap_ctx_set(r->ctx, "ap::http::method", "https");
+ ap_ctx_set(r->ctx, "ap::default::port", "443");
+ }
+ else {
+ ap_ctx_set(r->ctx, "ap::http::method", NULL);
+ ap_ctx_set(r->ctx, "ap::default::port", NULL);
+ }
+ return DECLINED;
+}
+
+/*
+ * Content Handler
+ */
+int ssl_hook_Handler(request_rec *r)
+{
+ int port;
+ char *thisport;
+ char *thisurl;
+
+ if (strNEn(r->uri, "/mod_ssl:", 9))
+ return DECLINED;
+
+ if (strEQ(r->uri, "/mod_ssl:error:HTTP-request")) {
+ thisport = "";
+ port = ap_get_server_port(r);
+ if (!ap_is_default_port(port, r))
+ thisport = ap_psprintf(r->pool, ":%u", port);
+ thisurl = ap_psprintf(r->pool, "https://%s%s/",
+ ap_get_server_name(r), thisport);
+
+ ap_table_setn(r->notes, "error-notes", ap_psprintf(r->pool,
+ "Reason: You're speaking plain HTTP to an SSL-enabled server port.<BR>\n"
+ "Instead use the HTTPS scheme to access this URL, please.<BR>\n"
+ "<BLOCKQUOTE>Hint: <A HREF=\"%s\"><B>%s</B></A></BLOCKQUOTE>",
+ thisurl, thisurl));
+ }
+
+ return HTTP_BAD_REQUEST;
+}
+
+/*
+ * Auth Handler:
+ * Fake a Basic authentication from the X509 client certificate.
+ *
+ * This must be run fairly early on to prevent a real authentication from
+ * occuring, in particular it must be run before anything else that
+ * authenticates a user. This means that the Module statement for this
+ * module should be LAST in the Configuration file.
+ */
+int ssl_hook_Auth(request_rec *r)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(r->server);
+ SSLDirConfigRec *dc = myDirConfig(r);
+ char b1[MAX_STRING_LEN], b2[MAX_STRING_LEN];
+ char *clientdn;
+
+ /*
+ * We decline operation in various situations..
+ */
+ if (!sc->bEnabled)
+ return DECLINED;
+ if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL)
+ return DECLINED;
+ if (!(dc->nOptions & SSL_OPT_FAKEBASICAUTH))
+ return DECLINED;
+ if (r->connection->user)
+ return DECLINED;
+ if ((clientdn = (char *)ap_ctx_get(r->connection->client->ctx, "ssl::client::dn")) == NULL)
+ return DECLINED;
+
+ /*
+ * Fake a password - which one would be immaterial, as, it seems, an empty
+ * password in the users file would match ALL incoming passwords, if only
+ * we were using the standard crypt library routine. Unfortunately, SSLeay
+ * "fixes" a "bug" in crypt and thus prevents blank passwords from
+ * working. (IMHO what they really fix is a bug in the users of the code
+ * - failing to program correctly for shadow passwords). We need,
+ * therefore, to provide a password. This password can be matched by
+ * adding the string "xxj31ZMTZzkVA" as the password in the user file.
+ * This is just the crypted variant of the word "password" ;-)
+ */
+ ap_snprintf(b1, sizeof(b1), "%s:password", clientdn);
+ ssl_util_uuencode(b2, b1, FALSE);
+ ap_snprintf(b1, sizeof(b1), "Basic %s", b2);
+ ap_table_set(r->headers_in, "Authorization", b1);
+
+ return DECLINED;
+}
+
+/*
+ * Access Handler
+ */
+int ssl_hook_Access(request_rec *r)
+{
+ SSLDirConfigRec *dc;
+ SSLSrvConfigRec *sc;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ array_header *apRequirement;
+ ssl_require_t *pRequirements;
+ ssl_require_t *pRequirement;
+ char *cp;
+ int ok;
+ int i;
+ BOOL renegotiate;
+#ifdef SSL_EXPERIMENTAL
+ BOOL reconfigured_locations;
+ STACK *skCAList;
+ char *cpCAPath;
+ char *cpCAFile;
+#endif
+ STACK *skCipherOld;
+ STACK *skCipher;
+ int nVerifyOld;
+ int nVerify;
+ int n;
+
+ dc = myDirConfig(r);
+ sc = mySrvConfig(r->server);
+ ssl = ap_ctx_get(r->connection->client->ctx, "ssl");
+ if (ssl != NULL)
+ ctx = SSL_get_SSL_CTX(ssl);
+
+ /*
+ * Support for SSLRequireSSL directive
+ */
+ if (dc->bSSLRequired && ssl == NULL) {
+ ap_log_reason("SSL connection required", r->filename, r);
+ return FORBIDDEN;
+ }
+
+ /*
+ * Check to see if SSL protocol is on
+ */
+ if (!sc->bEnabled)
+ return DECLINED;
+ if (ssl == NULL)
+ return DECLINED;
+
+ /*
+ * Support for per-directory SSL connection parameters.
+ *
+ * This is implemented by forcing an SSL renegotiation with the
+ * reconfigured parameter suite. But Apache's internal API processing
+ * makes our life very hard, because when internal sub-requests occur we
+ * nevertheless should avoid multiple unnecessary SSL handshakes (they
+ * need network I/O and time to perform). But the optimization for
+ * filtering out the unnecessary handshakes isn't such obvious.
+ * Especially because while Apache is in its sub-request processing the
+ * client could force additional handshakes, too. And these take place
+ * perhaps without our notice. So the only possibility is to ask
+ * SSLeay/OpenSSL whether the renegotiation has to be performed or not. It
+ * has to performed when some parameters which were previously known (by
+ * us) are not those we've now reconfigured (as known by SSLeay/OpenSSL).
+ */
+ renegotiate = FALSE;
+#ifdef SSL_EXPERIMENTAL
+ reconfigured_locations = FALSE;
+#endif
+
+ /*
+ * override of SSLCipherSuite
+ */
+ if (dc->szCipherSuite != NULL) {
+ /* remember old cipher suite for comparison */
+ if ((skCipherOld = SSL_get_ciphers(ssl)) != NULL)
+ skCipherOld = sk_dup(skCipherOld);
+ /* configure new cipher suite */
+ if (!SSL_set_cipher_list(ssl, dc->szCipherSuite)) {
+ ssl_log(r->server, SSL_LOG_WARN|SSL_ADD_SSLERR,
+ "Unable to reconfigure (per-directory) permitted SSL ciphers");
+ return FORBIDDEN;
+ }
+ /* determine whether the cipher suite was actually changed */
+ skCipher = SSL_get_ciphers(ssl);
+ if ((skCipherOld == NULL && skCipher != NULL) ||
+ (skCipherOld != NULL && skCipher == NULL) )
+ renegotiate = TRUE;
+ else if (skCipherOld != NULL && skCipher != NULL) {
+ for (n = 0; n < sk_num(skCipher); n++) {
+ if (sk_find(skCipherOld, sk_value(skCipher, n)) < 0) {
+ renegotiate = TRUE;
+ break;
+ }
+ }
+ for (n = 0; n < sk_num(skCipherOld); n++) {
+ if (sk_find(skCipher, sk_value(skCipherOld, n)) < 0) {
+ renegotiate = TRUE;
+ break;
+ }
+ }
+ }
+ /* free old cipher suite */
+ if (skCipherOld != NULL)
+ sk_free(skCipherOld);
+ }
+
+ /*
+ * override of SSLVerifyDepth:
+ * This is handled by us manually inside the verify callback
+ * function and not by SSLeay internally. And our function is
+ * aware of both the per-server and per-directory contexts.
+ * All we have to do is to force the renegotiation when the
+ * maximum allowed depth is changed.
+ */
+ if (dc->nVerifyDepth != UNSET) {
+ if (dc->nVerifyDepth != sc->nVerifyDepth)
+ renegotiate = TRUE;
+ }
+
+ /*
+ * override of SSLVerifyClient
+ */
+ if (dc->nVerifyClient != SSL_CVERIFY_UNSET) {
+ /* remember old verify mode */
+ nVerifyOld = SSL_get_verify_mode(ssl);
+ /* configure new verify mode */
+ nVerify = SSL_VERIFY_NONE;
+ if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE)
+ nVerify |= SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ if ( (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL)
+ || (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) )
+ nVerify |= SSL_VERIFY_PEER;
+ SSL_set_verify(ssl, nVerify, ssl_callback_SSLVerify);
+ SSL_set_verify_result(ssl, X509_V_OK);
+ /* determine whether the verify mode was actually changed */
+ if (nVerify != nVerifyOld)
+ renegotiate = TRUE;
+ }
+
+ /*
+ * override SSLCACertificateFile & SSLCACertificatePath
+ * This is tagged experimental because it has to use an ugly kludge: We
+ * have to change the locations inside the SSL_CTX* (per-server global)
+ * instead inside SSL* (per-connection local) and reconfigure it to the
+ * old values later. That's problematic at least for the threaded process
+ * model of Apache under Win32 or when an error occurs. But unless
+ * OpenSSL provides a SSL_load_verify_locations() function we've no other
+ * chance to provide this functionality...
+ */
+#ifdef SSL_EXPERIMENTAL
+ if ( ( dc->szCACertificateFile != NULL
+ && ( sc->szCACertificateFile == NULL
+ || ( sc->szCACertificateFile != NULL
+ && strNE(dc->szCACertificateFile, sc->szCACertificateFile))))
+ || ( dc->szCACertificatePath != NULL
+ && ( sc->szCACertificatePath == NULL
+ || ( sc->szCACertificatePath != NULL
+ && strNE(dc->szCACertificatePath, sc->szCACertificatePath)))) ) {
+ cpCAFile = dc->szCACertificateFile != NULL ?
+ dc->szCACertificateFile : sc->szCACertificateFile;
+ cpCAPath = dc->szCACertificatePath != NULL ?
+ dc->szCACertificatePath : sc->szCACertificatePath;
+ /*
+ FIXME: This should be...
+ if (!SSL_load_verify_locations(ssl, cpCAFile, cpCAPath)) {
+ ...but SSLeay/OpenSSL still doesn't provide this!
+ */
+ if (!SSL_CTX_load_verify_locations(ctx, cpCAFile, cpCAPath)) {
+ ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Unable to reconfigure verify locations "
+ "for client authentication");
+ return FORBIDDEN;
+ }
+ if ((skCAList = ssl_init_FindCAList(r->server, r->pool,
+ cpCAFile, cpCAPath)) == NULL) {
+ ssl_log(r->server, SSL_LOG_ERROR,
+ "Unable to determine list of available "
+ "CA certificates for client authentication");
+ return FORBIDDEN;
+ }
+ SSL_set_client_CA_list(ssl, skCAList);
+ renegotiate = TRUE;
+ reconfigured_locations = TRUE;
+ }
+#endif /* SSL_EXPERIMENTAL */
+
+ /*
+ * now do the renegotiation if anything was actually reconfigured
+ */
+ if (renegotiate) {
+ /*
+ * Now we force the SSL renegotation by sending the Hello Request
+ * message to the client. Here we have to do a workaround: Actually
+ * SSLeay returns immediately after sending the Hello Request (the
+ * intent AFAIK is because the SSL/TLS protocol says it's not a must
+ * that the client replies to a Hello Request). But because we insist
+ * on a reply (anything else is an error for us) we have to go to the
+ * ACCEPT state manually. Using SSL_set_accept_state() doesn't work
+ * here because it resets too much of the connection. So we set the
+ * state explicitly and continue the handshake manually.
+ */
+ ssl_log(r->server, SSL_LOG_INFO, "Requesting connection re-negotiation");
+ SSL_renegotiate(ssl);
+ SSL_do_handshake(ssl);
+ if (SSL_get_state(ssl) != SSL_ST_OK) {
+ ssl_log(r->server, SSL_LOG_ERROR, "Re-negotation request failed");
+ return FORBIDDEN;
+ }
+ ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake");
+ SSL_set_state(ssl, SSL_ST_ACCEPT);
+ SSL_do_handshake(ssl);
+ if (SSL_get_state(ssl) != SSL_ST_OK) {
+ ssl_log(r->server, SSL_LOG_ERROR,
+ "Re-negotiation handshake failed: Not accepted by client!?");
+ return FORBIDDEN;
+ }
+
+ /*
+ * Finally check for acceptable renegotiation results
+ */
+ if (dc->nVerifyClient != SSL_CVERIFY_NONE) {
+ if (SSL_get_verify_result(ssl) != X509_V_OK) {
+ ssl_log(r->server, SSL_LOG_ERROR,
+ "Re-negotiation handshake failed: Client verification failed");
+ return FORBIDDEN;
+ }
+ if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE
+ && SSL_get_peer_certificate(ssl) == NULL ) {
+ ssl_log(r->server, SSL_LOG_ERROR,
+ "Re-negotiation handshake failed: Client certificate missing");
+ return FORBIDDEN;
+ }
+ }
+ }
+
+ /*
+ * Under old SSLeay we had to change the X509_STORE inside the SSL_CTX
+ * instead inside the SSL structure, so we have to reconfigure it to the
+ * old values. This should be changed with forthcoming OpenSSL version
+ * when better functionality is avaiable.
+ */
+#ifdef SSL_EXPERIMENTAL
+ if (renegotiate && reconfigured_locations) {
+ if (!SSL_CTX_load_verify_locations(ctx,
+ sc->szCACertificateFile, sc->szCACertificatePath)) {
+ ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Unable to reconfigure verify locations "
+ "to per-server configuration parameters");
+ return FORBIDDEN;
+ }
+ }
+#endif /* SSL_EXPERIMENTAL */
+
+ /*
+ * Check SSLRequire boolean expressions
+ */
+ apRequirement = dc->aRequirement;
+ pRequirements = (ssl_require_t *)apRequirement->elts;
+ for (i = 0; i < apRequirement->nelts; i++) {
+ pRequirement = &pRequirements[i];
+ ok = ssl_expr_exec(r, pRequirement->mpExpr);
+ if (ok < 0) {
+ cp = ap_psprintf(r->pool, "Failed to execute SSL requirement expression: %s",
+ ssl_expr_get_error());
+ ap_log_reason(cp, r->filename, r);
+ return FORBIDDEN;
+ }
+ if (ok != 1) {
+ ssl_log(r->server, SSL_LOG_INFO,
+ "Access to %s denied for %s (requirement expression not fulfilled)",
+ r->filename, r->connection->remote_ip);
+ ssl_log(r->server, SSL_LOG_INFO,
+ "Failed expression: %s", pRequirement->cpExpr);
+ ap_log_reason("SSL requirement expression not fulfilled "
+ "(see SSL logfile for more details)", r->filename, r);
+ return FORBIDDEN;
+ }
+ }
+
+ /*
+ * Else access is granted...
+ */
+ return OK;
+}
+
+/*
+ * Fixup Handler
+ */
+
+static const char *ssl_hook_Fixup_vars[] = {
+ "SSL_VERSION_INTERFACE",
+ "SSL_VERSION_LIBRARY",
+ "SSL_PROTOCOL",
+ "SSL_CIPHER",
+ "SSL_CIPHER_EXPORT",
+ "SSL_CIPHER_USEKEYSIZE",
+ "SSL_CIPHER_ALGKEYSIZE",
+ "SSL_CLIENT_M_VERSION",
+ "SSL_CLIENT_M_SERIAL",
+ "SSL_CLIENT_V_START",
+ "SSL_CLIENT_V_END",
+ "SSL_CLIENT_S_DN",
+ "SSL_CLIENT_S_DN_C",
+ "SSL_CLIENT_S_DN_SP",
+ "SSL_CLIENT_S_DN_L",
+ "SSL_CLIENT_S_DN_O",
+ "SSL_CLIENT_S_DN_OU",
+ "SSL_CLIENT_S_DN_CN",
+ "SSL_CLIENT_S_DN_Email",
+ "SSL_CLIENT_I_DN",
+ "SSL_CLIENT_I_DN_C",
+ "SSL_CLIENT_I_DN_SP",
+ "SSL_CLIENT_I_DN_L",
+ "SSL_CLIENT_I_DN_O",
+ "SSL_CLIENT_I_DN_OU",
+ "SSL_CLIENT_I_DN_CN",
+ "SSL_CLIENT_I_DN_Email",
+ "SSL_CLIENT_A_KEY",
+ "SSL_CLIENT_A_SIG",
+ "SSL_SERVER_M_VERSION",
+ "SSL_SERVER_M_SERIAL",
+ "SSL_SERVER_V_START",
+ "SSL_SERVER_V_END",
+ "SSL_SERVER_S_DN",
+ "SSL_SERVER_S_DN_C",
+ "SSL_SERVER_S_DN_SP",
+ "SSL_SERVER_S_DN_L",
+ "SSL_SERVER_S_DN_O",
+ "SSL_SERVER_S_DN_OU",
+ "SSL_SERVER_S_DN_CN",
+ "SSL_SERVER_S_DN_Email",
+ "SSL_SERVER_I_DN",
+ "SSL_SERVER_I_DN_C",
+ "SSL_SERVER_I_DN_SP",
+ "SSL_SERVER_I_DN_L",
+ "SSL_SERVER_I_DN_O",
+ "SSL_SERVER_I_DN_OU",
+ "SSL_SERVER_I_DN_CN",
+ "SSL_SERVER_I_DN_Email",
+ "SSL_SERVER_A_KEY",
+ "SSL_SERVER_A_SIG",
+ NULL
+};
+
+int ssl_hook_Fixup(request_rec *r)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(r->server);
+ SSLDirConfigRec *dc = myDirConfig(r);
+ table *e = r->subprocess_env;
+ char *var;
+ char *val;
+ int i;
+
+ /*
+ * Check to see if SSL is on
+ */
+ if (!sc->bEnabled)
+ return DECLINED;
+ if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL)
+ return DECLINED;
+
+ /*
+ * Annotate the SSI/CGI environment with standard SSL information
+ */
+ ap_table_set(e, "HTTPS", "on"); /* the HTTPS (=HTTP over SSL) flag! */
+ for (i = 0; ssl_hook_Fixup_vars[i] != NULL; i++) {
+ var = (char *)ssl_hook_Fixup_vars[i];
+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
+ if (!strIsEmpty(val))
+ ap_table_set(e, var, val);
+ }
+
+ /*
+ * On-demand bloat up the SSI/CGI environment with certificate data
+ */
+ if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) {
+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_CERT");
+ ap_table_set(e, "SSL_CLIENT_CERT", val);
+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_SERVER_CERT");
+ ap_table_set(e, "SSL_SERVER_CERT", val);
+ }
+
+ /*
+ * On-demand bloat up the SSI/CGI environment with compat variables
+ */
+#ifdef SSL_COMPAT
+ if (dc->nOptions & SSL_OPT_COMPATENVVARS)
+ ssl_compat_variables(r);
+#endif
+
+ return DECLINED;
+}
+
+/* _________________________________________________________________
+**
+** SSLeay Callback Functions
+** _________________________________________________________________
+*/
+
+/*
+ * Handle out the already generated RSA key...
+ */
+RSA *ssl_callback_TmpRSA(SSL *pSSL, int nExport)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ return mc->pRSATmpKey;
+}
+
+/*
+ * This SSLeay callback function is called when SSLeay
+ * does client authentication and verifies the certificate chain.
+ */
+int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
+{
+ SSL *ssl;
+ conn_rec *conn;
+ server_rec *s;
+ request_rec *r;
+ SSLSrvConfigRec *sc;
+ SSLDirConfigRec *dc;
+ X509 *xs;
+ int errnum;
+ int errdepth;
+ char *cp;
+ char *cp2;
+ int depth;
+
+ /*
+ * Get Apache context back through SSLeay context
+ */
+ ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
+ conn = (conn_rec *)SSL_get_app_data(ssl);
+ r = (request_rec *)SSL_get_app_data2(ssl);
+ s = conn->server;
+ sc = mySrvConfig(s);
+ dc = (r != NULL ? myDirConfig(r) : NULL);
+
+ /*
+ * Get verify ingredients
+ */
+ xs = X509_STORE_CTX_get_current_cert(ctx);
+ errnum = X509_STORE_CTX_get_error(ctx);
+ errdepth = X509_STORE_CTX_get_error_depth(ctx);
+
+ /*
+ * Log verification information
+ */
+ cp = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0);
+ cp2 = X509_NAME_oneline(X509_get_issuer_name(xs), NULL, 0);
+ ssl_log(s, SSL_LOG_TRACE,
+ "Certificate Verification: depth: %d, subject: %s, issuer: %s",
+ errdepth, cp != NULL ? cp : "-unknown-",
+ cp2 != NULL ? cp2 : "-unknown");
+ if (cp)
+ free(cp);
+ if (cp2)
+ free(cp2);
+
+ /*
+ * Check for optionally acceptable non-verifiable issuer situation
+ */
+ if ( ( errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
+ || errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
+ || errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
+ || errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE )
+ && sc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA ) {
+ ssl_log(s, SSL_LOG_TRACE,
+ "Certificate Verification: Verifiable Issuer is configured as "
+ "optional, therefore we're accepting the certificate");
+ ok = TRUE;
+ }
+
+ /*
+ * If we already know it's not ok, log the real reason
+ */
+ if (!ok) {
+ ssl_log(s, SSL_LOG_ERROR, "Certificate Verification: Error (%d): %s",
+ errnum, X509_verify_cert_error_string(errnum));
+ ap_ctx_set(conn->client->ctx, "ssl::client::dn", NULL);
+ ap_ctx_set(conn->client->ctx, "ssl::verify::error",
+ X509_verify_cert_error_string(errnum));
+ }
+
+ /*
+ * Finally check the depth of the certificate verification
+ */
+ if (dc != NULL && dc->nVerifyDepth != UNSET)
+ depth = dc->nVerifyDepth;
+ else
+ depth = sc->nVerifyDepth;
+ if (errdepth > depth) {
+ ssl_log(s, SSL_LOG_ERROR,
+ "Certificate Verification: Certificate Chain too long "
+ "(chain has %d certificates, but maximum allowed are only %d)",
+ errdepth, depth);
+ ap_ctx_set(conn->client->ctx, "ssl::verify::error",
+ X509_verify_cert_error_string(X509_V_ERR_CERT_CHAIN_TOO_LONG));
+ ok = FALSE;
+ }
+
+ /*
+ * And finally signal SSLeay the (perhaps changed) state
+ */
+ return (ok);
+}
+
+/*
+ * This callback function is executed by SSLeay whenever a new SSL_SESSION is
+ * added to the internal SSLeay session cache. We use this hook to spread the
+ * SSL_SESSION also to the inter-process disk-cache to make share it with our
+ * other Apache pre-forked server processes.
+ */
+int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
+{
+ conn_rec *conn;
+ server_rec *s;
+ SSLSrvConfigRec *sc;
+ long t;
+
+ /*
+ * Get Apache context back through SSLeay context
+ */
+ conn = (conn_rec *)SSL_get_app_data(ssl);
+ s = conn->server;
+ sc = mySrvConfig(s);
+
+ /*
+ * Set the timeout also for the internal SSLeay cache, because this way
+ * our inter-process cache is consulted only when it's really necessary.
+ */
+ t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout);
+ SSL_set_timeout(pNew, t);
+
+ /*
+ * Store the SSL_SESSION in the inter-process cache with the
+ * same expire time, so it expires automatically there, too.
+ */
+ ssl_scache_store(s, pNew, t);
+
+ /*
+ * Log this cache operation
+ */
+ ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
+ "request=SET id=%s timeout=%ds (session caching)",
+ ssl_scache_id2sz(pNew->session_id, pNew->session_id_length),
+ t-time(NULL));
+
+ /*
+ * return 0 which means to SSLeay that the pNew is still
+ * valid and was not freed by us with SSL_SESSION_free().
+ */
+ return 0;
+}
+
+/*
+ * This callback function is executed by SSLeay whenever a
+ * SSL_SESSION is looked up in the internal SSLeay cache and it
+ * was not found. We use this to lookup the SSL_SESSION in the
+ * inter-process disk-cache where it was perhaps stored by one
+ * of our other Apache pre-forked server processes.
+ */
+SSL_SESSION *ssl_callback_GetSessionCacheEntry(
+ SSL *ssl, unsigned char *id, int idlen, int *pCopy)
+{
+ conn_rec *conn;
+ server_rec *s;
+ SSL_SESSION *pSession;
+
+ /*
+ * Get Apache context back through SSLeay context
+ */
+ conn = (conn_rec *)SSL_get_app_data(ssl);
+ s = conn->server;
+
+ /*
+ * Try to retrieve the SSL_SESSION from the inter-process cache
+ */
+ pSession = ssl_scache_retrieve(s, id, idlen);
+
+ /*
+ * Log this cache operation
+ */
+ if (pSession != NULL)
+ ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
+ "request=GET status=FOUND id=%s (session reuse)",
+ ssl_scache_id2sz(id, idlen));
+ else
+ ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
+ "request=GET status=MISSED id=%s (session renewal)",
+ ssl_scache_id2sz(id, idlen));
+
+ /*
+ * Return NULL or the retrieved SSL_SESSION. But indicate (by
+ * setting pCopy to 0) that the reference count on the
+ * SSL_SESSION should not be incremented by the SSL library,
+ * because we will no longer hold a reference to it ourself.
+ */
+ *pCopy = 0;
+ return pSession;
+}
+
+/*
+ * This callback function is executed by SSLeay whenever a
+ * SSL_SESSION is removed from the the internal SSLeay cache.
+ * We use this to remove the SSL_SESSION in the inter-process
+ * disk-cache, too.
+ */
+void ssl_callback_DelSessionCacheEntry(
+ SSL_CTX *ctx, SSL_SESSION *pSession)
+{
+ server_rec *s;
+
+ /*
+ * Get Apache context back through SSLeay context
+ */
+ s = (server_rec *)SSL_CTX_get_app_data(ctx);
+
+ /*
+ * Remove the SSL_SESSION from the inter-process cache
+ */
+ ssl_scache_remove(s, pSession);
+
+ /*
+ * Log this cache operation
+ */
+ ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
+ "request=REM status=OK id=%s (session dead)",
+ ssl_scache_id2sz(pSession->session_id,
+ pSession->session_id_length));
+
+ return;
+}
+
+/*
+ * This callback function is executed while SSLeay processes the
+ * SSL handshake and does SSL record layer stuff. We use it to
+ * trace SSLeay's processing in out SSL logfile.
+ */
+void ssl_callback_LogTracingState(SSL *ssl, int where, int rc)
+{
+ conn_rec *c;
+ server_rec *s;
+ SSLSrvConfigRec *sc;
+ char *str;
+
+ /*
+ * find corresponding server
+ */
+ if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
+ return;
+ s = c->server;
+ if ((sc = mySrvConfig(s)) == NULL)
+ return;
+
+ /*
+ * create the various trace messages
+ */
+ if (sc->nLogLevel >= SSL_LOG_TRACE) {
+ if (where & SSL_CB_HANDSHAKE_START)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Handshake: start", SSL_LIBRARY_NAME);
+ else if (where & SSL_CB_HANDSHAKE_DONE)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Handshake: done", SSL_LIBRARY_NAME);
+ else if (where & SSL_CB_LOOP)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Loop: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ else if (where & SSL_CB_READ)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Read: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ else if (where & SSL_CB_WRITE)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Write: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ else if (where & SSL_CB_ALERT) {
+ str = (where & SSL_CB_READ) ? "read" : "write";
+ ssl_log(s, SSL_LOG_TRACE, "%s: Alert: %s:%s\n", SSL_LIBRARY_NAME,
+ SSL_alert_type_string_long(rc),
+ SSL_alert_desc_string_long(rc));
+ }
+ else if (where & SSL_CB_EXIT) {
+ if (rc == 0)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Exit: failed in %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ else if (rc < 0)
+ ssl_log(s, SSL_LOG_TRACE, "%s: Exit: error in %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ }
+ }
+
+ /*
+ * Because SSL renegotations can happen at any time (not only after
+ * SSL_accept()), the best way to log the current connection details is
+ * right after a finished handshake.
+ */
+ if (where & SSL_CB_HANDSHAKE_DONE) {
+ ssl_log(s, SSL_LOG_INFO,
+ "Connection: Client IP: %s, Protocol: %s, Cipher: %s (%s/%s bits)",
+ ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE"));
+ }
+
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c
new file mode 100644
index 00000000000..b020fd6f865
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c
@@ -0,0 +1,292 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_log.c
+** Logging Facility
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``The difference between a computer
+ industry job and open-source software
+ hacking is about 30 hours a week.''
+ -- Ralf S. Engelschall */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Logfile Support
+** _________________________________________________________________
+*/
+
+/*
+ * Open the SSL logfile
+ */
+void ssl_log_open(server_rec *s, pool *p)
+{
+ char *szLogFile;
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ piped_log *pl;
+
+ if (sc->szLogFile != NULL) {
+ if (strEQ(sc->szLogFile, "/dev/null"))
+ return;
+ else if (sc->szLogFile[0] == '|') {
+ szLogFile = ap_server_root_relative(p, sc->szLogFile+1);
+ if ((pl = ap_open_piped_log(p, szLogFile)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open reliable pipe to SSL logfile filter %s", szLogFile);
+ ssl_die();
+ }
+ sc->fileLogFile = ap_pfdopen(p, ap_piped_log_write_fd(pl), "a");
+ setbuf(sc->fileLogFile, NULL);
+ }
+ else {
+ szLogFile = ap_server_root_relative(p, sc->szLogFile);
+ if ((sc->fileLogFile = ap_pfopen(p, szLogFile, "a")) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open SSL logfile %s", szLogFile);
+ ssl_die();
+ }
+ setbuf(sc->fileLogFile, NULL);
+ }
+ }
+ return;
+}
+
+static struct {
+ int nLevel;
+ char *szLevel;
+} ssl_log_level2string[] = {
+ { SSL_LOG_ERROR, "error" },
+ { SSL_LOG_WARN, "warn" },
+ { SSL_LOG_INFO, "info" },
+ { SSL_LOG_TRACE, "trace" },
+ { SSL_LOG_DEBUG, "debug" },
+ { 0, NULL }
+};
+
+static struct {
+ char *cpPattern;
+ char *cpAnnotation;
+} ssl_log_annotate[] = {
+ { "*envelope*bad*decrypt*", "wrong pass phrase!?" },
+ { "*CLIENT_HELLO*unknown*protocol*", "speaking not SSL to HTTPS port!?" },
+ { "*CLIENT_HELLO*http*request*", "speaking HTTP to HTTPS port!?" },
+ { "*SSL3_READ_BYTES:sslv3*alert*bad*certificate*", "Subject CN in certificate not server name!?" },
+ { "*self signed certificate in certificate chain*", "Client certificate signed by CA not known to server?" },
+ { "*peer did not return a certificate*", "No CAs known to server for verification?" },
+ { NULL, NULL }
+};
+
+static char *ssl_log_annotation(char *error)
+{
+ char *errstr;
+ int i;
+
+ errstr = NULL;
+ for (i = 0; ssl_log_annotate[i].cpPattern != NULL; i++) {
+ if (ap_strcmp_match(error, ssl_log_annotate[i].cpPattern) == 0) {
+ errstr = ssl_log_annotate[i].cpAnnotation;
+ break;
+ }
+ }
+ return errstr;
+}
+
+void ssl_log(server_rec *s, int level, const char *msg, ...)
+{
+ char tstr[80];
+ char lstr[20];
+ char vstr[1024];
+ char str[1024];
+ char nstr[2];
+ int timz;
+ struct tm *t;
+ va_list ap;
+ int add;
+ int i;
+ char *astr;
+ int safe_errno;
+ unsigned long e;
+ SSLSrvConfigRec *sc;
+ char *cpE;
+ char *cpA;
+
+ /* initialization */
+ va_start(ap, msg);
+ safe_errno = errno;
+ sc = mySrvConfig(s);
+
+ /* strip out additional flags */
+ add = (level & ~SSL_LOG_MASK);
+ level = (level & SSL_LOG_MASK);
+
+ /* reduce flags when not reasonable in context */
+ if (add & SSL_ADD_ERRNO && errno == 0)
+ add &= ~SSL_ADD_ERRNO;
+ if (add & SSL_ADD_SSLERR && ERR_peek_error() == 0)
+ add &= ~SSL_ADD_SSLERR;
+
+ /* we log only levels below, except for errors */
+ if ( sc->fileLogFile == NULL
+ && !(level & SSL_LOG_ERROR))
+ return;
+ if ( level > sc->nLogLevel
+ && !(level & SSL_LOG_ERROR))
+ return;
+
+ /* determine the time entry string */
+ if (add & SSL_NO_TIMESTAMP)
+ tstr[0] = NUL;
+ else {
+ t = ap_get_gmtoff(&timz);
+ strftime(tstr, 80, "[%d/%b/%Y %H:%M:%S] ", t);
+ }
+
+ /* determine whether newline should be writteni */
+ if (add & SSL_NO_NEWLINE)
+ nstr[0] = NUL;
+ else {
+ nstr[0] = '\n';
+ nstr[1] = NUL;
+ }
+
+ /* determine level name */
+ lstr[0] = NUL;
+ if (!(add & SSL_NO_LEVELID)) {
+ for (i = 0; ssl_log_level2string[i].nLevel != 0; i++) {
+ if (ssl_log_level2string[i].nLevel == level) {
+ ap_snprintf(lstr, sizeof(lstr), "[%s]", ssl_log_level2string[i].szLevel);
+ break;
+ }
+ }
+ for (i = strlen(lstr); i <= 7; i++)
+ lstr[i] = ' ';
+ lstr[i] = NUL;
+ }
+
+ /* create custom message */
+ ap_vsnprintf(vstr, sizeof(vstr), msg, ap);
+
+ /* write out SSLog message */
+ if ((add & SSL_ADD_ERRNO) && (add & SSL_ADD_SSLERR))
+ astr = " (System and " SSL_LIBRARY_NAME " library errors follow)";
+ else if (add & SSL_ADD_ERRNO)
+ astr = " (System error follows)";
+ else if (add & SSL_ADD_SSLERR)
+ astr = " (" SSL_LIBRARY_NAME " library error follows)";
+ else
+ astr = "";
+ if (level <= sc->nLogLevel && sc->fileLogFile != NULL) {
+ ap_snprintf(str, sizeof(str), "%s%s%s%s%s", tstr, lstr, vstr, astr, nstr);
+ fprintf(sc->fileLogFile, "%s", str);
+ }
+ if (level & SSL_LOG_ERROR)
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s,
+ "mod_ssl: %s%s", vstr, astr);
+
+ /* write out additional attachment messages */
+ if (add & SSL_ADD_ERRNO) {
+ if (level <= sc->nLogLevel && sc->fileLogFile != NULL) {
+ ap_snprintf(str, sizeof(str), "%s%sSystem: %s (errno: %d)%s",
+ tstr, lstr, strerror(safe_errno), safe_errno, nstr);
+ fprintf(sc->fileLogFile, "%s", str);
+ }
+ if (level & SSL_LOG_ERROR)
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s,
+ "System: %s (errno: %d)",
+ strerror(safe_errno), safe_errno);
+ }
+ if (add & SSL_ADD_SSLERR) {
+ while ((e = ERR_get_error())) {
+ cpE = ERR_error_string(e, NULL);
+ cpA = ssl_log_annotation(cpE);
+ if (level <= sc->nLogLevel && sc->fileLogFile != NULL) {
+ ap_snprintf(str, sizeof(str), "%s%s%s: %s%s%s%s%s",
+ tstr, lstr, SSL_LIBRARY_NAME, cpE,
+ cpA != NULL ? " [Hint: " : "",
+ cpA != NULL ? cpA : "", cpA != NULL ? "]" : "",
+ nstr);
+ fprintf(sc->fileLogFile, "%s", str);
+ }
+ if (level & SSL_LOG_ERROR)
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s,
+ "%s: %s%s%s%s", SSL_LIBRARY_NAME, cpE,
+ cpA != NULL ? " [Hint: " : "",
+ cpA != NULL ? cpA : "", cpA != NULL ? "]" : "");
+ }
+ }
+ /* make sure the next log starts from a clean base */
+ /* ERR_clear_error(); */
+
+ /* cleanup and return */
+ if (sc->fileLogFile != NULL)
+ fflush(sc->fileLogFile);
+ errno = safe_errno;
+ va_end(ap);
+ return;
+}
+
+void ssl_die(void)
+{
+ /*
+ * This is used for fatal errors and here
+ * it is common module practice to really
+ * exit from the complete program.
+ */
+ exit(1);
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c
new file mode 100644
index 00000000000..8d5a14132cc
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c
@@ -0,0 +1,340 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_mutex.c
+** Semaphore for Mutual Exclusion
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Real programmers confuse
+ Christmas and Halloween
+ because DEC 25 = OCT 31.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Mutex Support (Common)
+** _________________________________________________________________
+*/
+
+void ssl_mutex_init(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nMutexMode == SSL_MUTEXMODE_FILE) {
+ ssl_mutex_file_create(s, p);
+ ap_register_cleanup(p, (void *)s, ssl_mutex_file_remove, ap_null_cleanup);
+ }
+ else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) {
+ ssl_mutex_sem_create(s, p);
+ ap_register_cleanup(p, (void *)s, ssl_mutex_sem_remove, ap_null_cleanup);
+ }
+ return;
+}
+
+void ssl_mutex_open(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
+ ssl_mutex_file_open(s, p);
+ else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
+ ssl_mutex_sem_open(s, p);
+ return;
+}
+
+void ssl_mutex_on(void)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
+ ssl_mutex_file_acquire();
+ else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
+ ssl_mutex_sem_acquire();
+ return;
+}
+
+void ssl_mutex_off(void)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nMutexMode == SSL_MUTEXMODE_FILE)
+ ssl_mutex_file_release();
+ else if (mc->nMutexMode == SSL_MUTEXMODE_SEM)
+ ssl_mutex_sem_release();
+ return;
+}
+
+
+/* _________________________________________________________________
+**
+** Mutex Support (Lockfile)
+** _________________________________________________________________
+*/
+
+void ssl_mutex_file_create(server_rec *s, pool *p)
+{
+#ifndef WIN32
+ SSLModConfigRec *mc = myModConfig();
+
+ /* create the lockfile */
+ unlink(mc->szMutexFile);
+ if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile,
+ O_WRONLY|O_CREAT, SSL_MUTEX_LOCK_MODE)) < 0) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Parent process could not create SSLMutex lockfile %s",
+ mc->szMutexFile);
+ ssl_die();
+ }
+ /* make sure the childs have access to this file */
+ if (geteuid() == 0 /* is superuser */)
+ chown(mc->szMutexFile, ap_user_id, -1 /* no gid change */);
+#endif
+ return;
+}
+
+void ssl_mutex_file_open(server_rec *s, pool *p)
+{
+#ifndef WIN32
+ SSLModConfigRec *mc = myModConfig();
+
+ /* open the lockfile (once per child) to get a unique fd */
+ if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile,
+ O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Child could not open SSLMutex lockfile %s",
+ mc->szMutexFile);
+ ssl_die();
+ }
+#endif
+ return;
+}
+
+void ssl_mutex_file_remove(void *data)
+{
+#ifndef WIN32
+ SSLModConfigRec *mc = myModConfig();
+
+ /* remove the mutex lockfile */
+ unlink(mc->szMutexFile);
+#endif
+ return;
+}
+
+#ifndef WIN32
+#ifdef SSL_USE_FCNTL
+static struct flock lock_it;
+static struct flock unlock_it;
+#endif
+#endif
+
+BOOL ssl_mutex_file_acquire(void)
+{
+ int rc = -1;
+#ifndef WIN32
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_USE_FCNTL
+ lock_it.l_whence = SEEK_SET; /* from current point */
+ lock_it.l_start = 0; /* -"- */
+ lock_it.l_len = 0; /* until end of file */
+ lock_it.l_type = F_WRLCK; /* set exclusive/write lock */
+ lock_it.l_pid = 0; /* pid not actually interesting */
+
+ while ( ((rc = fcntl(mc->nMutexFD, F_SETLKW, &lock_it)) < 0)
+ && (errno == EINTR) ) {
+ continue;
+ }
+#endif
+#ifdef SSL_USE_FLOCK
+ while ( ((rc = flock(mc->nMutexFD, LOCK_EX)) < 0)
+ && (errno == EINTR) ) {
+ continue;
+ }
+#endif
+#endif
+
+ if (rc < 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+BOOL ssl_mutex_file_release(void)
+{
+ int rc = -1;
+#ifndef WIN32
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_USE_FCNTL
+ unlock_it.l_whence = SEEK_SET; /* from current point */
+ unlock_it.l_start = 0; /* -"- */
+ unlock_it.l_len = 0; /* until end of file */
+ unlock_it.l_type = F_UNLCK; /* unlock */
+ unlock_it.l_pid = 0; /* pid not actually interesting */
+
+ rc = fcntl(mc->nMutexFD, F_SETLKW, &unlock_it);
+#endif
+#ifdef SSL_USE_FLOCK
+ rc = flock(mc->nMutexFD, LOCK_UN);
+#endif
+#endif
+
+ if (rc < 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/* _________________________________________________________________
+**
+** Mutex Support (Process Semaphore)
+** _________________________________________________________________
+*/
+
+void ssl_mutex_sem_create(server_rec *s, pool *p)
+{
+#ifdef SSL_CAN_USE_SEM
+ int semid;
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_HAVE_IPCSEM
+ semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
+ if (semid == -1 && errno == EEXIST)
+ semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
+ if (semid == -1) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Parent process could not create private SSLMutex semaphore");
+ ssl_die();
+ }
+#endif
+#ifdef SSL_HAVE_W32SEM
+ semid = (int)ap_create_mutex("mod_ssl_mutex");
+#endif
+ mc->nMutexSEMID = semid;
+#endif
+ return;
+}
+
+void ssl_mutex_sem_open(server_rec *s, pool *p)
+{
+#ifdef SSL_CAN_USE_SEM
+#ifdef SSL_HAVE_W32SEM
+ SSLModConfigRec *mc = myModConfig();
+
+ mc->nMutexSEMID = (int)ap_open_mutex("mod_ssl_mutex");
+#endif
+#endif
+ return;
+}
+
+void ssl_mutex_sem_remove(void *data)
+{
+#ifdef SSL_CAN_USE_SEM
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_HAVE_IPCSEM
+ semctl(mc->nMutexSEMID, 0, IPC_RMID, 0);
+#endif
+#ifdef SSL_HAVE_W32SEM
+ ap_destroy_mutex((mutex *)mc->nMutexSEMID);
+#endif
+#endif
+ return;
+}
+
+BOOL ssl_mutex_sem_acquire(void)
+{
+ int rc = 0;
+#ifdef SSL_CAN_USE_SEM
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_HAVE_IPCSEM
+ struct sembuf sb[] = {
+ { 0, 0, 0 }, /* wait for semaphore */
+ { 0, 1, SEM_UNDO } /* increment semaphore */
+ };
+
+ rc = semop(mc->nMutexSEMID, sb, 2);
+#endif
+#ifdef SSL_HAVE_W32SEM
+ rc = ap_acquire_mutex((mutex *)mc->nMutexSEMID);
+#endif
+#endif
+ return rc;
+}
+
+BOOL ssl_mutex_sem_release(void)
+{
+ int rc = 0;
+#ifdef SSL_CAN_USE_SEM
+ SSLModConfigRec *mc = myModConfig();
+
+#ifdef SSL_HAVE_IPCSEM
+ struct sembuf sb[] = {
+ { 0, -1, SEM_UNDO } /* derements semaphore */
+ };
+
+ rc = semop(mc->nMutexSEMID, sb, 1);
+#endif
+#ifdef SSL_HAVE_W32SEM
+ rc = ap_release_mutex((mutex *)mc->nMutexSEMID);
+#endif
+#endif
+ return rc;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c
new file mode 100644
index 00000000000..f4caa4ad64d
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c
@@ -0,0 +1,464 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_pphrase.c
+** Pass Phrase Dialog
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Treat your password like your
+ toothbrush. Don't let anybody
+ else use it, and get a new one
+ every six months.''
+ -- Clifford Stoll */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Pass Phrase and Private Key Handling
+** _________________________________________________________________
+*/
+
+#define STDERR_FILENO_STORE 10
+#define BUILTIN_DIALOG_BACKOFF 2
+#define BUILTIN_DIALOG_RETRIES 5
+
+void ssl_pphrase_Handle(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+ SSLSrvConfigRec *sc;
+ server_rec *pServ;
+ char *cpVHostID;
+ char szPath[MAX_STRING_LEN];
+ ssl_asn1_t *asn1;
+ unsigned char *ucp;
+ RSA *pRSAKey;
+ X509 *pX509Cert;
+ FILE *fp;
+ BOOL bReadable;
+ ssl_ds_array *aPassPhrase;
+ int nPassPhrase;
+ int nPassPhraseCur;
+ char *cpPassPhraseCur;
+ int nPassPhraseRetry;
+ int nPassPhraseDialog;
+ int nPassPhraseDialogCur;
+ BOOL bPassPhraseDialogOnce;
+ char **cpp;
+
+ /*
+ * Start with a fresh pass phrase array
+ */
+ aPassPhrase = ssl_ds_array_make(p, sizeof(char *));
+ nPassPhrase = 0;
+ nPassPhraseDialog = 0;
+
+ /*
+ * Walk through all configured servers
+ */
+ for (pServ = s; pServ != NULL; pServ = pServ->next) {
+ sc = mySrvConfig(pServ);
+
+ if (!sc->bEnabled)
+ continue;
+
+ cpVHostID = ssl_util_vhostid(p, pServ);
+ ssl_log(pServ, SSL_LOG_INFO,
+ "Init: Loading certificate & private key of SSL-aware server %s",
+ cpVHostID);
+
+ /*
+ * Read in server certificate: This is the easy part
+ * because this file isn't encrypted in any way.
+ */
+ if (sc->szCertificateFile == NULL) {
+ ssl_log(pServ, SSL_LOG_ERROR,
+ "Init: Server %s should be SSL-aware but has no certificate configured "
+ "[Hint: SSLCertifcateFile]", cpVHostID);
+ ssl_die();
+ }
+ ap_cpystrn(szPath, sc->szCertificateFile, sizeof(szPath));
+ if ((fp = ap_pfopen(p, szPath, "r")) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Init: Can't open server certificate file %s", szPath);
+ ssl_die();
+ }
+ pX509Cert = X509_new();
+ if (!PEM_read_X509(fp, &pX509Cert, NULL)) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+ "Init: Unable to read server certificate from file %s", szPath);
+ ssl_die();
+ }
+ ap_pfclose(p, fp);
+
+ /*
+ * Insert the certificate into global module configuration to let it
+ * survive the processing between the 1st Apache API init round (where
+ * we operate here) and the 2nd Apache init round (where the
+ * certificate is actually used to configure mod_ssl's per-server
+ * configuration structures).
+ */
+ asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPublicCert, cpVHostID);
+ asn1->nData = i2d_X509(pX509Cert, NULL);
+ asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
+ ucp = asn1->cpData; i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */
+
+ /*
+ * Free the X509 structure
+ */
+ X509_free(pX509Cert);
+
+ /*
+ * Read in the private key: This is the non-trivial part, because the
+ * key is typically encrypted, so a pass phrase dialog has to be used
+ * to request it from the user (or it has to be alternatively gathered
+ * from a dialog program). The important point here is that ISPs
+ * usually have hundrets of virtual servers configured and a lot of
+ * them use SSL, so really we have to minimize the pass phrase
+ * dialogs.
+ *
+ * The idea is this: When N virtual hosts are configured and all of
+ * them use encrypted private keys with different pass phrases, we
+ * have no chance and have to pop up N pass phrase dialogs. But
+ * usually the admin is clever enough and uses the same pass phrase
+ * for more private key files (typically he even uses one single pass
+ * phrase for all). When this is the case we can minimize the dialogs
+ * by trying to re-use already known/entered pass phrases.
+ */
+ if (sc->szKeyFile)
+ ap_cpystrn(szPath, sc->szKeyFile, sizeof(szPath));
+
+ /*
+ * Spread context variables for callback function
+ */
+ myCtxVarSet(mc, 1, pServ);
+ myCtxVarSet(mc, 2, p);
+ myCtxVarSet(mc, 3, aPassPhrase);
+ myCtxVarSet(mc, 4, &nPassPhraseCur);
+ myCtxVarSet(mc, 5, &cpPassPhraseCur);
+ myCtxVarSet(mc, 6, cpVHostID);
+ myCtxVarSet(mc, 7, &nPassPhraseDialog);
+ myCtxVarSet(mc, 8, &nPassPhraseDialogCur);
+ myCtxVarSet(mc, 9, &bPassPhraseDialogOnce);
+
+ pRSAKey = RSA_new();
+ nPassPhraseCur = 0;
+ nPassPhraseRetry = 0;
+ nPassPhraseDialogCur = 0;
+ bPassPhraseDialogOnce = TRUE;
+
+ for (;;) {
+ /*
+ * Try to read the private key file with the help of
+ * the callback function which serves the pass
+ * phrases to SSLeay
+ */
+ if ((fp = ap_pfopen(p, szPath, "r")) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Init: Can't open server private key file %s", szPath);
+ ssl_die();
+ }
+ cpPassPhraseCur = NULL;
+ bReadable = (PEM_read_RSAPrivateKey(fp, &pRSAKey,
+ ssl_pphrase_Handle_CB) ? TRUE : FALSE);
+ ap_pfclose(p, fp);
+
+ /*
+ * when the private key file now was readable,
+ * it's fine and we go out of the loop
+ */
+ if (bReadable)
+ break;
+
+ /*
+ * when we have more remembered pass phrases
+ * try to reuse these first.
+ */
+ if (nPassPhraseCur < nPassPhrase) {
+ nPassPhraseCur++;
+ continue;
+ }
+
+ /*
+ * else it's not readable and we have no more
+ * remembered pass phrases. Then this has to mean
+ * that the callback function popped up the dialog
+ * but a wrong pass phrase was entered. We give the
+ * user (but not the dialog program) a few more
+ * chances...
+ */
+ if ( sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN
+ && cpPassPhraseCur != NULL
+ && nPassPhraseRetry < BUILTIN_DIALOG_RETRIES ) {
+ fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect "
+ "(%d more retr%s permitted).\n",
+ (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry),
+ (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry) == 1 ? "y" : "ies");
+ nPassPhraseRetry++;
+ if (nPassPhraseRetry > BUILTIN_DIALOG_BACKOFF)
+ sleep((nPassPhraseRetry-BUILTIN_DIALOG_BACKOFF)*5);
+ continue;
+ }
+
+ /*
+ * Ok, anything else now means a fatal error.
+ */
+ if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) {
+ fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect.\n");
+ fprintf(stdout, "**Stopped\n");
+ }
+ ssl_log(pServ, SSL_LOG_ERROR, "Init: Pass phrase incorrect.");
+ ssl_die();
+ }
+
+ /*
+ * Log the type of reading
+ */
+ if (nPassPhraseDialogCur == 0)
+ ssl_log(pServ, SSL_LOG_TRACE,
+ "Init: (%s) unencrypted private key - pass phrase not required",
+ cpVHostID);
+ else {
+ if (cpPassPhraseCur != NULL)
+ ssl_log(pServ, SSL_LOG_TRACE,
+ "Init: (%s) encrypted private key - pass phrase requested",
+ cpVHostID);
+ else
+ ssl_log(pServ, SSL_LOG_TRACE,
+ "Init: (%s) encrypted private key - pass phrase reused",
+ cpVHostID);
+ }
+
+ /*
+ * Ok, when have one more pass phrase store it
+ */
+ if (cpPassPhraseCur != NULL) {
+ cpp = (char **)ssl_ds_array_push(aPassPhrase);
+ *cpp = cpPassPhraseCur;
+ nPassPhrase++;
+ }
+
+ /*
+ * Insert private key into the global module configuration
+ * (we convert it to a stand-alone DER byte sequence
+ * because the SSL library uses static variables inside a
+ * RSA structure which do not survive DSO reloads!)
+ */
+ asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPrivateKey, cpVHostID);
+ asn1->nData = i2d_RSAPrivateKey(pRSAKey, NULL);
+ asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
+ ucp = asn1->cpData; i2d_RSAPrivateKey(pRSAKey, &ucp); /* 2nd arg increments */
+
+ /*
+ * Free the RSA structure
+ */
+ RSA_free(pRSAKey);
+ }
+
+ /*
+ * Let the user know when we're successful.
+ */
+ if (nPassPhraseDialog > 0) {
+ sc = mySrvConfig(s);
+ if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) {
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Ok: Pass Phrase Dialog successful.\n");
+ }
+ }
+
+ /*
+ * Wipe out the used memory from the
+ * pass phrase array and then deallocate it
+ */
+ if (!ssl_ds_array_isempty(aPassPhrase)) {
+ ssl_ds_array_wipeout(aPassPhrase);
+ ssl_ds_array_kill(aPassPhrase);
+ ssl_log(s, SSL_LOG_INFO, "Init: Wiped out the queried pass phrases from memory");
+ }
+
+ return;
+}
+
+int ssl_pphrase_Handle_CB(char *buf, int bufsize, int w)
+{
+ SSLModConfigRec *mc = myModConfig();
+ server_rec *s;
+ pool *p;
+ ssl_ds_array *aPassPhrase;
+ SSLSrvConfigRec *sc;
+ int *pnPassPhraseCur;
+ char **cppPassPhraseCur;
+ char *cpVHostID;
+ int *pnPassPhraseDialog;
+ int *pnPassPhraseDialogCur;
+ BOOL *pbPassPhraseDialogOnce;
+ char **cpp;
+ int len = -1;
+
+ /*
+ * Reconnect to the context of ssl_phrase_Handle()
+ */
+ s = myCtxVarGet(mc, 1, server_rec *);
+ p = myCtxVarGet(mc, 2, pool *);
+ aPassPhrase = myCtxVarGet(mc, 3, ssl_ds_array *);
+ pnPassPhraseCur = myCtxVarGet(mc, 4, int *);
+ cppPassPhraseCur = myCtxVarGet(mc, 5, char **);
+ cpVHostID = myCtxVarGet(mc, 6, char *);
+ pnPassPhraseDialog = myCtxVarGet(mc, 7, int *);
+ pnPassPhraseDialogCur = myCtxVarGet(mc, 8, int *);
+ pbPassPhraseDialogOnce = myCtxVarGet(mc, 9, BOOL *);
+ sc = mySrvConfig(s);
+
+ (*pnPassPhraseDialog)++;
+ (*pnPassPhraseDialogCur)++;
+
+ /*
+ * When remembered pass phrases are available use them...
+ */
+ if ((cpp = (char **)ssl_ds_array_get(aPassPhrase, *pnPassPhraseCur)) != NULL) {
+ ap_cpystrn(buf, *cpp, bufsize);
+ len = strlen(buf);
+ return len;
+ }
+
+ /*
+ * Builtin dialog
+ */
+ if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) {
+ char *prompt;
+ int i;
+
+ ssl_log(s, SSL_LOG_INFO,
+ "Init: Requesting pass phrase via builtin terminal dialog");
+
+ /*
+ * Reconnect STDERR to terminal (here STDOUT) because
+ * at our init stage Apache already connected STDERR
+ * to the general error logfile.
+ */
+ dup2(STDERR_FILENO, STDERR_FILENO_STORE);
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+
+ /*
+ * The first time display a header to inform the user about what
+ * program he actually speaks to, which modules is responsible for
+ * this terminal dialog and why to the hell he has to enter
+ * something...
+ */
+ if (*pnPassPhraseDialog == 1) {
+ fprintf(stderr, "%s mod_ssl/%s (Pass Phrase Dialog)\n",
+ SERVER_BASEVERSION, MOD_SSL_VERSION);
+ fprintf(stderr, "Some of your private key files are encrypted for security reasons.\n");
+ fprintf(stderr, "In order to read them you have to provide us with the pass phrases.\n");
+ }
+ if (*pbPassPhraseDialogOnce) {
+ *pbPassPhraseDialogOnce = FALSE;
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Server %s\n", cpVHostID);
+ }
+
+ /*
+ * Emulate the SSLeay internal pass phrase dialog
+ * (see crypto/pem/pem_lib.c:def_callback() for details)
+ */
+ prompt = "Enter pass phrase:";
+ for (;;) {
+ if ((i = EVP_read_pw_string(buf, bufsize, prompt, w)) != 0) {
+ PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
+ memset(buf, 0, (unsigned int)bufsize);
+ return (-1);
+ }
+ len = strlen(buf);
+ if (len < 4)
+ fprintf(stderr, "Apache:mod_ssl:Error: Pass phrase too short (needs to be at least 4 chars).\n");
+ else
+ break;
+ }
+
+ /*
+ * Restore STDERR to Apache error logfile
+ */
+ dup2(STDERR_FILENO_STORE, STDERR_FILENO);
+ }
+
+ /*
+ * Filter program
+ */
+ else if (sc->nPassPhraseDialogType == SSL_PPTYPE_FILTER) {
+ char *cmd;
+ char *result;
+
+ ssl_log(s, SSL_LOG_INFO,
+ "Init: Requesting pass phrase from dialog filter program (%s)",
+ sc->szPassPhraseDialogPath);
+
+ cmd = ap_psprintf(p, "%s %s", sc->szPassPhraseDialogPath, cpVHostID);
+ result = ssl_util_readfilter(s, p, cmd);
+ ap_cpystrn(buf, result, bufsize);
+ len = strlen(buf);
+ }
+
+ /*
+ * Ok, we now have the pass phrase, so give it back
+ */
+ *cppPassPhraseCur = ap_pstrdup(p, buf);
+
+ /*
+ * And return it's length to SSLeay...
+ */
+ return (len);
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c
new file mode 100644
index 00000000000..fe150c8fb45
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c
@@ -0,0 +1,189 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_rand.c
+** Random Number Generator Seeding
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``The generation of random
+ numbers is too important
+ to be left to chance.'' */
+
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Support for better seeding of SSL library's RNG
+** _________________________________________________________________
+*/
+
+static int ssl_rand_choosenum(int, int);
+static int ssl_rand_feedfp(pool *, FILE *, int);
+
+int ssl_rand_seed(server_rec *s, pool *p, ssl_rsctx_t nCtx)
+{
+ SSLModConfigRec *mc;
+ array_header *apRandSeed;
+ ssl_randseed_t *pRandSeeds;
+ ssl_randseed_t *pRandSeed;
+ int nReq, nDone;
+ FILE *fp;
+ int i, n, l;
+ time_t t;
+ pid_t pid;
+
+ mc = myModConfig();
+ nReq = 0;
+ nDone = 0;
+ apRandSeed = mc->aRandSeed;
+ pRandSeeds = (ssl_randseed_t *)apRandSeed->elts;
+ for (i = 0; i < apRandSeed->nelts; i++) {
+ pRandSeed = &pRandSeeds[i];
+ if (pRandSeed->nCtx == nCtx) {
+ nReq += pRandSeed->nBytes;
+ if (pRandSeed->nSrc == SSL_RSSRC_FILE) {
+ /*
+ * seed in contents of an external file
+ */
+ if ((fp = ap_pfopen(p, pRandSeed->cpPath, "r")) == NULL)
+ continue;
+ nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes);
+ ap_pfclose(p, fp);
+ }
+ else if (pRandSeed->nSrc == SSL_RSSRC_EXEC) {
+ /*
+ * seed in contents generated by an external program
+ */
+ if ((fp = ssl_util_ppopen(s, p, pRandSeed->cpPath)) == NULL)
+ continue;
+ nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes);
+ ssl_util_ppclose(s, p, fp);
+ }
+ else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) {
+ /*
+ * seed in the current time (usually just 4 bytes)
+ */
+ t = time(NULL);
+ l = sizeof(time_t);
+ RAND_seed((unsigned char *)&t, l);
+ nDone += l;
+
+ /*
+ * seed in the current process id (usually just 4 bytes)
+ */
+ pid = getpid();
+ l = sizeof(pid_t);
+ RAND_seed((unsigned char *)&pid, l);
+ nDone += l;
+
+ /*
+ * seed in an 1KB extract of the current scoreboard
+ */
+ if (ap_scoreboard_image != NULL) {
+ n = ssl_rand_choosenum(0, SCOREBOARD_SIZE-1024-1);
+ RAND_seed((unsigned char *)ap_scoreboard_image+n, 1024);
+ nDone += 1024;
+ }
+ }
+ }
+ }
+ return nDone;
+}
+
+#define BUFSIZE 8192
+
+static int ssl_rand_feedfp(pool *p, FILE *fp, int nReq)
+{
+ int nDone;
+ unsigned char caBuf[BUFSIZE];
+ int nBuf;
+ int nRead;
+ int nTodo;
+
+ nDone = 0;
+ nRead = BUFSIZE;
+ nTodo = nReq;
+ while (1) {
+ if (nReq > 0)
+ nRead = (nTodo < BUFSIZE ? nTodo : BUFSIZE);
+ if ((nBuf = (int)fread(caBuf, 1, nRead, fp)) <= 0)
+ break;
+ RAND_seed(caBuf, nBuf);
+ nDone += nBuf;
+ if (nReq > 0) {
+ nTodo -= nBuf;
+ if (nTodo <= 0)
+ break;
+ }
+ }
+ return nDone;
+}
+
+static int ssl_rand_choosenum(int l, int h)
+{
+ int i;
+ char buf[50];
+
+ srand((unsigned int)time(NULL));
+ ap_snprintf(buf, sizeof(buf), "%.0f",
+ (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l)));
+ i = atoi(buf)+1;
+ if (i < l) i = l;
+ if (i > h) i = h;
+ return i;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c
new file mode 100644
index 00000000000..4ba070ce386
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c
@@ -0,0 +1,408 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_scache.c
+** Session Cache
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Open-Source Software: generous
+ programmers from around the world all
+ join forces to help you shoot
+ yourself in the foot for free.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Session Cache Support (Common)
+** _________________________________________________________________
+*/
+
+/*
+ * FIXME: There is no define in SSLeay, but SSLeay uses 1024*10,
+ * so 1024*20 should be ok.
+ */
+#define MAX_SESSION_DER 1024*20
+
+void ssl_scache_init(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_init(s, p);
+ ssl_scache_expire(s);
+ return;
+}
+
+void ssl_scache_store(server_rec *s, SSL_SESSION *pSession, int timeout)
+{
+ SSLModConfigRec *mc = myModConfig();
+ ssl_scinfo_t SCI;
+ UCHAR buf[MAX_SESSION_DER];
+ UCHAR *b;
+
+ /* add the key */
+ SCI.ucaKey = pSession->session_id;
+ SCI.nKey = pSession->session_id_length;
+
+ /* transform the session into a data stream */
+ SCI.ucaData = b = buf;
+ SCI.nData = i2d_SSL_SESSION(pSession, &b);
+ SCI.tExpiresAt = timeout;
+
+ /* and store it... */
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_store(s, &SCI);
+
+ return;
+}
+
+SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen)
+{
+ SSLModConfigRec *mc = myModConfig();
+ SSL_SESSION *pSession = NULL;
+ ssl_scinfo_t SCI;
+ time_t tNow;
+
+ /* create cache query */
+ SCI.ucaKey = id;
+ SCI.nKey = idlen;
+ SCI.ucaData = NULL;
+ SCI.nData = 0;
+ SCI.tExpiresAt = 0;
+
+ /* perform cache query */
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_retrieve(s, &SCI);
+
+ /* return immediately if not found */
+ if (SCI.ucaData == NULL)
+ return NULL;
+
+ /* check for expire time */
+ tNow = time(NULL);
+ if (SCI.tExpiresAt <= tNow) {
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_remove(s, &SCI);
+ return NULL;
+ }
+
+ /* extract result and return it */
+ pSession = d2i_SSL_SESSION(NULL, &SCI.ucaData, SCI.nData);
+ return pSession;
+}
+
+void ssl_scache_remove(server_rec *s, SSL_SESSION *pSession)
+{
+ SSLModConfigRec *mc = myModConfig();
+ ssl_scinfo_t SCI;
+
+ /* create cache query */
+ SCI.ucaKey = pSession->session_id;
+ SCI.nKey = pSession->session_id_length;
+ SCI.ucaData = NULL;
+ SCI.nData = 0;
+ SCI.tExpiresAt = 0;
+
+ /* perform remove */
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_remove(s, &SCI);
+
+ return;
+}
+
+void ssl_scache_expire(server_rec *s)
+{
+ SSLModConfigRec *mc = myModConfig();
+
+ if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
+ ssl_scache_dbm_expire(s);
+ return;
+}
+
+char *ssl_scache_id2sz(UCHAR *id, int idlen)
+{
+ static char str[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2];
+ char *cp;
+ int n;
+
+ cp = str;
+ for (n = 0; n < idlen && n < SSL_MAX_SSL_SESSION_ID_LENGTH; n++) {
+ ap_snprintf(cp, sizeof(str)-(cp-str), "%02X", id[n]);
+ cp += 2;
+ }
+ *cp = NUL;
+ return str;
+}
+
+
+/* _________________________________________________________________
+**
+** Session Cache Support (DBM)
+** _________________________________________________________________
+*/
+
+void ssl_scache_dbm_init(server_rec *s, pool *p)
+{
+ SSLModConfigRec *mc = myModConfig();
+ DBM *dbm;
+
+ /*
+ * for the DBM we need the data file
+ */
+ if (mc->szSessionCacheDataFile == NULL) {
+ ssl_log(s, SSL_LOG_ERROR, "SSLSessionCache required");
+ ssl_die();
+ }
+
+ /*
+ * Open it once to create it and to make sure it
+ * _can_ be created.
+ */
+ ssl_mutex_on();
+ if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,
+ O_RDWR|O_CREAT, SSL_DBM_FILE_MODE)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot create SSLSessionCache DBM file `%s'",
+ mc->szSessionCacheDataFile);
+ ssl_mutex_off();
+ return;
+ }
+ ssl_dbm_close(dbm);
+
+#ifndef WIN32
+ /*
+ * we have to make sure the Apache child processes
+ * have access to the DBM file...
+ */
+ if (geteuid() == 0 /* is superuser */) {
+ chown(mc->szSessionCacheDataFile,
+ ap_user_id, -1 /* no gid change */);
+ chown(ap_pstrcat(p, mc->szSessionCacheDataFile,
+ SSL_DBM_FILE_SUFFIX_DIR, NULL),
+ ap_user_id, -1 /* no gid change */);
+ chown(ap_pstrcat(p, mc->szSessionCacheDataFile,
+ SSL_DBM_FILE_SUFFIX_PAG, NULL),
+ ap_user_id, -1 /* no gid change */);
+ }
+#endif
+ ssl_mutex_off();
+
+ return;
+}
+
+void ssl_scache_dbm_store(server_rec *s, ssl_scinfo_t *SCI)
+{
+ SSLModConfigRec *mc = myModConfig();
+ DBM *dbm;
+ datum dbmkey;
+ datum dbmval;
+
+ /* create DBM key */
+ dbmkey.dptr = SCI->ucaKey;
+ dbmkey.dsize = SCI->nKey;
+
+ /* create DBM value */
+ dbmval.dsize = sizeof(time_t)+SCI->nData;
+ dbmval.dptr = (UCHAR *)malloc(dbmval.dsize);
+ if (dbmval.dptr == NULL)
+ return;
+ memcpy(dbmval.dptr, &SCI->tExpiresAt, sizeof(time_t));
+ memcpy((char *)dbmval.dptr+sizeof(time_t), SCI->ucaData, SCI->nData);
+
+ /* and store it to the DBM file */
+ ssl_mutex_on();
+ if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,
+ O_RDWR, SSL_DBM_FILE_MODE)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open SSLSessionCache DBM file `%s' for writing (store)",
+ mc->szSessionCacheDataFile);
+ ssl_mutex_off();
+ return;
+ }
+ ssl_dbm_store(dbm, dbmkey, dbmval, DBM_INSERT);
+ ssl_dbm_close(dbm);
+ ssl_mutex_off();
+
+ /* free temporary buffers */
+ free(dbmval.dptr);
+
+ return;
+}
+
+void ssl_scache_dbm_retrieve(server_rec *s, ssl_scinfo_t *SCI)
+{
+ SSLModConfigRec *mc = myModConfig();
+ DBM *dbm;
+ datum dbmkey;
+ datum dbmval;
+
+ /* initialize result */
+ SCI->ucaData = NULL;
+ SCI->nData = 0;
+ SCI->tExpiresAt = 0;
+
+ /* create DBM key and values */
+ dbmkey.dptr = SCI->ucaKey;
+ dbmkey.dsize = SCI->nKey;
+
+ /* and fetch it from the DBM file */
+ ssl_mutex_on();
+ if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,
+ O_RDONLY, SSL_DBM_FILE_MODE)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open SSLSessionCache DBM file `%s' for reading (fetch)",
+ mc->szSessionCacheDataFile);
+ ssl_mutex_off();
+ return;
+ }
+ dbmval = ssl_dbm_fetch(dbm, dbmkey);
+ ssl_dbm_close(dbm);
+ ssl_mutex_off();
+
+ /* immediately return if not found */
+ if (dbmval.dptr == NULL || dbmval.dsize < sizeof(time_t))
+ return;
+
+ /* copy over the information to the SCI */
+ SCI->nData = dbmval.dsize-sizeof(time_t);
+ SCI->ucaData = (UCHAR *)malloc(SCI->nData);
+ if (SCI->ucaData == NULL) {
+ SCI->nData = 0;
+ return;
+ }
+ memcpy(SCI->ucaData, (char *)dbmval.dptr+sizeof(time_t), SCI->nData);
+ memcpy(&SCI->tExpiresAt, dbmval.dptr, sizeof(time_t));
+
+ return;
+}
+
+void ssl_scache_dbm_remove(server_rec *s, ssl_scinfo_t *SCI)
+{
+ SSLModConfigRec *mc = myModConfig();
+ DBM *dbm;
+ datum dbmkey;
+
+ /* create DBM key and values */
+ dbmkey.dptr = SCI->ucaKey;
+ dbmkey.dsize = SCI->nKey;
+
+ /* and delete it from the DBM file */
+ ssl_mutex_on();
+ if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,
+ O_RDWR, SSL_DBM_FILE_MODE)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open SSLSessionCache DBM file `%s' for writing (delete)",
+ mc->szSessionCacheDataFile);
+ ssl_mutex_off();
+ return;
+ }
+ ssl_dbm_delete(dbm, dbmkey);
+ ssl_dbm_close(dbm);
+ ssl_mutex_off();
+
+ return;
+}
+
+void ssl_scache_dbm_expire(server_rec *s)
+{
+ SSLModConfigRec *mc = myModConfig();
+ static int nExpireCalls = 0;
+ DBM *dbm;
+ datum dbmkey;
+ datum dbmval;
+ time_t tNow;
+ time_t tExpiresAt;
+
+ /*
+ * It's to expensive to expire allways,
+ * so do it only from time to time...
+ */
+ if (nExpireCalls++ < 100)
+ return;
+ else
+ nExpireCalls = 0;
+
+ ssl_mutex_on();
+ if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,
+ O_RDWR, SSL_DBM_FILE_MODE)) == NULL) {
+ ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
+ "Cannot open SSLSessionCache DBM file `%s' for expiring",
+ mc->szSessionCacheDataFile);
+ ssl_mutex_off();
+ return;
+ }
+ tNow = time(NULL);
+ dbmkey = ssl_dbm_firstkey(dbm);
+ for ( ; dbmkey.dptr != NULL; dbmkey = ssl_dbm_nextkey(dbm)) {
+ dbmval = ssl_dbm_fetch(dbm, dbmkey);
+ if (dbmval.dptr == NULL)
+ continue;
+ if (dbmval.dsize < sizeof(time_t)) {
+ ssl_dbm_delete(dbm, dbmkey);
+ continue;
+ }
+ memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t));
+ if (tExpiresAt >= tNow)
+ ssl_dbm_delete(dbm, dbmkey);
+ }
+ ssl_dbm_close(dbm);
+ ssl_mutex_off();
+
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c
new file mode 100644
index 00000000000..ef54924d3e1
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c
@@ -0,0 +1,626 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_engine_vars.c
+** Variable Lookup Facility
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Those of you who think they
+ know everything are very annoying
+ to those of us who do.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Variable Lookup
+** _________________________________________________________________
+*/
+
+static char *ssl_var_lookup_header(pool *p, request_rec *r, const char *name);
+static char *ssl_var_lookup_ssl(pool *p, conn_rec *c, char *var);
+static char *ssl_var_lookup_ssl_cert(pool *p, X509 *xs, char *var);
+static char *ssl_var_lookup_ssl_cert_dn(pool *p, X509_NAME *xsname, char *var);
+static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm);
+static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs);
+static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK *sk, char *var);
+static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs);
+static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var);
+static void ssl_var_lookup_ssl_cipher_bits(char *cipher, int *usekeysize, int *algkeysize);
+static char *ssl_var_lookup_ssl_version(pool *p, char *var);
+
+void ssl_var_register(void)
+{
+ ap_hook_configure("ap::mod_ssl::var_lookup",
+ AP_HOOK_SIG6(ptr,ptr,ptr,ptr,ptr,ptr), AP_HOOK_DECLINE(NULL));
+ ap_hook_register("ap::mod_ssl::var_lookup",
+ ssl_var_lookup, AP_HOOK_NOCTX);
+ return;
+}
+
+void ssl_var_unregister(void)
+{
+ ap_hook_unregister("ap::mod_ssl::var_lookup", ssl_var_lookup);
+ return;
+}
+
+char *ssl_var_lookup(pool *p, server_rec *s, conn_rec *c, request_rec *r, char *var)
+{
+ SSLModConfigRec *mc = myModConfig();
+ char *result;
+ BOOL resdup;
+ time_t tc;
+ struct tm *tm;
+
+ result = NULL;
+ resdup = TRUE;
+
+ /*
+ * When no pool is given try to find one
+ */
+ if (p == NULL) {
+ if (r != NULL)
+ p = r->pool;
+ else if (c != NULL)
+ p = c->pool;
+ else
+ p = mc->pPool;
+ }
+
+ /*
+ * Request dependent stuff
+ */
+ if (r != NULL) {
+ if (strcEQ(var, "HTTP_USER_AGENT"))
+ result = ssl_var_lookup_header(p, r, "User-Agent");
+ else if (strcEQ(var, "HTTP_REFERER"))
+ result = ssl_var_lookup_header(p, r, "Referer");
+ else if (strcEQ(var, "HTTP_COOKIE"))
+ result = ssl_var_lookup_header(p, r, "Cookie");
+ else if (strcEQ(var, "HTTP_FORWARDED"))
+ result = ssl_var_lookup_header(p, r, "Forwarded");
+ else if (strcEQ(var, "HTTP_HOST"))
+ result = ssl_var_lookup_header(p, r, "Host");
+ else if (strcEQ(var, "HTTP_PROXY_CONNECTION"))
+ result = ssl_var_lookup_header(p, r, "Proxy-Connection");
+ else if (strcEQ(var, "HTTP_ACCEPT"))
+ result = ssl_var_lookup_header(p, r, "Accept");
+ else if (strlen(var) > 5 && strcEQn(var, "HTTP:", 5))
+ /* all other headers from which we are still not know about */
+ result = ssl_var_lookup_header(p, r, var+5);
+ else if (strcEQ(var, "THE_REQUEST"))
+ result = r->the_request;
+ else if (strcEQ(var, "REQUEST_METHOD"))
+ result = r->method;
+ else if (strcEQ(var, "REQUEST_SCHEME"))
+ result = ap_http_method(r);
+ else if (strcEQ(var, "REQUEST_URI"))
+ result = r->uri;
+ else if (strcEQ(var, "SCRIPT_FILENAME") ||
+ strcEQ(var, "REQUEST_FILENAME"))
+ result = r->filename;
+ else if (strcEQ(var, "PATH_INFO"))
+ result = r->path_info;
+ else if (strcEQ(var, "QUERY_STRING"))
+ result = r->args;
+ else if (strcEQ(var, "REMOTE_HOST"))
+ result = (char *)ap_get_remote_host(r->connection,
+ r->per_dir_config, REMOTE_NAME);
+ else if (strcEQ(var, "REMOTE_IDENT"))
+ result = (char *)ap_get_remote_logname(r);
+ else if (strcEQ(var, "IS_SUBREQ"))
+ result = (r->main != NULL ? "true" : "false");
+ else if (strcEQ(var, "DOCUMENT_ROOT"))
+ result = (char *)ap_document_root(r);
+ else if (strcEQ(var, "SERVER_ADMIN"))
+ result = r->server->server_admin;
+ else if (strcEQ(var, "SERVER_NAME"))
+ result = (char *)ap_get_server_name(r);
+ else if (strcEQ(var, "SERVER_PORT"))
+ result = ap_psprintf(p, "%u", ap_get_server_port(r));
+ else if (strcEQ(var, "SERVER_PROTOCOL"))
+ result = r->protocol;
+ }
+
+ /*
+ * Connection stuff
+ */
+ if (result == NULL && c != NULL) {
+ if (strcEQ(var, "REMOTE_ADDR"))
+ result = c->remote_ip;
+ else if (strcEQ(var, "REMOTE_USER"))
+ result = c->user;
+ else if (strcEQ(var, "AUTH_TYPE"))
+ result = c->ap_auth_type;
+ else if (strlen(var) > 4 && strcEQn(var, "SSL_", 4))
+ result = ssl_var_lookup_ssl(p, c, var+4);
+ }
+
+ /*
+ * Totally independent stuff
+ */
+ if (result == NULL) {
+ if (strlen(var) > 12 && strcEQn(var, "SSL_VERSION_", 12))
+ result = ssl_var_lookup_ssl_version(p, var+12);
+ else if (strcEQ(var, "SERVER_SOFTWARE"))
+ result = (char *)ap_get_server_version();
+ else if (strcEQ(var, "API_VERSION")) {
+ result = ap_psprintf(p, "%d", MODULE_MAGIC_NUMBER);
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "TIME_YEAR")) {
+ tc = time(NULL);
+ tm = localtime(&tc);
+ result = ap_psprintf(p, "%02d%02d",
+ (tm->tm_year / 100) + 19, tm->tm_year % 100);
+ resdup = FALSE;
+ }
+#define MKTIMESTR(format, tmfield) \
+ tc = time(NULL); \
+ tm = localtime(&tc); \
+ result = ap_psprintf(p, format, tm->tmfield); \
+ resdup = FALSE;
+ else if (strcEQ(var, "TIME_MON")) {
+ MKTIMESTR("%02d", tm_mon+1)
+ }
+ else if (strcEQ(var, "TIME_DAY")) {
+ MKTIMESTR("%02d", tm_mday)
+ }
+ else if (strcEQ(var, "TIME_HOUR")) {
+ MKTIMESTR("%02d", tm_hour)
+ }
+ else if (strcEQ(var, "TIME_MIN")) {
+ MKTIMESTR("%02d", tm_min)
+ }
+ else if (strcEQ(var, "TIME_SEC")) {
+ MKTIMESTR("%02d", tm_sec)
+ }
+ else if (strcEQ(var, "TIME_WDAY")) {
+ MKTIMESTR("%d", tm_wday)
+ }
+ else if (strcEQ(var, "TIME")) {
+ tc = time(NULL);
+ tm = localtime(&tc);
+ result = ap_psprintf(p,
+ "%02d%02d%02d%02d%02d%02d%02d", (tm->tm_year / 100) + 19,
+ (tm->tm_year % 100), tm->tm_mon+1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ resdup = FALSE;
+ }
+ /* all other env-variables from the parent Apache process */
+ else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) {
+ result = (char *)ap_table_get(r->notes, var+4);
+ if (result == NULL)
+ result = (char *)ap_table_get(r->subprocess_env, var+4);
+ if (result == NULL)
+ result = getenv(var+4);
+ }
+ }
+
+ if (result != NULL && resdup)
+ result = ap_pstrdup(p, result);
+ if (result == NULL)
+ result = "";
+ return result;
+}
+
+static char *ssl_var_lookup_header(pool *p, request_rec *r, const char *name)
+{
+ array_header *hdrs_arr;
+ table_entry *hdrs;
+ int i;
+
+ hdrs_arr = ap_table_elts(r->headers_in);
+ hdrs = (table_entry *)hdrs_arr->elts;
+ for (i = 0; i < hdrs_arr->nelts; ++i) {
+ if (hdrs[i].key == NULL)
+ continue;
+ if (strcEQ(hdrs[i].key, name))
+ return ap_pstrdup(p, hdrs[i].val);
+ }
+ return NULL;
+}
+
+static char *ssl_var_lookup_ssl(pool *p, conn_rec *c, char *var)
+{
+ char *result;
+ X509 *xs;
+ STACK *sk;
+ SSL *ssl;
+
+ result = NULL;
+
+ if (strlen(var) > 8 && strcEQn(var, "VERSION_", 8)) {
+ result = ssl_var_lookup_ssl_version(p, var+8);
+ }
+ else if (strcEQ(var, "PROTOCOL")) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ result = SSL_get_version(ssl);
+ }
+ else if (strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
+ result = ssl_var_lookup_ssl_cipher(p, c, var+6);
+ }
+ else if (strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ sk = SSL_get_peer_cert_chain(ssl);
+ result = ssl_var_lookup_ssl_cert_chain(p, sk, var+17);
+ }
+ else if (strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ if ((xs = SSL_get_peer_certificate(ssl)) != NULL)
+ result = ssl_var_lookup_ssl_cert(p, xs, var+7);
+ }
+ else if (strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ if ((xs = SSL_get_certificate(ssl)) != NULL)
+ result = ssl_var_lookup_ssl_cert(p, xs, var+7);
+ }
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert(pool *p, X509 *xs, char *var)
+{
+ char *result;
+ BOOL resdup;
+ X509_NAME *xsname;
+ int nid;
+ char *cp;
+
+ result = NULL;
+ resdup = TRUE;
+
+ if (strcEQ(var, "M_VERSION")) {
+ result = ap_psprintf(p, "%lu", X509_get_version(xs)+1);
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "M_SERIAL")) {
+ result = ssl_var_lookup_ssl_cert_serial(p, xs);
+ }
+ else if (strcEQ(var, "V_START")) {
+ result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notBefore(xs));
+ }
+ else if (strcEQ(var, "V_END")) {
+ result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs));
+ }
+ else if (strcEQ(var, "S_DN")) {
+ xsname = X509_get_subject_name(xs);
+ cp = X509_NAME_oneline(xsname, NULL, 0);
+ result = ap_pstrdup(p, cp);
+ free(cp);
+ resdup = FALSE;
+ }
+ else if (strlen(var) > 5 && strcEQn(var, "S_DN_", 5)) {
+ xsname = X509_get_subject_name(xs);
+ result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "I_DN")) {
+ xsname = X509_get_issuer_name(xs);
+ cp = X509_NAME_oneline(xsname, NULL, 0);
+ result = ap_pstrdup(p, cp);
+ free(cp);
+ resdup = FALSE;
+ }
+ else if (strlen(var) > 5 && strcEQn(var, "I_DN_", 5)) {
+ xsname = X509_get_issuer_name(xs);
+ result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "A_SIG")) {
+ nid = OBJ_obj2nid(xs->cert_info->signature->algorithm);
+ result = ap_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "A_KEY")) {
+ nid = OBJ_obj2nid(xs->cert_info->key->algor->algorithm);
+ result = ap_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "CERT")) {
+ result = ssl_var_lookup_ssl_cert_PEM(p, xs);
+ }
+
+ if (result != NULL && resdup)
+ result = ap_pstrdup(p, result);
+ return result;
+}
+
+static const struct {
+ char *name;
+ int nid;
+} ssl_var_lookup_ssl_cert_dn_rec[] = {
+ { "C", NID_countryName },
+ { "SP", NID_stateOrProvinceName },
+ { "L", NID_localityName },
+ { "O", NID_organizationName },
+ { "OU", NID_organizationalUnitName },
+ { "CN", NID_commonName },
+ { "Email", NID_pkcs9_emailAddress },
+ { NULL, 0 }
+};
+
+static char *ssl_var_lookup_ssl_cert_dn(pool *p, X509_NAME *xsname, char *var)
+{
+ char *result;
+ X509_NAME_ENTRY *xsne;
+ int i, j, n;
+
+ result = NULL;
+
+ for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {
+ if (strEQ(var, ssl_var_lookup_ssl_cert_dn_rec[i].name)) {
+ for (j = 0; j < sk_num(xsname->entries); j++) {
+ xsne = (X509_NAME_ENTRY *)sk_value(xsname->entries, j);
+ n = OBJ_obj2nid(xsne->object);
+ if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid) {
+ result = ap_palloc(p, xsne->value->length+1);
+ ap_cpystrn(result, (char *)xsne->value->data, xsne->value->length+1);
+ result[xsne->value->length] = NUL;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm)
+{
+ char *result;
+ BIO* bio;
+ int n;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ ASN1_UTCTIME_print(bio, tm);
+ n = BIO_pending(bio);
+ result = ap_pcalloc(p, n+1);
+ n = BIO_read(bio, result, n);
+ result[n] = NUL;
+ BIO_free(bio);
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs)
+{
+ char *result;
+ BIO* bio;
+ int n;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs));
+ n = BIO_pending(bio);
+ result = ap_pcalloc(p, n+1);
+ n = BIO_read(bio, result, n);
+ result[n] = NUL;
+ BIO_free(bio);
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK *sk, char *var)
+{
+ char *result;
+ X509 *xs;
+ int n;
+
+ result = NULL;
+
+ if (strspn(var, "0123456789") == strlen(var)) {
+ n = atoi(var);
+ if (sk_num(sk) >= n) {
+ xs = (X509 *)sk_value(sk, n);
+ result = ssl_var_lookup_ssl_cert_PEM(p, xs);
+ }
+ }
+
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs)
+{
+ char *result;
+ BIO *bio;
+ int n;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ PEM_write_bio_X509(bio, xs);
+ n = BIO_pending(bio);
+ result = ap_pcalloc(p, n+1);
+ n = BIO_read(bio, result, n);
+ result[n] = NUL;
+ BIO_free(bio);
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var)
+{
+ char *result;
+ BOOL resdup;
+ char *cipher;
+ int usekeysize, algkeysize;
+ SSL *ssl;
+
+ result = NULL;
+ resdup = TRUE;
+
+ if (strEQ(var, "")) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ result = SSL_get_cipher_name(ssl);
+ }
+ else if (strcEQ(var, "_EXPORT")) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ cipher = SSL_get_cipher_name(ssl);
+ ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize);
+ result = (usekeysize < 56 ? "true" : "false");
+ }
+ else if (strcEQ(var, "_USEKEYSIZE")) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ cipher = SSL_get_cipher_name(ssl);
+ ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize);
+ result = ap_psprintf(p, "%d", usekeysize);
+ resdup = FALSE;
+ }
+ else if (strcEQ(var, "_ALGKEYSIZE")) {
+ ssl = ap_ctx_get(c->client->ctx, "ssl");
+ cipher = SSL_get_cipher_name(ssl);
+ ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize);
+ result = ap_psprintf(p, "%d", algkeysize);
+ resdup = FALSE;
+ }
+
+ if (result != NULL && resdup)
+ result = ap_pstrdup(p, result);
+ return result;
+}
+
+/*
+ * This structure is used instead of SSL_get_cipher_bits() because
+ * this SSLeay function has rounding problems, but we want the
+ * correct sizes.
+ */
+static const struct {
+ char *szName;
+ int nUseKeySize;
+ int nAlgKeySize;
+} ssl_var_lookup_ssl_cipher_bits_rec[] = {
+ { SSL3_TXT_RSA_IDEA_128_SHA /*IDEA-CBC-SHA*/, 128, 128 },
+ { SSL3_TXT_RSA_NULL_MD5 /*NULL-MD5*/, 0, 0 },
+ { SSL3_TXT_RSA_NULL_SHA /*NULL-SHA*/, 0, 0 },
+ { SSL3_TXT_RSA_RC4_40_MD5 /*EXP-RC4-MD5*/, 40, 128 },
+ { SSL3_TXT_RSA_RC4_128_MD5 /*RC4-MD5*/, 128, 128 },
+ { SSL3_TXT_RSA_RC4_128_SHA /*RC4-SHA*/, 128, 128 },
+ { SSL3_TXT_RSA_RC2_40_MD5 /*EXP-RC2-CBC-MD5*/, 40, 128 },
+ { SSL3_TXT_RSA_IDEA_128_SHA /*IDEA-CBC-MD5*/, 128, 128 },
+ { SSL3_TXT_RSA_DES_40_CBC_SHA /*EXP-DES-CBC-SHA*/, 40, 56 },
+ { SSL3_TXT_RSA_DES_64_CBC_SHA /*DES-CBC-SHA*/ , 56, 56 },
+ { SSL3_TXT_RSA_DES_192_CBC3_SHA /*DES-CBC3-SHA*/ , 168, 168 },
+ { SSL3_TXT_DH_DSS_DES_40_CBC_SHA /*EXP-DH-DSS-DES-CBC-SHA*/, 40, 56 },
+ { SSL3_TXT_DH_DSS_DES_64_CBC_SHA /*DH-DSS-DES-CBC-SHA*/, 56, 56 },
+ { SSL3_TXT_DH_DSS_DES_192_CBC3_SHA /*DH-DSS-DES-CBC3-SHA*/, 168, 168 },
+ { SSL3_TXT_DH_RSA_DES_40_CBC_SHA /*EXP-DH-RSA-DES-CBC-SHA*/, 40, 56 },
+ { SSL3_TXT_DH_RSA_DES_64_CBC_SHA /*DH-RSA-DES-CBC-SHA*/, 56, 56 },
+ { SSL3_TXT_DH_RSA_DES_192_CBC3_SHA /*DH-RSA-DES-CBC3-SHA*/, 168, 168 },
+ { SSL3_TXT_EDH_DSS_DES_40_CBC_SHA /*EXP-EDH-DSS-DES-CBC-SHA*/, 40, 56 },
+ { SSL3_TXT_EDH_DSS_DES_64_CBC_SHA /*EDH-DSS-DES-CBC-SHA*/, 56, 56 },
+ { SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA /*EDH-DSS-DES-CBC3-SHA*/, 168, 168 },
+ { SSL3_TXT_EDH_RSA_DES_40_CBC_SHA /*EXP-EDH-RSA-DES-CBC*/, 40, 56 },
+ { SSL3_TXT_EDH_RSA_DES_64_CBC_SHA /*EDH-RSA-DES-CBC-SHA*/, 56, 56 },
+ { SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA /*EDH-RSA-DES-CBC3-SHA*/, 168, 168 },
+ { SSL3_TXT_ADH_RC4_40_MD5 /*EXP-ADH-RC4-MD5*/, 40, 128 },
+ { SSL3_TXT_ADH_RC4_128_MD5 /*ADH-RC4-MD5*/, 128, 128 },
+ { SSL3_TXT_ADH_DES_40_CBC_SHA /*EXP-ADH-DES-CBC-SHA*/, 40, 128 },
+ { SSL3_TXT_ADH_DES_64_CBC_SHA /*ADH-DES-CBC-SHA*/, 56, 56 },
+ { SSL3_TXT_ADH_DES_192_CBC_SHA /*ADH-DES-CBC3-SHA*/, 168, 168 },
+ { SSL3_TXT_FZA_DMS_NULL_SHA /*FZA-NULL-SHA*/, 0, 0 },
+ { SSL3_TXT_FZA_DMS_FZA_SHA /*FZA-FZA-CBC-SHA*/, 0, 0 },
+ { SSL3_TXT_FZA_DMS_RC4_SHA /*FZA-RC4-SHA*/, 128, 128 },
+ { SSL2_TXT_DES_64_CFB64_WITH_MD5_1 /*DES-CFB-M1*/, 56, 56 },
+ { SSL2_TXT_RC2_128_CBC_WITH_MD5 /*RC2-CBC-MD5*/, 128, 128 },
+ { SSL2_TXT_DES_64_CBC_WITH_MD5 /*DES-CBC-MD5*/, 56, 56 },
+ { SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 /*DES-CBC3-MD5*/, 168, 168 },
+ { SSL2_TXT_RC4_64_WITH_MD5 /*RC4-64-MD5*/, 64, 64 },
+ { SSL2_TXT_NULL /*NULL*/, 0, 0 },
+ { NULL, 0, 0 }
+};
+
+static void ssl_var_lookup_ssl_cipher_bits(char *cipher, int *usekeysize, int *algkeysize)
+{
+ int n;
+
+ *usekeysize = 0;
+ *algkeysize = 0;
+ for (n = 0; ssl_var_lookup_ssl_cipher_bits_rec[n].szName; n++) {
+ if (strEQ(cipher, ssl_var_lookup_ssl_cipher_bits_rec[n].szName)) {
+ *algkeysize = ssl_var_lookup_ssl_cipher_bits_rec[n].nAlgKeySize;
+ *usekeysize = ssl_var_lookup_ssl_cipher_bits_rec[n].nUseKeySize;
+ break;
+ }
+ }
+ return;
+}
+
+static char *ssl_var_lookup_ssl_version(pool *p, char *var)
+{
+ char *result;
+ char *cp, *cp2;
+
+ result = NULL;
+
+ if (strEQ(var, "PRODUCT")) {
+#if defined(SSL_PRODUCT_NAME) && defined(SSL_PRODUCT_VERSION)
+ result = ap_psprintf(p, "%s/%s", SSL_PRODUCT_NAME, SSL_PRODUCT_VERSION);
+#else
+ result = NULL;
+#endif
+ }
+ else if (strEQ(var, "INTERFACE")) {
+ result = ap_psprintf(p, "mod_ssl/%s", MOD_SSL_VERSION);
+ }
+ else if (strEQ(var, "LIBRARY")) {
+ result = ap_pstrdup(p, SSLeay_version(SSLEAY_VERSION));
+ if ((cp = strchr(result, ' ')) != NULL) {
+ *cp = '/';
+ if ((cp2 = strchr(cp, ' ')) != NULL)
+ *cp2 = NUL;
+ }
+ }
+ return result;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr.c
new file mode 100644
index 00000000000..0015ea09ad5
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr.c
@@ -0,0 +1,119 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr.c
+** Expression Handling
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``It is hard to fly with
+ the eagles when you work
+ with the turkeys.''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Expression Handling
+** _________________________________________________________________
+*/
+
+ssl_expr_info_type ssl_expr_info;
+char *ssl_expr_error;
+
+ssl_expr *ssl_expr_comp(pool *p, char *expr)
+{
+ ssl_expr_info.pool = p;
+ ssl_expr_info.inputbuf = expr;
+ ssl_expr_info.inputlen = strlen(expr);
+ ssl_expr_info.inputptr = ssl_expr_info.inputbuf;
+ ssl_expr_info.expr = FALSE;
+
+ ssl_expr_error = NULL;
+ if (ssl_expr_yyparse())
+ return NULL;
+ return ssl_expr_info.expr;
+}
+
+char *ssl_expr_get_error(void)
+{
+ if (ssl_expr_error == NULL)
+ return "";
+ return ssl_expr_error;
+}
+
+ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *a1, void *a2)
+{
+ ssl_expr *node;
+
+ node = (ssl_expr *)ap_palloc(ssl_expr_info.pool, sizeof(ssl_expr));
+ node->node_op = op;
+ node->node_arg1 = (char *)a1;
+ node->node_arg2 = (char *)a2;
+ return node;
+}
+
+int ssl_expr_exec(request_rec *r, ssl_expr *expr)
+{
+ BOOL rc;
+
+ rc = ssl_expr_eval(r, expr);
+ if (ssl_expr_error != NULL)
+ return (-1);
+ else
+ return (rc ? 1 : 0);
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr.h b/usr.sbin/httpd/src/modules/ssl/ssl_expr.h
new file mode 100644
index 00000000000..b6851971038
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr.h
@@ -0,0 +1,139 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr.h
+** Expression Handling (Header)
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+ /* ``May all your PUSHes be POPed.'' */
+
+#ifndef SSL_EXPR_H
+#define SSL_EXPR_H
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+#ifndef YY_NULL
+#define YY_NULL 0
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef BOOL
+#define BOOL unsigned int
+#endif
+
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+
+typedef enum {
+ op_NOP, op_ListElement,
+ op_True, op_False, op_Not, op_Or, op_And, op_Comp,
+ op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE,
+ op_Digit, op_String, op_Regex, op_Var, op_Func
+} ssl_expr_node_op;
+
+typedef struct {
+ ssl_expr_node_op node_op;
+ void *node_arg1;
+ void *node_arg2;
+} ssl_expr_node;
+
+typedef ssl_expr_node ssl_expr;
+
+typedef struct {
+ pool *pool;
+ char *inputbuf;
+ int inputlen;
+ char *inputptr;
+ ssl_expr *expr;
+} ssl_expr_info_type;
+
+extern ssl_expr_info_type ssl_expr_info;
+extern char *ssl_expr_error;
+
+#define yylval ssl_expr_yylval
+#define yyerror ssl_expr_yyerror
+#define yyinput ssl_expr_yyinput
+
+extern int ssl_expr_yyparse(void);
+extern int ssl_expr_yyerror(char *);
+extern int ssl_expr_yylex(void);
+
+extern ssl_expr *ssl_expr_comp(pool *, char *);
+extern int ssl_expr_exec(request_rec *, ssl_expr *);
+extern char *ssl_expr_get_error(void);
+extern ssl_expr *ssl_expr_make(ssl_expr_node_op, void *, void *);
+extern BOOL ssl_expr_eval(request_rec *, ssl_expr *);
+
+#endif /* SSL_EXPR_H */
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c
new file mode 100644
index 00000000000..61e6f826ac5
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c
@@ -0,0 +1,257 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr_eval.c
+** Expression Evaluation
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Make love,
+ not software!''
+ -- Unknown */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Expression Evaluation
+** _________________________________________________________________
+*/
+
+static BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node);
+static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node);
+static char *ssl_expr_eval_func_file(request_rec *r, char *filename);
+
+BOOL ssl_expr_eval(request_rec *r, ssl_expr *node)
+{
+ switch (node->node_op) {
+ case op_True: {
+ return TRUE;
+ }
+ case op_False: {
+ return FALSE;
+ }
+ case op_Not: {
+ ssl_expr *e = (ssl_expr *)node->node_arg1;
+ return (!ssl_expr_eval(r, e));
+ }
+ case op_Or: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (ssl_expr_eval(r, e1) || ssl_expr_eval(r, e2));
+ }
+ case op_And: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (ssl_expr_eval(r, e1) && ssl_expr_eval(r, e2));
+ }
+ case op_Comp: {
+ ssl_expr *e = (ssl_expr *)node->node_arg1;
+ return ssl_expr_eval_comp(r, e);
+ }
+ default: {
+ ssl_expr_error = "Internal evaluation error: Unknown expression node";
+ return FALSE;
+ }
+ }
+}
+
+static BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node)
+{
+ switch (node->node_op) {
+ case op_EQ: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) == 0);
+ }
+ case op_NE: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) != 0);
+ }
+ case op_LT: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) < 0);
+ }
+ case op_LE: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) <= 0);
+ }
+ case op_GT: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) > 0);
+ }
+ case op_GE: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) >= 0);
+ }
+ case op_IN: {
+ ssl_expr *e1 = (ssl_expr *)node->node_arg1;
+ ssl_expr *e2 = (ssl_expr *)node->node_arg2;
+ ssl_expr *e3;
+ char *w1 = ssl_expr_eval_word(r, e1);
+ BOOL found = FALSE;
+ do {
+ e3 = (ssl_expr *)e2->node_arg1;
+ e2 = (ssl_expr *)e2->node_arg2;
+ if (strcmp(w1, ssl_expr_eval_word(r, e3)) == 0) {
+ found = TRUE;
+ break;
+ }
+ } while (e2 != NULL);
+ return found;
+ }
+ case op_REG: {
+ ssl_expr *e1;
+ ssl_expr *e2;
+ char *word;
+ regex_t *regex;
+
+ e1 = (ssl_expr *)node->node_arg1;
+ e2 = (ssl_expr *)node->node_arg2;
+ word = ssl_expr_eval_word(r, e1);
+ regex = (regex_t *)(e2->node_arg1);
+ return (regexec(regex, word, 0, NULL, 0) == 0);
+ }
+ case op_NRE: {
+ ssl_expr *e1;
+ ssl_expr *e2;
+ char *word;
+ regex_t *regex;
+
+ e1 = (ssl_expr *)node->node_arg1;
+ e2 = (ssl_expr *)node->node_arg2;
+ word = ssl_expr_eval_word(r, e1);
+ regex = (regex_t *)(e2->node_arg1);
+ return !(regexec(regex, word, 0, NULL, 0) == 0);
+ }
+ default: {
+ ssl_expr_error = "Internal evaluation error: Unknown expression node";
+ return FALSE;
+ }
+ }
+}
+
+static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node)
+{
+ switch (node->node_op) {
+ case op_Digit: {
+ char *string = (char *)node->node_arg1;
+ return string;
+ }
+ case op_String: {
+ char *string = (char *)node->node_arg1;
+ return string;
+ }
+ case op_Var: {
+ char *var = (char *)node->node_arg1;
+ char *val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
+ return (val == NULL ? "" : val);
+ }
+ case op_Func: {
+ char *name = (char *)node->node_arg1;
+ ssl_expr *args = (ssl_expr *)node->node_arg2;
+ if (strEQ(name, "file"))
+ return ssl_expr_eval_func_file(r, (char *)(args->node_arg1));
+ else {
+ ssl_expr_error = "Internal evaluation error: Unknown function name";
+ return "";
+ }
+ }
+ default: {
+ ssl_expr_error = "Internal evaluation error: Unknown expression node";
+ return FALSE;
+ }
+ }
+}
+
+static char *ssl_expr_eval_func_file(request_rec *r, char *filename)
+{
+ FILE *fp;
+ char *buf;
+ int len;
+
+ if ((fp = ap_pfopen(r->pool, filename, "r")) == NULL) {
+ ssl_expr_error = "Cannot open file";
+ return "";
+ }
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ if (len == 0) {
+ buf = (char *)ap_palloc(r->pool, sizeof(char) * 1);
+ *buf = NUL;
+ }
+ else {
+ if ((buf = (char *)ap_palloc(r->pool, sizeof(char) * len+1)) == NULL) {
+ ssl_expr_error = "Cannot allocate memory";
+ ap_pfclose(r->pool, fp);
+ return "";
+ }
+ fseek(fp, 0, SEEK_SET);
+ if (fread(buf, len, 1, fp) == 0) {
+ ssl_expr_error = "Cannot read from file";
+ fclose(fp);
+ return ("");
+ }
+ buf[len] = NUL;
+ }
+ ap_pfclose(r->pool, fp);
+ return buf;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c
new file mode 100644
index 00000000000..cbc42253136
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c
@@ -0,0 +1,550 @@
+#ifndef lint
+#endif
+#include <stdlib.h>
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYLEX ssl_expr_yylex()
+#define YYEMPTY -1
+#define ssl_expr_yyclearin (ssl_expr_yychar=(YYEMPTY))
+#define ssl_expr_yyerrok (ssl_expr_yyerrflag=0)
+#define YYRECOVERING (ssl_expr_yyerrflag!=0)
+#if defined(c_plusplus) || defined(__cplusplus)
+#include <stdlib.h>
+#else
+extern char *getenv();
+extern void *realloc();
+#endif
+static int ssl_expr_yygrowstack();
+#define YYPREFIX "ssl_expr_yy"
+#include "mod_ssl.h"
+typedef union {
+ char *cpVal;
+ ssl_expr *exVal;
+} YYSTYPE;
+#define T_TRUE 257
+#define T_FALSE 258
+#define T_DIGIT 259
+#define T_ID 260
+#define T_STRING 261
+#define T_REGEX 262
+#define T_REGEX_I 263
+#define T_FUNC_FILE 264
+#define T_OP_EQ 265
+#define T_OP_NE 266
+#define T_OP_LT 267
+#define T_OP_LE 268
+#define T_OP_GT 269
+#define T_OP_GE 270
+#define T_OP_REG 271
+#define T_OP_NRE 272
+#define T_OP_IN 273
+#define T_OP_OR 274
+#define T_OP_AND 275
+#define T_OP_NOT 276
+#define YYERRCODE 256
+const short ssl_expr_yylhs[] = { -1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 5, 5, 6,
+ 6, 6, 6, 4, 4, 3,
+};
+const short ssl_expr_yylen[] = { 2,
+ 1, 1, 1, 2, 3, 3, 1, 3, 3, 3,
+ 3, 3, 3, 3, 5, 3, 3, 1, 3, 1,
+ 1, 4, 1, 1, 1, 4,
+};
+const short ssl_expr_yydefred[] = { 0,
+ 2, 3, 20, 21, 0, 0, 0, 0, 0, 0,
+ 7, 23, 0, 0, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 6, 9, 10, 11, 12, 13, 14, 24,
+ 25, 16, 17, 0, 26, 22, 0, 18, 15, 0,
+ 19,
+};
+const short ssl_expr_yydgoto[] = { 9,
+ 10, 11, 12, 42, 47, 13,
+};
+const short ssl_expr_yysindex[] = { -37,
+ 0, 0, 0, 0, -35, -37, -37, -99, 0, -247,
+ 0, 0, -250, -229, 0, -39, -227, -37, -37, -33,
+ -33, -33, -33, -33, -33, -233, -233, -89, -6, 0,
+ -87, -239, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -33, 0, 0, -38, 0, 0, -33,
+ 0,
+};
+const short ssl_expr_yyrindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+};
+const short ssl_expr_yygindex[] = { 0,
+ 7, 0, 0, 13, 0, -13,
+};
+#define YYTABLESIZE 275
+const short ssl_expr_yytable[] = { 8,
+ 5, 30, 7, 8, 14, 50, 34, 35, 36, 37,
+ 38, 39, 15, 16, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 17, 32, 33, 18, 19, 40, 41,
+ 48, 29, 31, 44, 45, 19, 51, 46, 1, 43,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 49, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 2, 3, 0, 4, 0, 3, 5, 4, 0, 0,
+ 5, 0, 0, 0, 18, 19, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5,
+};
+const short ssl_expr_yycheck[] = { 37,
+ 0, 41, 40, 37, 40, 44, 20, 21, 22, 23,
+ 24, 25, 6, 7, 265, 266, 267, 268, 269, 270,
+ 271, 272, 273, 123, 18, 19, 274, 275, 262, 263,
+ 44, 261, 260, 123, 41, 275, 50, 125, 0, 27,
+ -1, 41, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 125, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 257,
+ 258, 259, -1, 261, -1, 259, 264, 261, -1, -1,
+ 264, -1, -1, -1, 274, 275, -1, -1, 276, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 274,
+};
+#define YYFINAL 9
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#elif YYDEBUG
+#include <stdio.h>
+#endif
+#define YYMAXTOKEN 276
+#if YYDEBUG
+const char * const ssl_expr_yyname[] = {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,"'%'",0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_TRUE",
+"T_FALSE","T_DIGIT","T_ID","T_STRING","T_REGEX","T_REGEX_I","T_FUNC_FILE",
+"T_OP_EQ","T_OP_NE","T_OP_LT","T_OP_LE","T_OP_GT","T_OP_GE","T_OP_REG",
+"T_OP_NRE","T_OP_IN","T_OP_OR","T_OP_AND","T_OP_NOT",
+};
+const char * const ssl_expr_yyrule[] = {
+"$accept : root",
+"root : expr",
+"expr : T_TRUE",
+"expr : T_FALSE",
+"expr : T_OP_NOT expr",
+"expr : expr T_OP_OR expr",
+"expr : expr T_OP_AND expr",
+"expr : comparison",
+"expr : '(' expr ')'",
+"comparison : word T_OP_EQ word",
+"comparison : word T_OP_NE word",
+"comparison : word T_OP_LT word",
+"comparison : word T_OP_LE word",
+"comparison : word T_OP_GT word",
+"comparison : word T_OP_GE word",
+"comparison : word T_OP_IN '{' words '}'",
+"comparison : word T_OP_REG regex",
+"comparison : word T_OP_NRE regex",
+"words : word",
+"words : words ',' word",
+"word : T_DIGIT",
+"word : T_STRING",
+"word : '%' '{' T_ID '}'",
+"word : funccall",
+"regex : T_REGEX",
+"regex : T_REGEX_I",
+"funccall : T_FUNC_FILE '(' T_STRING ')'",
+};
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+#define YYINITSTACKSIZE 200
+int ssl_expr_yydebug;
+int ssl_expr_yynerrs;
+int ssl_expr_yyerrflag;
+int ssl_expr_yychar;
+short *ssl_expr_yyssp;
+YYSTYPE *ssl_expr_yyvsp;
+YYSTYPE ssl_expr_yyval;
+YYSTYPE ssl_expr_yylval;
+short *ssl_expr_yyss;
+short *ssl_expr_yysslim;
+YYSTYPE *ssl_expr_yyvs;
+int ssl_expr_yystacksize;
+
+int ssl_expr_yyerror(char *s)
+{
+ ssl_expr_error = s;
+ return 2;
+}
+
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+static int ssl_expr_yygrowstack()
+{
+ int newsize, i;
+ short *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = ssl_expr_yystacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return -1;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+ i = ssl_expr_yyssp - ssl_expr_yyss;
+ if ((newss = (short *)realloc(ssl_expr_yyss, newsize * sizeof *newss)) == NULL)
+ return -1;
+ ssl_expr_yyss = newss;
+ ssl_expr_yyssp = newss + i;
+ if ((newvs = (YYSTYPE *)realloc(ssl_expr_yyvs, newsize * sizeof *newvs)) == NULL)
+ return -1;
+ ssl_expr_yyvs = newvs;
+ ssl_expr_yyvsp = newvs + i;
+ ssl_expr_yystacksize = newsize;
+ ssl_expr_yysslim = ssl_expr_yyss + newsize - 1;
+ return 0;
+}
+
+#define YYABORT goto ssl_expr_yyabort
+#define YYREJECT goto ssl_expr_yyabort
+#define YYACCEPT goto ssl_expr_yyaccept
+#define YYERROR goto ssl_expr_yyerrlab
+
+int
+ssl_expr_yyparse()
+{
+ register int ssl_expr_yym, ssl_expr_yyn, ssl_expr_yystate;
+#if YYDEBUG
+ register const char *ssl_expr_yys;
+
+ if ((ssl_expr_yys = getenv("YYDEBUG")))
+ {
+ ssl_expr_yyn = *ssl_expr_yys;
+ if (ssl_expr_yyn >= '0' && ssl_expr_yyn <= '9')
+ ssl_expr_yydebug = ssl_expr_yyn - '0';
+ }
+#endif
+
+ ssl_expr_yynerrs = 0;
+ ssl_expr_yyerrflag = 0;
+ ssl_expr_yychar = (-1);
+
+ if (ssl_expr_yyss == NULL && ssl_expr_yygrowstack()) goto ssl_expr_yyoverflow;
+ ssl_expr_yyssp = ssl_expr_yyss;
+ ssl_expr_yyvsp = ssl_expr_yyvs;
+ *ssl_expr_yyssp = ssl_expr_yystate = 0;
+
+ssl_expr_yyloop:
+ if ((ssl_expr_yyn = ssl_expr_yydefred[ssl_expr_yystate])) goto ssl_expr_yyreduce;
+ if (ssl_expr_yychar < 0)
+ {
+ if ((ssl_expr_yychar = ssl_expr_yylex()) < 0) ssl_expr_yychar = 0;
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ {
+ ssl_expr_yys = 0;
+ if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
+ if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, ssl_expr_yystate, ssl_expr_yychar, ssl_expr_yys);
+ }
+#endif
+ }
+ if ((ssl_expr_yyn = ssl_expr_yysindex[ssl_expr_yystate]) && (ssl_expr_yyn += ssl_expr_yychar) >= 0 &&
+ ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yychar)
+ {
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, ssl_expr_yystate, ssl_expr_yytable[ssl_expr_yyn]);
+#endif
+ if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
+ {
+ goto ssl_expr_yyoverflow;
+ }
+ *++ssl_expr_yyssp = ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
+ *++ssl_expr_yyvsp = ssl_expr_yylval;
+ ssl_expr_yychar = (-1);
+ if (ssl_expr_yyerrflag > 0) --ssl_expr_yyerrflag;
+ goto ssl_expr_yyloop;
+ }
+ if ((ssl_expr_yyn = ssl_expr_yyrindex[ssl_expr_yystate]) && (ssl_expr_yyn += ssl_expr_yychar) >= 0 &&
+ ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yychar)
+ {
+ ssl_expr_yyn = ssl_expr_yytable[ssl_expr_yyn];
+ goto ssl_expr_yyreduce;
+ }
+ if (ssl_expr_yyerrflag) goto ssl_expr_yyinrecovery;
+#if defined(lint) || defined(__GNUC__)
+ goto ssl_expr_yynewerror;
+#endif
+ssl_expr_yynewerror:
+ ssl_expr_yyerror("syntax error");
+#if defined(lint) || defined(__GNUC__)
+ goto ssl_expr_yyerrlab;
+#endif
+ssl_expr_yyerrlab:
+ ++ssl_expr_yynerrs;
+ssl_expr_yyinrecovery:
+ if (ssl_expr_yyerrflag < 3)
+ {
+ ssl_expr_yyerrflag = 3;
+ for (;;)
+ {
+ if ((ssl_expr_yyn = ssl_expr_yysindex[*ssl_expr_yyssp]) && (ssl_expr_yyn += YYERRCODE) >= 0 &&
+ ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *ssl_expr_yyssp, ssl_expr_yytable[ssl_expr_yyn]);
+#endif
+ if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
+ {
+ goto ssl_expr_yyoverflow;
+ }
+ *++ssl_expr_yyssp = ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
+ *++ssl_expr_yyvsp = ssl_expr_yylval;
+ goto ssl_expr_yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *ssl_expr_yyssp);
+#endif
+ if (ssl_expr_yyssp <= ssl_expr_yyss) goto ssl_expr_yyabort;
+ --ssl_expr_yyssp;
+ --ssl_expr_yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (ssl_expr_yychar == 0) goto ssl_expr_yyabort;
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ {
+ ssl_expr_yys = 0;
+ if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
+ if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, ssl_expr_yystate, ssl_expr_yychar, ssl_expr_yys);
+ }
+#endif
+ ssl_expr_yychar = (-1);
+ goto ssl_expr_yyloop;
+ }
+ssl_expr_yyreduce:
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, ssl_expr_yystate, ssl_expr_yyn, ssl_expr_yyrule[ssl_expr_yyn]);
+#endif
+ ssl_expr_yym = ssl_expr_yylen[ssl_expr_yyn];
+ ssl_expr_yyval = ssl_expr_yyvsp[1-ssl_expr_yym];
+ switch (ssl_expr_yyn)
+ {
+case 1:
+{ ssl_expr_info.expr = ssl_expr_yyvsp[0].exVal; }
+break;
+case 2:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_True, NULL, NULL); }
+break;
+case 3:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_False, NULL, NULL); }
+break;
+case 4:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_Not, ssl_expr_yyvsp[0].exVal, NULL); }
+break;
+case 5:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_Or, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 6:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_And, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 7:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_Comp, ssl_expr_yyvsp[0].exVal, NULL); }
+break;
+case 8:
+{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[-1].exVal; }
+break;
+case 9:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_EQ, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 10:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_NE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 11:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_LT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 12:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_LE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 13:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_GT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 14:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_GE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 15:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_IN, ssl_expr_yyvsp[-4].exVal, ssl_expr_yyvsp[-1].exVal); }
+break;
+case 16:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_REG, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 17:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_NRE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
+break;
+case 18:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, NULL); }
+break;
+case 19:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, ssl_expr_yyvsp[-2].exVal); }
+break;
+case 20:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_Digit, ssl_expr_yyvsp[0].cpVal, NULL); }
+break;
+case 21:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_String, ssl_expr_yyvsp[0].cpVal, NULL); }
+break;
+case 22:
+{ ssl_expr_yyval.exVal = ssl_expr_make(op_Var, ssl_expr_yyvsp[-1].cpVal, NULL); }
+break;
+case 23:
+{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[0].exVal; }
+break;
+case 24:
+{
+ regex_t *regex;
+ if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal,
+ REG_EXTENDED|REG_NOSUB)) == NULL) {
+ ssl_expr_error = "Failed to compile regular expression";
+ YYERROR;
+ regex = NULL;
+ }
+ ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL);
+ }
+break;
+case 25:
+{
+ regex_t *regex;
+ if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal,
+ REG_EXTENDED|REG_NOSUB|REG_ICASE)) == NULL) {
+ ssl_expr_error = "Failed to compile regular expression";
+ YYERROR;
+ regex = NULL;
+ }
+ ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL);
+ }
+break;
+case 26:
+{
+ ssl_expr *args = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[-1].cpVal, NULL);
+ ssl_expr_yyval.exVal = ssl_expr_make(op_Func, "file", args);
+ }
+break;
+ }
+ ssl_expr_yyssp -= ssl_expr_yym;
+ ssl_expr_yystate = *ssl_expr_yyssp;
+ ssl_expr_yyvsp -= ssl_expr_yym;
+ ssl_expr_yym = ssl_expr_yylhs[ssl_expr_yyn];
+ if (ssl_expr_yystate == 0 && ssl_expr_yym == 0)
+ {
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ ssl_expr_yystate = YYFINAL;
+ *++ssl_expr_yyssp = YYFINAL;
+ *++ssl_expr_yyvsp = ssl_expr_yyval;
+ if (ssl_expr_yychar < 0)
+ {
+ if ((ssl_expr_yychar = ssl_expr_yylex()) < 0) ssl_expr_yychar = 0;
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ {
+ ssl_expr_yys = 0;
+ if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
+ if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, ssl_expr_yychar, ssl_expr_yys);
+ }
+#endif
+ }
+ if (ssl_expr_yychar == 0) goto ssl_expr_yyaccept;
+ goto ssl_expr_yyloop;
+ }
+ if ((ssl_expr_yyn = ssl_expr_yygindex[ssl_expr_yym]) && (ssl_expr_yyn += ssl_expr_yystate) >= 0 &&
+ ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yystate)
+ ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
+ else
+ ssl_expr_yystate = ssl_expr_yydgoto[ssl_expr_yym];
+#if YYDEBUG
+ if (ssl_expr_yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *ssl_expr_yyssp, ssl_expr_yystate);
+#endif
+ if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
+ {
+ goto ssl_expr_yyoverflow;
+ }
+ *++ssl_expr_yyssp = ssl_expr_yystate;
+ *++ssl_expr_yyvsp = ssl_expr_yyval;
+ goto ssl_expr_yyloop;
+ssl_expr_yyoverflow:
+ ssl_expr_yyerror("yacc stack overflow");
+ssl_expr_yyabort:
+ return (1);
+ssl_expr_yyaccept:
+ return (0);
+}
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.h b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.h
new file mode 100644
index 00000000000..64413c2b324
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.h
@@ -0,0 +1,25 @@
+#define T_TRUE 257
+#define T_FALSE 258
+#define T_DIGIT 259
+#define T_ID 260
+#define T_STRING 261
+#define T_REGEX 262
+#define T_REGEX_I 263
+#define T_FUNC_FILE 264
+#define T_OP_EQ 265
+#define T_OP_NE 266
+#define T_OP_LT 267
+#define T_OP_LE 268
+#define T_OP_GT 269
+#define T_OP_GE 270
+#define T_OP_REG 271
+#define T_OP_NRE 272
+#define T_OP_IN 273
+#define T_OP_OR 274
+#define T_OP_AND 275
+#define T_OP_NOT 276
+typedef union {
+ char *cpVal;
+ ssl_expr *exVal;
+} YYSTYPE;
+extern YYSTYPE ssl_expr_yylval;
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y
new file mode 100644
index 00000000000..cc4590ad824
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y
@@ -0,0 +1,186 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr_parse.y
+** Expression LR(1) Parser
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+ /* ``What you see is all you get.''
+ -- Brian Kernighan */
+
+/* _________________________________________________________________
+**
+** Expression Parser
+** _________________________________________________________________
+*/
+
+%{
+#include "mod_ssl.h"
+%}
+
+%union {
+ char *cpVal;
+ ssl_expr *exVal;
+}
+
+%token T_TRUE
+%token T_FALSE
+
+%token <cpVal> T_DIGIT
+%token <cpVal> T_ID
+%token <cpVal> T_STRING
+%token <cpVal> T_REGEX
+%token <cpVal> T_REGEX_I
+
+%token T_FUNC_FILE
+
+%token T_OP_EQ
+%token T_OP_NE
+%token T_OP_LT
+%token T_OP_LE
+%token T_OP_GT
+%token T_OP_GE
+%token T_OP_REG
+%token T_OP_NRE
+%token T_OP_IN
+
+%token T_OP_OR
+%token T_OP_AND
+%token T_OP_NOT
+
+%left T_OP_OR
+%left T_OP_AND
+%left T_OP_NOT
+
+%type <exVal> expr
+%type <exVal> comparison
+%type <exVal> funccall
+%type <exVal> regex
+%type <exVal> words
+%type <exVal> word
+
+%%
+
+root : expr { ssl_expr_info.expr = $1; }
+ ;
+
+expr : T_TRUE { $$ = ssl_expr_make(op_True, NULL, NULL); }
+ | T_FALSE { $$ = ssl_expr_make(op_False, NULL, NULL); }
+ | T_OP_NOT expr { $$ = ssl_expr_make(op_Not, $2, NULL); }
+ | expr T_OP_OR expr { $$ = ssl_expr_make(op_Or, $1, $3); }
+ | expr T_OP_AND expr { $$ = ssl_expr_make(op_And, $1, $3); }
+ | comparison { $$ = ssl_expr_make(op_Comp, $1, NULL); }
+ | '(' expr ')' { $$ = $2; }
+ ;
+
+comparison: word T_OP_EQ word { $$ = ssl_expr_make(op_EQ, $1, $3); }
+ | word T_OP_NE word { $$ = ssl_expr_make(op_NE, $1, $3); }
+ | word T_OP_LT word { $$ = ssl_expr_make(op_LT, $1, $3); }
+ | word T_OP_LE word { $$ = ssl_expr_make(op_LE, $1, $3); }
+ | word T_OP_GT word { $$ = ssl_expr_make(op_GT, $1, $3); }
+ | word T_OP_GE word { $$ = ssl_expr_make(op_GE, $1, $3); }
+ | word T_OP_IN '{' words '}' { $$ = ssl_expr_make(op_IN, $1, $4); }
+ | word T_OP_REG regex { $$ = ssl_expr_make(op_REG, $1, $3); }
+ | word T_OP_NRE regex { $$ = ssl_expr_make(op_NRE, $1, $3); }
+ ;
+
+words : word { $$ = ssl_expr_make(op_ListElement, $1, NULL); }
+ | words ',' word { $$ = ssl_expr_make(op_ListElement, $3, $1); }
+ ;
+
+word : T_DIGIT { $$ = ssl_expr_make(op_Digit, $1, NULL); }
+ | T_STRING { $$ = ssl_expr_make(op_String, $1, NULL); }
+ | '%' '{' T_ID '}' { $$ = ssl_expr_make(op_Var, $3, NULL); }
+ | funccall { $$ = $1; }
+ ;
+
+regex : T_REGEX {
+ regex_t *regex;
+ if ((regex = ap_pregcomp(ssl_expr_info.pool, $1,
+ REG_EXTENDED|REG_NOSUB)) == NULL) {
+ ssl_expr_error = "Failed to compile regular expression";
+ YYERROR;
+ regex = NULL;
+ }
+ $$ = ssl_expr_make(op_Regex, regex, NULL);
+ }
+ | T_REGEX_I {
+ regex_t *regex;
+ if ((regex = ap_pregcomp(ssl_expr_info.pool, $1,
+ REG_EXTENDED|REG_NOSUB|REG_ICASE)) == NULL) {
+ ssl_expr_error = "Failed to compile regular expression";
+ YYERROR;
+ regex = NULL;
+ }
+ $$ = ssl_expr_make(op_Regex, regex, NULL);
+ }
+ ;
+
+funccall : T_FUNC_FILE '(' T_STRING ')' {
+ ssl_expr *args = ssl_expr_make(op_ListElement, $3, NULL);
+ $$ = ssl_expr_make(op_Func, "file", args);
+ }
+ ;
+
+%%
+
+int yyerror(char *s)
+{
+ ssl_expr_error = s;
+ return 2;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c
new file mode 100644
index 00000000000..b8d8b40ace6
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c
@@ -0,0 +1,2002 @@
+#define yy_create_buffer ssl_expr_yy_create_buffer
+#define yy_delete_buffer ssl_expr_yy_delete_buffer
+#define yy_scan_buffer ssl_expr_yy_scan_buffer
+#define yy_scan_string ssl_expr_yy_scan_string
+#define yy_scan_bytes ssl_expr_yy_scan_bytes
+#define yy_flex_debug ssl_expr_yy_flex_debug
+#define yy_init_buffer ssl_expr_yy_init_buffer
+#define yy_flush_buffer ssl_expr_yy_flush_buffer
+#define yy_load_buffer_state ssl_expr_yy_load_buffer_state
+#define yy_switch_to_buffer ssl_expr_yy_switch_to_buffer
+#define yyin ssl_expr_yyin
+#define yyleng ssl_expr_yyleng
+#define yylex ssl_expr_yylex
+#define yyout ssl_expr_yyout
+#define yyrestart ssl_expr_yyrestart
+#define yytext ssl_expr_yytext
+
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 46
+#define YY_END_OF_BUFFER 47
+static yyconst short int yy_accept[86] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 47, 45,
+ 1, 38, 2, 45, 43, 24, 45, 28, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 45,
+ 13, 4, 3, 14, 16, 18, 17, 1, 22, 32,
+ 34, 43, 26, 20, 31, 30, 44, 44, 19, 44,
+ 44, 29, 27, 39, 25, 23, 15, 15, 21, 44,
+ 35, 44, 36, 13, 12, 5, 6, 10, 11, 7,
+ 8, 9, 33, 44, 44, 37, 44, 5, 6, 44,
+ 40, 41, 5, 42, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 1, 1, 1, 6, 1, 1,
+ 1, 1, 1, 1, 7, 1, 1, 8, 8, 8,
+ 8, 8, 8, 8, 8, 9, 9, 1, 1, 10,
+ 11, 12, 1, 1, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 1, 14, 1, 1, 7, 1, 15, 16, 13, 17,
+
+ 18, 19, 20, 13, 21, 13, 13, 22, 23, 24,
+ 25, 13, 26, 27, 28, 29, 30, 13, 13, 13,
+ 13, 13, 1, 31, 1, 32, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[33] =
+ { 0,
+ 1, 1, 2, 1, 3, 1, 4, 4, 4, 1,
+ 1, 1, 4, 3, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1
+ } ;
+
+static yyconst short int yy_base[93] =
+ { 0,
+ 0, 0, 30, 31, 0, 0, 82, 81, 101, 142,
+ 35, 28, 142, 94, 32, 88, 31, 87, 0, 69,
+ 66, 28, 28, 67, 29, 63, 30, 63, 62, 57,
+ 0, 142, 142, 88, 142, 142, 142, 48, 142, 142,
+ 142, 44, 142, 142, 142, 142, 0, 70, 0, 64,
+ 63, 0, 0, 0, 0, 0, 142, 0, 0, 55,
+ 0, 46, 142, 0, 142, 53, 62, 142, 142, 142,
+ 142, 142, 0, 44, 48, 0, 41, 70, 72, 38,
+ 0, 0, 74, 0, 142, 117, 121, 125, 50, 129,
+ 133, 137
+
+ } ;
+
+static yyconst short int yy_def[93] =
+ { 0,
+ 85, 1, 86, 86, 87, 87, 88, 88, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 89, 89,
+ 89, 89, 89, 89, 89, 90, 89, 89, 89, 85,
+ 91, 85, 85, 92, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 89, 89, 89, 89,
+ 89, 89, 89, 89, 89, 89, 85, 89, 89, 89,
+ 89, 89, 85, 91, 85, 85, 85, 85, 85, 85,
+ 85, 85, 89, 89, 89, 89, 89, 85, 85, 89,
+ 89, 89, 85, 89, 0, 85, 85, 85, 85, 85,
+ 85, 85
+
+ } ;
+
+static yyconst short int yy_nxt[175] =
+ { 0,
+ 10, 11, 11, 12, 13, 14, 10, 15, 15, 16,
+ 17, 18, 19, 10, 20, 19, 19, 21, 22, 23,
+ 24, 25, 26, 27, 28, 19, 19, 19, 29, 19,
+ 30, 10, 32, 32, 33, 33, 38, 38, 39, 42,
+ 42, 44, 50, 34, 34, 52, 55, 59, 51, 38,
+ 38, 42, 42, 47, 60, 84, 53, 56, 82, 40,
+ 78, 79, 45, 57, 57, 81, 57, 57, 57, 79,
+ 79, 80, 57, 57, 57, 77, 57, 83, 79, 79,
+ 79, 79, 79, 76, 75, 74, 73, 63, 62, 61,
+ 54, 49, 48, 57, 57, 66, 67, 46, 43, 41,
+
+ 85, 37, 37, 68, 85, 85, 69, 85, 85, 85,
+ 85, 70, 85, 85, 71, 85, 72, 31, 31, 31,
+ 31, 35, 35, 35, 35, 36, 36, 36, 36, 58,
+ 85, 58, 58, 64, 85, 85, 64, 65, 65, 65,
+ 65, 9, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85
+ } ;
+
+static yyconst short int yy_chk[175] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 4, 3, 4, 11, 11, 12, 15,
+ 15, 17, 22, 3, 4, 23, 25, 27, 22, 38,
+ 38, 42, 42, 89, 27, 80, 23, 25, 77, 12,
+ 66, 66, 17, 26, 26, 75, 26, 26, 26, 67,
+ 67, 74, 26, 26, 26, 62, 26, 78, 78, 79,
+ 79, 83, 83, 60, 51, 50, 48, 30, 29, 28,
+ 24, 21, 20, 26, 26, 34, 34, 18, 16, 14,
+
+ 9, 8, 7, 34, 0, 0, 34, 0, 0, 0,
+ 0, 34, 0, 0, 34, 0, 34, 86, 86, 86,
+ 86, 87, 87, 87, 87, 88, 88, 88, 88, 90,
+ 0, 90, 90, 91, 0, 0, 91, 92, 92, 92,
+ 92, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "ssl_expr_scan.l"
+#define INITIAL 0
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr_scan.l
+** Expression Scanner
+*/
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+/* ``Killing for peace is
+like fucking for virginity.''
+-- Unknown */
+/* _________________________________________________________________
+**
+** Expression Scanner
+** _________________________________________________________________
+*/
+#line 73 "ssl_expr_scan.l"
+#include "mod_ssl.h"
+
+#include "ssl_expr_parse.h"
+
+#define YY_NO_UNPUT 1
+int yyinput(char *buf, int max_size);
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ (result = yyinput(buf, max_size))
+
+#define MAX_STR_LEN 2048
+/* %option stack */
+#define YY_NEVER_INTERACTIVE 1
+#define str 1
+
+#define regex 2
+#define regex_flags 3
+
+#line 537 "lex.ssl_expr_yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 94 "ssl_expr_scan.l"
+
+
+ char caStr[MAX_STR_LEN];
+ char *cpStr = NULL;
+ char caRegex[MAX_STR_LEN];
+ char *cpRegex = NULL;
+ char cRegexDel = NUL;
+
+ /*
+ * Whitespaces
+ */
+#line 700 "lex.ssl_expr_yy.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 86 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 85 );
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 105 "ssl_expr_scan.l"
+{
+ /* NOP */
+}
+ YY_BREAK
+/*
+ * C-style strings ("...")
+ */
+case 2:
+YY_RULE_SETUP
+#line 112 "ssl_expr_scan.l"
+{
+ cpStr = caStr;
+ BEGIN(str);
+}
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 116 "ssl_expr_scan.l"
+{
+ BEGIN(INITIAL);
+ *cpStr = NUL;
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caStr);
+ return T_STRING;
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 122 "ssl_expr_scan.l"
+{
+ yyerror("Unterminated string");
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 125 "ssl_expr_scan.l"
+{
+ int result;
+
+ (void)sscanf(yytext+1, "%o", &result);
+ if (result > 0xff)
+ yyerror("Escape sequence out of bound");
+ else
+ *cpStr++ = result;
+}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 134 "ssl_expr_scan.l"
+{
+ yyerror("Bad escape sequence");
+}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 137 "ssl_expr_scan.l"
+{ *cpStr++ = '\n'; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 138 "ssl_expr_scan.l"
+{ *cpStr++ = '\r'; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 139 "ssl_expr_scan.l"
+{ *cpStr++ = '\t'; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 140 "ssl_expr_scan.l"
+{ *cpStr++ = '\b'; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 141 "ssl_expr_scan.l"
+{ *cpStr++ = '\f'; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 142 "ssl_expr_scan.l"
+{
+ *cpStr++ = yytext[1];
+}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 145 "ssl_expr_scan.l"
+{
+ char *cp = yytext;
+ while (*cp != NUL)
+ *cpStr++ = *cp++;
+}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 150 "ssl_expr_scan.l"
+{
+ *cpStr++ = yytext[1];
+}
+ YY_BREAK
+/*
+ * Regular Expression
+ */
+case 15:
+YY_RULE_SETUP
+#line 157 "ssl_expr_scan.l"
+{
+ cRegexDel = yytext[1];
+ cpRegex = caRegex;
+ BEGIN(regex);
+}
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 162 "ssl_expr_scan.l"
+{
+ if (yytext[0] == cRegexDel) {
+ *cpRegex = NUL;
+ BEGIN(regex_flags);
+ }
+ else {
+ *cpRegex++ = yytext[0];
+ }
+}
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 171 "ssl_expr_scan.l"
+{
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ BEGIN(INITIAL);
+ return T_REGEX_I;
+}
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 176 "ssl_expr_scan.l"
+{
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ yyless(0);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+ YY_BREAK
+case YY_STATE_EOF(regex_flags):
+#line 182 "ssl_expr_scan.l"
+{
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+ YY_BREAK
+/*
+ * Operators
+ */
+case 19:
+YY_RULE_SETUP
+#line 191 "ssl_expr_scan.l"
+{ return T_OP_EQ; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 192 "ssl_expr_scan.l"
+{ return T_OP_EQ; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 193 "ssl_expr_scan.l"
+{ return T_OP_NE; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 194 "ssl_expr_scan.l"
+{ return T_OP_NE; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 195 "ssl_expr_scan.l"
+{ return T_OP_LT; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 196 "ssl_expr_scan.l"
+{ return T_OP_LT; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 197 "ssl_expr_scan.l"
+{ return T_OP_LE; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 198 "ssl_expr_scan.l"
+{ return T_OP_LE; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 199 "ssl_expr_scan.l"
+{ return T_OP_GT; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 200 "ssl_expr_scan.l"
+{ return T_OP_GT; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 201 "ssl_expr_scan.l"
+{ return T_OP_GE; }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 202 "ssl_expr_scan.l"
+{ return T_OP_GE; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 203 "ssl_expr_scan.l"
+{ return T_OP_REG; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 204 "ssl_expr_scan.l"
+{ return T_OP_NRE; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 205 "ssl_expr_scan.l"
+{ return T_OP_AND; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 206 "ssl_expr_scan.l"
+{ return T_OP_AND; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 207 "ssl_expr_scan.l"
+{ return T_OP_OR; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 208 "ssl_expr_scan.l"
+{ return T_OP_OR; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 209 "ssl_expr_scan.l"
+{ return T_OP_NOT; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 210 "ssl_expr_scan.l"
+{ return T_OP_NOT; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 211 "ssl_expr_scan.l"
+{ return T_OP_IN; }
+ YY_BREAK
+/*
+ * Functions
+ */
+case 40:
+YY_RULE_SETUP
+#line 216 "ssl_expr_scan.l"
+{ return T_FUNC_FILE; }
+ YY_BREAK
+/*
+ * Specials
+ */
+case 41:
+YY_RULE_SETUP
+#line 221 "ssl_expr_scan.l"
+{ return T_TRUE; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 222 "ssl_expr_scan.l"
+{ return T_FALSE; }
+ YY_BREAK
+/*
+ * Digits
+ */
+case 43:
+YY_RULE_SETUP
+#line 227 "ssl_expr_scan.l"
+{
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext);
+ return T_DIGIT;
+}
+ YY_BREAK
+/*
+ * Identifiers
+ */
+case 44:
+YY_RULE_SETUP
+#line 235 "ssl_expr_scan.l"
+{
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext);
+ return T_ID;
+}
+ YY_BREAK
+/*
+ * Anything else is returned as is...
+ */
+case 45:
+YY_RULE_SETUP
+#line 243 "ssl_expr_scan.l"
+{
+ return yytext[0];
+}
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 247 "ssl_expr_scan.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 1100 "lex.ssl_expr_yy.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(str):
+case YY_STATE_EOF(regex):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 86 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 86 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 85);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 247 "ssl_expr_scan.l"
+
+
+int yyinput(char *buf, int max_size)
+{
+ int n;
+
+ if ((n = MIN(max_size, ssl_expr_info.inputbuf
+ + ssl_expr_info.inputlen
+ - ssl_expr_info.inputptr)) <= 0)
+ return YY_NULL;
+ memcpy(buf, ssl_expr_info.inputptr, n);
+ ssl_expr_info.inputptr += n;
+ return n;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l
new file mode 100644
index 00000000000..a6352724412
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l
@@ -0,0 +1,261 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_expr_scan.l
+** Expression Scanner
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+ /* ``Killing for peace is
+ like fucking for virginity.''
+ -- Unknown */
+
+/* _________________________________________________________________
+**
+** Expression Scanner
+** _________________________________________________________________
+*/
+
+%{
+#include "mod_ssl.h"
+
+#include "ssl_expr_parse.h"
+
+#define YY_NO_UNPUT 1
+int yyinput(char *buf, int max_size);
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ (result = yyinput(buf, max_size))
+
+#define MAX_STR_LEN 2048
+%}
+
+%pointer
+/* %option stack */
+%option never-interactive
+%option noyywrap
+%x str
+%x regex regex_flags
+
+%%
+
+ char caStr[MAX_STR_LEN];
+ char *cpStr = NULL;
+ char caRegex[MAX_STR_LEN];
+ char *cpRegex = NULL;
+ char cRegexDel = NUL;
+
+ /*
+ * Whitespaces
+ */
+[ \t\n]+ {
+ /* NOP */
+}
+
+ /*
+ * C-style strings ("...")
+ */
+\" {
+ cpStr = caStr;
+ BEGIN(str);
+}
+<str>\" {
+ BEGIN(INITIAL);
+ *cpStr = NUL;
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caStr);
+ return T_STRING;
+}
+<str>\n {
+ yyerror("Unterminated string");
+}
+<str>\\[0-7]{1,3} {
+ int result;
+
+ (void)sscanf(yytext+1, "%o", &result);
+ if (result > 0xff)
+ yyerror("Escape sequence out of bound");
+ else
+ *cpStr++ = result;
+}
+<str>\\[0-9]+ {
+ yyerror("Bad escape sequence");
+}
+<str>\\n { *cpStr++ = '\n'; }
+<str>\\r { *cpStr++ = '\r'; }
+<str>\\t { *cpStr++ = '\t'; }
+<str>\\b { *cpStr++ = '\b'; }
+<str>\\f { *cpStr++ = '\f'; }
+<str>\\(.|\n) {
+ *cpStr++ = yytext[1];
+}
+<str>[^\\\n\"]+ {
+ char *cp = yytext;
+ while (*cp != NUL)
+ *cpStr++ = *cp++;
+}
+<str>. {
+ *cpStr++ = yytext[1];
+}
+
+ /*
+ * Regular Expression
+ */
+"m". {
+ cRegexDel = yytext[1];
+ cpRegex = caRegex;
+ BEGIN(regex);
+}
+<regex>.|\n {
+ if (yytext[0] == cRegexDel) {
+ *cpRegex = NUL;
+ BEGIN(regex_flags);
+ }
+ else {
+ *cpRegex++ = yytext[0];
+ }
+}
+<regex_flags>i {
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ BEGIN(INITIAL);
+ return T_REGEX_I;
+}
+<regex_flags>.|\n {
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ yyless(0);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+<regex_flags><<EOF>> {
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex);
+ BEGIN(INITIAL);
+ return T_REGEX;
+}
+
+ /*
+ * Operators
+ */
+"eq" { return T_OP_EQ; }
+"==" { return T_OP_EQ; }
+"ne" { return T_OP_NE; }
+"!=" { return T_OP_NE; }
+"lt" { return T_OP_LT; }
+"<" { return T_OP_LT; }
+"le" { return T_OP_LE; }
+"<=" { return T_OP_LE; }
+"gt" { return T_OP_GT; }
+">" { return T_OP_GT; }
+"ge" { return T_OP_GE; }
+">=" { return T_OP_GE; }
+"=~" { return T_OP_REG; }
+"!~" { return T_OP_NRE; }
+"and" { return T_OP_AND; }
+"&&" { return T_OP_AND; }
+"or" { return T_OP_OR; }
+"||" { return T_OP_OR; }
+"not" { return T_OP_NOT; }
+"!" { return T_OP_NOT; }
+"in" { return T_OP_IN; }
+
+ /*
+ * Functions
+ */
+"file" { return T_FUNC_FILE; }
+
+ /*
+ * Specials
+ */
+"true" { return T_TRUE; }
+"false" { return T_FALSE; }
+
+ /*
+ * Digits
+ */
+[0-9]+ {
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext);
+ return T_DIGIT;
+}
+
+ /*
+ * Identifiers
+ */
+[a-zA-Z][a-zA-Z0-9_-]* {
+ yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext);
+ return T_ID;
+}
+
+ /*
+ * Anything else is returned as is...
+ */
+.|\n {
+ return yytext[0];
+}
+
+%%
+
+int yyinput(char *buf, int max_size)
+{
+ int n;
+
+ if ((n = MIN(max_size, ssl_expr_info.inputbuf
+ + ssl_expr_info.inputlen
+ - ssl_expr_info.inputptr)) <= 0)
+ return YY_NULL;
+ memcpy(buf, ssl_expr_info.inputptr, n);
+ ssl_expr_info.inputptr += n;
+ return n;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util.c b/usr.sbin/httpd/src/modules/ssl/ssl_util.c
new file mode 100644
index 00000000000..dd49b134be0
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_util.c
@@ -0,0 +1,348 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_util.c
+** Utility Functions
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/* ====================================================================
+ * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * 4. The name "Apache-SSL Server" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by Ben Laurie
+ * for use in the Apache-SSL HTTP server project."
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN LAURIE OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+ /* ``Every day of my life
+ I am forced to add another
+ name to the list of people
+ who piss me off!''
+ -- Calvin */
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Utility Functions
+** _________________________________________________________________
+*/
+
+char *ssl_util_vhostid(pool *p, server_rec *s)
+{
+ char *id;
+ SSLSrvConfigRec *sc;
+ char *host;
+ int port;
+
+ host = s->server_hostname;
+ if (s->port != 0)
+ port = s->port;
+ else {
+ sc = mySrvConfig(s);
+ if (sc->bEnabled)
+ port = DEFAULT_HTTPS_PORT;
+ else
+ port = DEFAULT_HTTP_PORT;
+ }
+ id = ap_psprintf(p, "%s:%d", host, port);
+ return id;
+}
+
+void ssl_util_strupper(char *s)
+{
+ for (; *s; ++s)
+ *s = toupper(*s);
+ return;
+}
+
+static const char ssl_util_uuencode_six2pr[64+1] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+void ssl_util_uuencode(char *szTo, const char *szFrom, BOOL bPad)
+{
+ ssl_util_uuencode_binary((unsigned char *)szTo,
+ (const unsigned char *)szFrom,
+ strlen(szFrom), bPad);
+}
+
+void ssl_util_uuencode_binary(
+ unsigned char *szTo, const unsigned char *szFrom, int nLength, BOOL bPad)
+{
+ const unsigned char *s;
+ int nPad = 0;
+
+ for (s = szFrom; nLength > 0; s += 3) {
+ *szTo++ = ssl_util_uuencode_six2pr[s[0] >> 2];
+ *szTo++ = ssl_util_uuencode_six2pr[(s[0] << 4 | s[1] >> 4) & 0x3f];
+ if (--nLength == 0) {
+ nPad = 2;
+ break;
+ }
+ *szTo++ = ssl_util_uuencode_six2pr[(s[1] << 2 | s[2] >> 6) & 0x3f];
+ if (--nLength == 0) {
+ nPad = 1;
+ break;
+ }
+ *szTo++ = ssl_util_uuencode_six2pr[s[2] & 0x3f];
+ --nLength;
+ }
+ while(bPad && nPad--)
+ *szTo++ = NUL;
+ *szTo = NUL;
+ return;
+}
+
+FILE *ssl_util_ppopen(server_rec *s, pool *p, char *cmd)
+{
+ FILE *fpout;
+ int rc;
+
+ fpout = NULL;
+ rc = ap_spawn_child(p, ssl_util_ppopen_child,
+ (void *)cmd, kill_after_timeout,
+ NULL, &fpout, NULL);
+ if (rc == 0 || fpout == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, s,
+ "ssl_util_ppopen: could not run: %s", cmd);
+ return NULL;
+ }
+ return (fpout);
+}
+
+int ssl_util_ppopen_child(void *cmd, child_info *pinfo)
+{
+ int child_pid = 1;
+
+ ap_cleanup_for_exec();
+#ifdef SIGHUP
+ signal(SIGHUP, SIG_IGN);
+#endif
+#if defined(__EMX__)
+ execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
+#else
+ execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
+#endif
+ return (child_pid);
+}
+
+void ssl_util_ppclose(server_rec *s, pool *p, FILE *fp)
+{
+ ap_pfclose(p, fp);
+ return;
+}
+
+/*
+ * Run a filter program and read the first line of its stdout output
+ */
+char *ssl_util_readfilter(server_rec *s, pool *p, char *cmd)
+{
+ static char buf[MAX_STRING_LEN];
+ FILE *fp;
+ char c;
+ int k;
+
+ if ((fp = ssl_util_ppopen(s, p, cmd)) == NULL)
+ return NULL;
+ for (k = 0; read(fileno(fp), &c, 1) == 1
+ && (k < MAX_STRING_LEN-1) ; ) {
+ if (c == '\n')
+ break;
+ buf[k++] = c;
+ }
+ buf[k] = NUL;
+ ssl_util_ppclose(s, p, fp);
+
+ return buf;
+}
+
+BOOL ssl_util_path_check(ssl_pathcheck_t pcm, char *path)
+{
+ struct stat sb;
+
+ if (path == NULL)
+ return FALSE;
+ if (pcm & SSL_PCM_EXISTS && stat(path, &sb) != 0)
+ return FALSE;
+ if (pcm & SSL_PCM_ISREG && !S_ISREG(sb.st_mode))
+ return FALSE;
+ if (pcm & SSL_PCM_ISDIR && !S_ISDIR(sb.st_mode))
+ return FALSE;
+ if (pcm & SSL_PCM_ISNONZERO && sb.st_mode <= 0)
+ return FALSE;
+ return TRUE;
+}
+
+char *ssl_util_ptxtsub(
+ pool *p, const char *cpLine, const char *cpMatch, char *cpSubst)
+{
+#define MAX_PTXTSUB 100
+ char *cppMatch[MAX_PTXTSUB];
+ char *cpResult;
+ int nResult;
+ int nLine;
+ int nSubst;
+ int nMatch;
+ char *cpI;
+ char *cpO;
+ char *cp;
+ int i;
+
+ /*
+ * Pass 1: find substitution locations and calculate sizes
+ */
+ nLine = strlen(cpLine);
+ nMatch = strlen(cpMatch);
+ nSubst = strlen(cpSubst);
+ for (cpI = (char *)cpLine, i = 0, nResult = 0;
+ cpI < cpLine+nLine && i < MAX_PTXTSUB; ) {
+ if ((cp = strstr(cpI, cpMatch)) != NULL) {
+ cppMatch[i++] = cp;
+ nResult += ((cp-cpI)+nSubst);
+ cpI = (cp+nMatch);
+ }
+ else {
+ nResult += strlen(cpI);
+ break;
+ }
+ }
+ cppMatch[i] = NULL;
+ if (i == 0)
+ return NULL;
+
+ /*
+ * Pass 2: allocate memory and assemble result
+ */
+ cpResult = ap_pcalloc(p, nResult+1);
+ for (cpI = (char *)cpLine, cpO = cpResult, i = 0; cppMatch[i] != NULL; i++) {
+ ap_cpystrn(cpO, cpI, cppMatch[i]-cpI+1);
+ cpO += (cppMatch[i]-cpI);
+ ap_cpystrn(cpO, cpSubst, nSubst+1);
+ cpO += nSubst;
+ cpI = (cppMatch[i]+nMatch);
+ }
+ ap_cpystrn(cpO, cpI, cpResult+nResult-cpO+1);
+
+ return cpResult;
+}
+
+/* _________________________________________________________________
+**
+** Special Functions for Win32/SSLeay
+** _________________________________________________________________
+*/
+
+#ifdef WIN32
+static HANDLE lock_cs[CRYPTO_NUM_LOCKS];
+
+static void win32_locking_callback(int mode, int type, char* file, int line)
+{
+ if (mode & CRYPTO_LOCK)
+ WaitForSingleObject(lock_cs[type], INFINITE);
+ else
+ ReleaseMutex(lock_cs[type]);
+ return;
+}
+#endif /* WIN32 */
+
+void ssl_util_thread_setup(void)
+{
+#ifdef WIN32
+ int i;
+
+ for (i = 0; i < CRYPTO_NUM_LOCKS; i++)
+ lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
+ CRYPTO_set_locking_callback((void(*)(int, int, char*, int))
+ win32_locking_callback);
+#endif /* WIN32 */
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c
new file mode 100644
index 00000000000..029335f88ba
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c
@@ -0,0 +1,926 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_util_sdbm.c
+** Built-in Simple DBM
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/*
+ * sdbm - ndbm work-alike hashed database library
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
+ * author: oz@nexus.yorku.ca
+ * status: public domain.
+ *
+ * core routines
+ */
+
+#include "mod_ssl.h"
+
+#ifdef SSL_USE_SDBM
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef WIN32
+#include <io.h>
+#include <errno.h>
+#else
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#ifdef __STDC__
+#include <stddef.h>
+#endif
+
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+/*
+ * externals
+ */
+#ifdef sun
+extern int errno;
+#endif
+
+/*
+ * forward
+ */
+static int getdbit proto((DBM *, long));
+static int setdbit proto((DBM *, long));
+static int getpage proto((DBM *, long));
+static datum getnext proto((DBM *));
+static int makroom proto((DBM *, long, int));
+
+/*
+ * useful macros
+ */
+#define bad(x) ((x).dptr == NULL || (x).dsize <= 0)
+#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
+#define ioerr(db) ((db)->flags |= DBM_IOERR)
+
+#define OFF_PAG(off) (long) (off) * PBLKSIZ
+#define OFF_DIR(off) (long) (off) * DBLKSIZ
+
+static long masks[] = {
+ 000000000000, 000000000001, 000000000003, 000000000007,
+ 000000000017, 000000000037, 000000000077, 000000000177,
+ 000000000377, 000000000777, 000000001777, 000000003777,
+ 000000007777, 000000017777, 000000037777, 000000077777,
+ 000000177777, 000000377777, 000000777777, 000001777777,
+ 000003777777, 000007777777, 000017777777, 000037777777,
+ 000077777777, 000177777777, 000377777777, 000777777777,
+ 001777777777, 003777777777, 007777777777, 017777777777
+};
+
+datum nullitem = {NULL, 0};
+
+DBM *
+sdbm_open(file, flags, mode)
+register char *file;
+register int flags;
+register int mode;
+{
+ register DBM *db;
+ register char *dirname;
+ register char *pagname;
+ register int n;
+
+ if (file == NULL || !*file)
+ return errno = EINVAL, (DBM *) NULL;
+/*
+ * need space for two seperate filenames
+ */
+ n = strlen(file) * 2 + strlen(DIRFEXT) + strlen(PAGFEXT) + 2;
+
+ if ((dirname = malloc((unsigned) n)) == NULL)
+ return errno = ENOMEM, (DBM *) NULL;
+/*
+ * build the file names
+ */
+ dirname = strcat(strcpy(dirname, file), DIRFEXT);
+ pagname = strcpy(dirname + strlen(dirname) + 1, file);
+ pagname = strcat(pagname, PAGFEXT);
+
+ db = sdbm_prep(dirname, pagname, flags, mode);
+ free((char *) dirname);
+ return db;
+}
+
+DBM *
+sdbm_prep(dirname, pagname, flags, mode)
+char *dirname;
+char *pagname;
+int flags;
+int mode;
+{
+ register DBM *db;
+ struct stat dstat;
+
+ if ((db = (DBM *) malloc(sizeof(DBM))) == NULL)
+ return errno = ENOMEM, (DBM *) NULL;
+
+ db->flags = 0;
+ db->hmask = 0;
+ db->blkptr = 0;
+ db->keyptr = 0;
+/*
+ * adjust user flags so that WRONLY becomes RDWR,
+ * as required by this package. Also set our internal
+ * flag for RDONLY if needed.
+ */
+ if (flags & O_WRONLY)
+ flags = (flags & ~O_WRONLY) | O_RDWR;
+ else if ((flags & 03) == O_RDONLY)
+ db->flags = DBM_RDONLY;
+#if defined(OS2) || defined(MSDOS) || defined(WIN32)
+ flags |= O_BINARY;
+#endif
+
+/*
+ * open the files in sequence, and stat the dirfile.
+ * If we fail anywhere, undo everything, return NULL.
+ */
+ if ((db->pagf = open(pagname, flags, mode)) > -1) {
+ if ((db->dirf = open(dirname, flags, mode)) > -1) {
+/*
+ * need the dirfile size to establish max bit number.
+ */
+ if (fstat(db->dirf, &dstat) == 0) {
+/*
+ * zero size: either a fresh database, or one with a single,
+ * unsplit data page: dirpage is all zeros.
+ */
+ db->dirbno = (!dstat.st_size) ? 0 : -1;
+ db->pagbno = -1;
+ db->maxbno = dstat.st_size * BYTESIZ;
+
+ (void) memset(db->pagbuf, 0, PBLKSIZ);
+ (void) memset(db->dirbuf, 0, DBLKSIZ);
+ /*
+ * success
+ */
+ return db;
+ }
+ (void) close(db->dirf);
+ }
+ (void) close(db->pagf);
+ }
+ free((char *) db);
+ return (DBM *) NULL;
+}
+
+void
+sdbm_close(db)
+register DBM *db;
+{
+ if (db == NULL)
+ errno = EINVAL;
+ else {
+ (void) close(db->dirf);
+ (void) close(db->pagf);
+ free((char *) db);
+ }
+}
+
+datum
+sdbm_fetch(db, key)
+register DBM *db;
+datum key;
+{
+ if (db == NULL || bad(key))
+ return errno = EINVAL, nullitem;
+
+ if (getpage(db, exhash(key)))
+ return getpair(db->pagbuf, key);
+
+ return ioerr(db), nullitem;
+}
+
+int
+sdbm_delete(db, key)
+register DBM *db;
+datum key;
+{
+ if (db == NULL || bad(key))
+ return errno = EINVAL, -1;
+ if (sdbm_rdonly(db))
+ return errno = EPERM, -1;
+
+ if (getpage(db, exhash(key))) {
+ if (!delpair(db->pagbuf, key))
+ return -1;
+/*
+ * update the page file
+ */
+ if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
+ || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return ioerr(db), -1;
+
+ return 0;
+ }
+
+ return ioerr(db), -1;
+}
+
+int
+sdbm_store(db, key, val, flags)
+register DBM *db;
+datum key;
+datum val;
+int flags;
+{
+ int need;
+ register long hash;
+
+ if (db == NULL || bad(key))
+ return errno = EINVAL, -1;
+ if (sdbm_rdonly(db))
+ return errno = EPERM, -1;
+
+ need = key.dsize + val.dsize;
+/*
+ * is the pair too big (or too small) for this database ??
+ */
+ if (need < 0 || need > PAIRMAX)
+ return errno = EINVAL, -1;
+
+ if (getpage(db, (hash = exhash(key)))) {
+/*
+ * if we need to replace, delete the key/data pair
+ * first. If it is not there, ignore.
+ */
+ if (flags == DBM_REPLACE)
+ (void) delpair(db->pagbuf, key);
+#ifdef SEEDUPS
+ else if (duppair(db->pagbuf, key))
+ return 1;
+#endif
+/*
+ * if we do not have enough room, we have to split.
+ */
+ if (!fitpair(db->pagbuf, need))
+ if (!makroom(db, hash, need))
+ return ioerr(db), -1;
+/*
+ * we have enough room or split is successful. insert the key,
+ * and update the page file.
+ */
+ (void) putpair(db->pagbuf, key, val);
+
+ if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
+ || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return ioerr(db), -1;
+ /*
+ * success
+ */
+ return 0;
+ }
+
+ return ioerr(db), -1;
+}
+
+/*
+ * makroom - make room by splitting the overfull page
+ * this routine will attempt to make room for SPLTMAX times before
+ * giving up.
+ */
+static int
+makroom(db, hash, need)
+register DBM *db;
+long hash;
+int need;
+{
+ long newp;
+ char twin[PBLKSIZ];
+ char *pag = db->pagbuf;
+ char *new = twin;
+ register int smax = SPLTMAX;
+
+ do {
+/*
+ * split the current page
+ */
+ (void) splpage(pag, new, db->hmask + 1);
+/*
+ * address of the new page
+ */
+ newp = (hash & db->hmask) | (db->hmask + 1);
+
+/*
+ * write delay, read avoidence/cache shuffle:
+ * select the page for incoming pair: if key is to go to the new page,
+ * write out the previous one, and copy the new one over, thus making
+ * it the current page. If not, simply write the new page, and we are
+ * still looking at the page of interest. current page is not updated
+ * here, as sdbm_store will do so, after it inserts the incoming pair.
+ */
+ if (hash & (db->hmask + 1)) {
+ if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
+ || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return 0;
+ db->pagbno = newp;
+ (void) memcpy(pag, new, PBLKSIZ);
+ }
+ else if (lseek(db->pagf, OFF_PAG(newp), SEEK_SET) < 0
+ || write(db->pagf, new, PBLKSIZ) < 0)
+ return 0;
+
+ if (!setdbit(db, db->curbit))
+ return 0;
+/*
+ * see if we have enough room now
+ */
+ if (fitpair(pag, need))
+ return 1;
+/*
+ * try again... update curbit and hmask as getpage would have
+ * done. because of our update of the current page, we do not
+ * need to read in anything. BUT we have to write the current
+ * [deferred] page out, as the window of failure is too great.
+ */
+ db->curbit = 2 * db->curbit +
+ ((hash & (db->hmask + 1)) ? 2 : 1);
+ db->hmask |= db->hmask + 1;
+
+ if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
+ || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return 0;
+
+ } while (--smax);
+/*
+ * if we are here, this is real bad news. After SPLTMAX splits,
+ * we still cannot fit the key. say goodnight.
+ */
+#ifdef BADMESS
+ (void) write(2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44);
+#endif
+ return 0;
+
+}
+
+/*
+ * the following two routines will break if
+ * deletions aren't taken into account. (ndbm bug)
+ */
+datum
+sdbm_firstkey(db)
+register DBM *db;
+{
+ if (db == NULL)
+ return errno = EINVAL, nullitem;
+/*
+ * start at page 0
+ */
+ if (lseek(db->pagf, OFF_PAG(0), SEEK_SET) < 0
+ || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return ioerr(db), nullitem;
+ db->pagbno = 0;
+ db->blkptr = 0;
+ db->keyptr = 0;
+
+ return getnext(db);
+}
+
+datum
+sdbm_nextkey(db)
+register DBM *db;
+{
+ if (db == NULL)
+ return errno = EINVAL, nullitem;
+ return getnext(db);
+}
+
+/*
+ * all important binary trie traversal
+ */
+static int
+getpage(db, hash)
+register DBM *db;
+register long hash;
+{
+ register int hbit;
+ register long dbit;
+ register long pagb;
+
+ dbit = 0;
+ hbit = 0;
+ while (dbit < db->maxbno && getdbit(db, dbit))
+ dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
+
+ debug(("dbit: %d...", dbit));
+
+ db->curbit = dbit;
+ db->hmask = masks[hbit];
+
+ pagb = hash & db->hmask;
+/*
+ * see if the block we need is already in memory.
+ * note: this lookaside cache has about 10% hit rate.
+ */
+ if (pagb != db->pagbno) {
+/*
+ * note: here, we assume a "hole" is read as 0s.
+ * if not, must zero pagbuf first.
+ */
+ if (lseek(db->pagf, OFF_PAG(pagb), SEEK_SET) < 0
+ || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
+ return 0;
+ if (!chkpage(db->pagbuf))
+ return 0;
+ db->pagbno = pagb;
+
+ debug(("pag read: %d\n", pagb));
+ }
+ return 1;
+}
+
+static int
+getdbit(db, dbit)
+register DBM *db;
+register long dbit;
+{
+ register long c;
+ register long dirb;
+
+ c = dbit / BYTESIZ;
+ dirb = c / DBLKSIZ;
+
+ if (dirb != db->dirbno) {
+ if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
+ || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
+ return 0;
+ db->dirbno = dirb;
+
+ debug(("dir read: %d\n", dirb));
+ }
+
+ return db->dirbuf[c % DBLKSIZ] & (1 << dbit % BYTESIZ);
+}
+
+static int
+setdbit(db, dbit)
+register DBM *db;
+register long dbit;
+{
+ register long c;
+ register long dirb;
+
+ c = dbit / BYTESIZ;
+ dirb = c / DBLKSIZ;
+
+ if (dirb != db->dirbno) {
+ if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
+ || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
+ return 0;
+ db->dirbno = dirb;
+
+ debug(("dir read: %d\n", dirb));
+ }
+
+ db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
+
+ if (dbit >= db->maxbno)
+ db->maxbno += DBLKSIZ * BYTESIZ;
+
+ if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
+ || write(db->dirf, db->dirbuf, DBLKSIZ) < 0)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * getnext - get the next key in the page, and if done with
+ * the page, try the next page in sequence
+ */
+static datum
+getnext(db)
+register DBM *db;
+{
+ datum key;
+
+ for (;;) {
+ db->keyptr++;
+ key = getnkey(db->pagbuf, db->keyptr);
+ if (key.dptr != NULL)
+ return key;
+/*
+ * we either run out, or there is nothing on this page..
+ * try the next one... If we lost our position on the
+ * file, we will have to seek.
+ */
+ db->keyptr = 0;
+ if (db->pagbno != db->blkptr++)
+ if (lseek(db->pagf, OFF_PAG(db->blkptr), SEEK_SET) < 0)
+ break;
+ db->pagbno = db->blkptr;
+ if (read(db->pagf, db->pagbuf, PBLKSIZ) <= 0)
+ break;
+ if (!chkpage(db->pagbuf))
+ break;
+ }
+
+ return ioerr(db), nullitem;
+}
+
+/* ************************* */
+
+/*
+ * sdbm - ndbm work-alike hashed database library
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
+ * author: oz@nexus.yorku.ca
+ * status: public domain. keep it that way.
+ *
+ * hashing routine
+ */
+
+/*
+ * polynomial conversion ignoring overflows
+ * [this seems to work remarkably well, in fact better
+ * then the ndbm hash function. Replace at your own risk]
+ * use: 65599 nice.
+ * 65587 even better.
+ */
+long
+sdbm_hash(str, len)
+register char *str;
+register int len;
+{
+ register unsigned long n = 0;
+
+#ifdef DUFF
+#define HASHC n = *str++ + 65599 * n
+ if (len > 0) {
+ register int loop = (len + 8 - 1) >> 3;
+
+ switch(len & (8 - 1)) {
+ case 0: do {
+ HASHC; case 7: HASHC;
+ case 6: HASHC; case 5: HASHC;
+ case 4: HASHC; case 3: HASHC;
+ case 2: HASHC; case 1: HASHC;
+ } while (--loop);
+ }
+
+ }
+#else
+ while (len--)
+ n = *str++ + 65599 * n;
+#endif
+ return n;
+}
+
+/* ************************* */
+
+/*
+ * sdbm - ndbm work-alike hashed database library
+ * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
+ * author: oz@nexus.yorku.ca
+ * status: public domain.
+ *
+ * page-level routines
+ */
+
+#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
+
+/*
+ * forward
+ */
+static int seepair proto((char *, int, char *, int));
+
+/*
+ * page format:
+ * +------------------------------+
+ * ino | n | keyoff | datoff | keyoff |
+ * +------------+--------+--------+
+ * | datoff | - - - ----> |
+ * +--------+---------------------+
+ * | F R E E A R E A |
+ * +--------------+---------------+
+ * | <---- - - - | data |
+ * +--------+-----+----+----------+
+ * | key | data | key |
+ * +--------+----------+----------+
+ *
+ * calculating the offsets for free area: if the number
+ * of entries (ino[0]) is zero, the offset to the END of
+ * the free area is the block size. Otherwise, it is the
+ * nth (ino[ino[0]]) entry's offset.
+ */
+
+int
+fitpair(pag, need)
+char *pag;
+int need;
+{
+ register int n;
+ register int off;
+ register int avail;
+ register short *ino = (short *) pag;
+
+ off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
+ avail = off - (n + 1) * sizeof(short);
+ need += 2 * sizeof(short);
+
+ debug(("free %d need %d\n", avail, need));
+
+ return need <= avail;
+}
+
+void
+putpair(pag, key, val)
+char *pag;
+datum key;
+datum val;
+{
+ register int n;
+ register int off;
+ register short *ino = (short *) pag;
+
+ off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
+/*
+ * enter the key first
+ */
+ off -= key.dsize;
+ (void) memcpy(pag + off, key.dptr, key.dsize);
+ ino[n + 1] = off;
+/*
+ * now the data
+ */
+ off -= val.dsize;
+ (void) memcpy(pag + off, val.dptr, val.dsize);
+ ino[n + 2] = off;
+/*
+ * adjust item count
+ */
+ ino[0] += 2;
+}
+
+datum
+getpair(pag, key)
+char *pag;
+datum key;
+{
+ register int i;
+ register int n;
+ datum val;
+ register short *ino = (short *) pag;
+
+ if ((n = ino[0]) == 0)
+ return nullitem;
+
+ if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
+ return nullitem;
+
+ val.dptr = pag + ino[i + 1];
+ val.dsize = ino[i] - ino[i + 1];
+ return val;
+}
+
+#ifdef SEEDUPS
+int
+duppair(pag, key)
+char *pag;
+datum key;
+{
+ register short *ino = (short *) pag;
+ return ino[0] > 0 && seepair(pag, ino[0], key.dptr, key.dsize) > 0;
+}
+#endif
+
+datum
+getnkey(pag, num)
+char *pag;
+int num;
+{
+ datum key;
+ register int off;
+ register short *ino = (short *) pag;
+
+ num = num * 2 - 1;
+ if (ino[0] == 0 || num > ino[0])
+ return nullitem;
+
+ off = (num > 1) ? ino[num - 1] : PBLKSIZ;
+
+ key.dptr = pag + ino[num];
+ key.dsize = off - ino[num];
+
+ return key;
+}
+
+int
+delpair(pag, key)
+char *pag;
+datum key;
+{
+ register int n;
+ register int i;
+ register short *ino = (short *) pag;
+
+ if ((n = ino[0]) == 0)
+ return 0;
+
+ if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
+ return 0;
+/*
+ * found the key. if it is the last entry
+ * [i.e. i == n - 1] we just adjust the entry count.
+ * hard case: move all data down onto the deleted pair,
+ * shift offsets onto deleted offsets, and adjust them.
+ * [note: 0 < i < n]
+ */
+ if (i < n - 1) {
+ register int m;
+ register char *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);
+ register char *src = pag + ino[i + 1];
+ register int zoo = dst - src;
+
+ debug(("free-up %d ", zoo));
+/*
+ * shift data/keys down
+ */
+ m = ino[i + 1] - ino[n];
+#ifdef DUFF
+#define MOVB *--dst = *--src
+ if (m > 0) {
+ register int loop = (m + 8 - 1) >> 3;
+
+ switch (m & (8 - 1)) {
+ case 0: do {
+ MOVB; case 7: MOVB;
+ case 6: MOVB; case 5: MOVB;
+ case 4: MOVB; case 3: MOVB;
+ case 2: MOVB; case 1: MOVB;
+ } while (--loop);
+ }
+ }
+#else
+ dst -= m;
+ src -= m;
+ memmove(dst, src, m);
+#endif
+/*
+ * adjust offset index up
+ */
+ while (i < n - 1) {
+ ino[i] = ino[i + 2] + zoo;
+ i++;
+ }
+ }
+ ino[0] -= 2;
+ return 1;
+}
+
+/*
+ * search for the key in the page.
+ * return offset index in the range 0 < i < n.
+ * return 0 if not found.
+ */
+static int
+seepair(pag, n, key, siz)
+char *pag;
+register int n;
+register char *key;
+register int siz;
+{
+ register int i;
+ register int off = PBLKSIZ;
+ register short *ino = (short *) pag;
+
+ for (i = 1; i < n; i += 2) {
+ if (siz == off - ino[i] &&
+ memcmp(key, pag + ino[i], siz) == 0)
+ return i;
+ off = ino[i + 1];
+ }
+ return 0;
+}
+
+void
+splpage(pag, new, sbit)
+char *pag;
+char *new;
+long sbit;
+{
+ datum key;
+ datum val;
+
+ register int n;
+ register int off = PBLKSIZ;
+ char cur[PBLKSIZ];
+ register short *ino = (short *) cur;
+
+ (void) memcpy(cur, pag, PBLKSIZ);
+ (void) memset(pag, 0, PBLKSIZ);
+ (void) memset(new, 0, PBLKSIZ);
+
+ n = ino[0];
+ for (ino++; n > 0; ino += 2) {
+ key.dptr = cur + ino[0];
+ key.dsize = off - ino[0];
+ val.dptr = cur + ino[1];
+ val.dsize = ino[0] - ino[1];
+/*
+ * select the page pointer (by looking at sbit) and insert
+ */
+ (void) putpair((exhash(key) & sbit) ? new : pag, key, val);
+
+ off = ino[1];
+ n -= 2;
+ }
+
+ debug(("%d split %d/%d\n", ((short *) cur)[0] / 2,
+ ((short *) new)[0] / 2,
+ ((short *) pag)[0] / 2));
+}
+
+/*
+ * check page sanity:
+ * number of entries should be something
+ * reasonable, and all offsets in the index should be in order.
+ * this could be made more rigorous.
+ */
+int
+chkpage(pag)
+char *pag;
+{
+ register int n;
+ register int off;
+ register short *ino = (short *) pag;
+
+ if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof(short))
+ return 0;
+
+ if (n > 0) {
+ off = PBLKSIZ;
+ for (ino++; n > 0; ino += 2) {
+ if (ino[0] > off || ino[1] > off ||
+ ino[1] > ino[0])
+ return 0;
+ off = ino[1];
+ n -= 2;
+ }
+ }
+ return 1;
+}
+
+#endif /* SSL_USE_SDBM */
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h
new file mode 100644
index 00000000000..076b8be5cdc
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h
@@ -0,0 +1,191 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_util_sdbm.c
+** Built-in Simple DBM (Header)
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/*
+ * sdbm - ndbm work-alike hashed database library
+ * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
+ * author: oz@nexus.yorku.ca
+ * status: public domain.
+ */
+
+#ifndef SSL_UTIL_SDBM_H
+#define SSL_UTIL_SDBM_H
+
+#define DUFF /* go ahead and use the loop-unrolled version */
+
+#include <stdio.h>
+
+#ifdef MOD_SSL
+#define DBLKSIZ 16384 /* SSL cert chains require more */
+#define PBLKSIZ 8192 /* SSL cert chains require more */
+#define PAIRMAX 8008 /* arbitrary on PBLKSIZ-N */
+#else
+#define DBLKSIZ 4096
+#define PBLKSIZ 1024
+#define PAIRMAX 1008 /* arbitrary on PBLKSIZ-N */
+#endif
+#define SPLTMAX 10 /* maximum allowed splits */
+ /* for a single insertion */
+#define DIRFEXT ".dir"
+#define PAGFEXT ".pag"
+
+typedef struct {
+ int dirf; /* directory file descriptor */
+ int pagf; /* page file descriptor */
+ int flags; /* status/error flags, see below */
+ long maxbno; /* size of dirfile in bits */
+ long curbit; /* current bit number */
+ long hmask; /* current hash mask */
+ long blkptr; /* current block for nextkey */
+ int keyptr; /* current key for nextkey */
+ long blkno; /* current page to read/write */
+ long pagbno; /* current page in pagbuf */
+ char pagbuf[PBLKSIZ]; /* page file block buffer */
+ long dirbno; /* current block in dirbuf */
+ char dirbuf[DBLKSIZ]; /* directory file block buffer */
+} DBM;
+
+#define DBM_RDONLY 0x1 /* data base open read-only */
+#define DBM_IOERR 0x2 /* data base I/O error */
+
+/*
+ * utility macros
+ */
+#define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY)
+#define sdbm_error(db) ((db)->flags & DBM_IOERR)
+
+#define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */
+
+#define sdbm_dirfno(db) ((db)->dirf)
+#define sdbm_pagfno(db) ((db)->pagf)
+
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+
+extern datum nullitem;
+
+#ifdef __STDC__
+#define proto(p) p
+#else
+#define proto(p) ()
+#endif
+
+/*
+ * flags to sdbm_store
+ */
+#define DBM_INSERT 0
+#define DBM_REPLACE 1
+
+/*
+ * ndbm interface
+ */
+extern DBM *sdbm_open proto((char *, int, int));
+extern void sdbm_close proto((DBM *));
+extern datum sdbm_fetch proto((DBM *, datum));
+extern int sdbm_delete proto((DBM *, datum));
+extern int sdbm_store proto((DBM *, datum, datum, int));
+extern datum sdbm_firstkey proto((DBM *));
+extern datum sdbm_nextkey proto((DBM *));
+
+/*
+ * other
+ */
+extern DBM *sdbm_prep proto((char *, char *, int, int));
+extern long sdbm_hash proto((char *, int));
+
+/* pair.h */
+extern int fitpair proto((char *, int));
+extern void putpair proto((char *, datum, datum));
+extern datum getpair proto((char *, datum));
+extern int delpair proto((char *, datum));
+extern int chkpage proto((char *));
+extern datum getnkey proto((char *, int));
+extern void splpage proto((char *, char *, long));
+extern int duppair proto((char *, datum));
+
+/* tune.h */
+/*
+ * sdbm - ndbm work-alike hashed database library
+ * tuning and portability constructs [not nearly enough]
+ * author: oz@nexus.yorku.ca
+ */
+
+#define BYTESIZ 8
+
+/*
+ * important tuning parms (hah)
+ */
+
+#define SEEDUPS /* always detect duplicates */
+#define BADMESS /* generate a message for worst case:
+ cannot make room after SPLTMAX splits */
+/*
+ * misc
+ */
+#ifdef DEBUG
+#define debug(x) printf x
+#else
+#define debug(x)
+#endif
+
+#endif /* SSL_UTIL_SDBM_H */
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c
new file mode 100644
index 00000000000..2d8632ae355
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c
@@ -0,0 +1,94 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_util_ssl.c
+** Additional Utility Functions for SSLeay
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "mod_ssl.h"
+
+
+/* _________________________________________________________________
+**
+** Additional High-Level Functions for SSLeay
+** _________________________________________________________________
+*/
+
+int SSL_get_app_data2_idx(void)
+{
+ static int app_data2_idx = -1;
+
+ if (app_data2_idx < 0) {
+ app_data2_idx = SSL_get_ex_new_index(0,
+ "Second Application Data for SSL", NULL, NULL, NULL);
+ app_data2_idx = SSL_get_ex_new_index(0,
+ "Second Application Data for SSL", NULL, NULL, NULL);
+ }
+ return(app_data2_idx);
+}
+
+void *SSL_get_app_data2(SSL *ssl)
+{
+ return (void *)SSL_get_ex_data(ssl, SSL_get_app_data2_idx());
+}
+
+void SSL_set_app_data2(SSL *ssl, void *arg)
+{
+ SSL_set_ex_data(ssl, SSL_get_app_data2_idx(), (char *)arg);
+ return;
+}
+
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h
new file mode 100644
index 00000000000..01e0cbe7f86
--- /dev/null
+++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h
@@ -0,0 +1,96 @@
+/* _ _
+** _ __ ___ ___ __| | ___ ___| |
+** | '_ ` _ \ / _ \ / _` | / __/ __| |
+** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay
+** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/
+** |_____|
+** ssl_util_ssl.h
+** Additional Utility Functions for SSLeay
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-1999 Ralf S. Engelschall. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * 4. The names "mod_ssl" must not be used to endorse or promote
+ * products derived from this software without prior written
+ * permission. For written permission, please contact
+ * rse@engelschall.com.
+ *
+ * 5. Products derived from this software may not be called "mod_ssl"
+ * nor may "mod_ssl" appear in their names without prior
+ * written permission of Ralf S. Engelschall.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by
+ * Ralf S. Engelschall <rse@engelschall.com> for use in the
+ * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
+ * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef SSL_UTIL_SSL_H
+#define SSL_UTIL_SSL_H
+
+/*
+ * Determine SSL library version number
+ */
+#ifdef OPENSSL_VERSION_NUMBER
+#define SSL_LIBRARY_VERSION OPENSSL_VERSION_NUMBER
+#define SSL_LIBRARY_NAME "OpenSSL"
+#else
+#ifdef SSLEAY_VERSION_NUMBER
+#define SSL_LIBRARY_VERSION SSLEAY_VERSION_NUMBER
+#define SSL_LIBRARY_NAME "SSLeay"
+#else
+#define SSL_LIBRARY_VERSION 0x0000
+#define SSL_LIBRARY_NAME "OtherSSL"
+#endif
+#endif
+
+/*
+ * Support for retrieving/overriding states
+ */
+#ifndef SSL_get_state
+#define SSL_get_state(ssl) SSL_state(ssl)
+#endif
+#define SSL_set_state(ssl,val) (ssl)->state = val
+
+/*
+ * Additional Functions
+ */
+int SSL_get_app_data2_idx(void);
+void *SSL_get_app_data2(SSL *);
+void SSL_set_app_data2(SSL *, void *);
+
+#endif /* SSL_UTIL_SSL_H */
diff --git a/usr.sbin/httpd/src/modules/standard/mod_log_config.c b/usr.sbin/httpd/src/modules/standard/mod_log_config.c
index ceab066c5fb..21ed1973f99 100644
--- a/usr.sbin/httpd/src/modules/standard/mod_log_config.c
+++ b/usr.sbin/httpd/src/modules/standard/mod_log_config.c
@@ -249,6 +249,9 @@ typedef struct {
typedef const char *(*item_key_func) (request_rec *, char *);
typedef struct {
+#ifdef EAPI
+ char ch;
+#endif
item_key_func func;
char *arg;
int condition_sense;
@@ -491,15 +494,36 @@ static struct log_item_list {
}
};
+#ifdef EAPI
+static struct log_item_list *find_log_func(pool *p, char k)
+#else /* EAPI */
static struct log_item_list *find_log_func(char k)
+#endif /* EAPI */
{
int i;
+#ifdef EAPI
+ struct log_item_list *lil;
+#endif /* EAPI */
for (i = 0; log_item_keys[i].ch; ++i)
if (k == log_item_keys[i].ch) {
return &log_item_keys[i];
}
+#ifdef EAPI
+ if (ap_hook_status(ap_psprintf(p, "ap::mod_log_config::log_%c", k))
+ != AP_HOOK_STATE_NOTEXISTANT) {
+ lil = (struct log_item_list *)
+ ap_pcalloc(p, sizeof(struct log_item_list));
+ if (lil == NULL)
+ return NULL;
+ lil->ch = k;
+ lil->func = NULL;
+ lil->want_orig_default = 0;
+ return lil;
+ }
+#endif /* EAPI */
+
return NULL;
}
@@ -594,7 +618,11 @@ static char *parse_log_item(pool *p, log_format_item *it, const char **sa)
break;
default:
+#ifdef EAPI
+ l = find_log_func(p, *s++);
+#else /* EAPI */
l = find_log_func(*s++);
+#endif /* EAPI */
if (!l) {
char dummy[2];
@@ -603,6 +631,9 @@ static char *parse_log_item(pool *p, log_format_item *it, const char **sa)
return ap_pstrcat(p, "Unrecognized LogFormat directive %",
dummy, NULL);
}
+#ifdef EAPI
+ it->ch = s[-1];
+#endif
it->func = l->func;
if (it->want_orig == -1) {
it->want_orig = l->want_orig_default;
@@ -664,6 +695,15 @@ static const char *process_item(request_rec *r, request_rec *orig,
/* We do. Do it... */
+#ifdef EAPI
+ if (item->func == NULL) {
+ cp = NULL;
+ ap_hook_use(ap_psprintf(r->pool, "ap::mod_log_config::log_%c", item->ch),
+ AP_HOOK_SIG3(ptr,ptr,ptr), AP_HOOK_DECLINE(NULL),
+ &cp, r, item->arg);
+ }
+ else
+#endif
cp = (*item->func) (item->want_orig ? orig : r, item->arg);
return cp ? cp : "-";
}
diff --git a/usr.sbin/httpd/src/modules/standard/mod_rewrite.c b/usr.sbin/httpd/src/modules/standard/mod_rewrite.c
index 41db2358cb7..9898103006f 100644
--- a/usr.sbin/httpd/src/modules/standard/mod_rewrite.c
+++ b/usr.sbin/httpd/src/modules/standard/mod_rewrite.c
@@ -3750,6 +3750,15 @@ static char *lookup_variable(request_rec *r, char *var)
}
#endif /* ndef WIN32 */
+#ifdef EAPI
+ else {
+ ap_hook_use("ap::mod_rewrite::lookup_variable",
+ AP_HOOK_SIG3(ptr,ptr,ptr),
+ AP_HOOK_DECLINE(NULL),
+ &result, r, var);
+ }
+#endif
+
if (result == NULL) {
return ap_pstrdup(r->pool, "");
}
diff --git a/usr.sbin/httpd/src/modules/standard/mod_so.c b/usr.sbin/httpd/src/modules/standard/mod_so.c
index 80ac4bcb673..ecc81f8f181 100644
--- a/usr.sbin/httpd/src/modules/standard/mod_so.c
+++ b/usr.sbin/httpd/src/modules/standard/mod_so.c
@@ -257,7 +257,12 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
* Make sure the found module structure is really a module structure
*
*/
+#ifdef EAPI
+ if ( modp->magic != MODULE_MAGIC_COOKIE_AP13
+ && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
+#else
if (modp->magic != MODULE_MAGIC_COOKIE) {
+#endif
return ap_pstrcat(cmd->pool, "API module structure `", modname,
"' in file ", szModuleFile, " is garbled -"
" perhaps this is not an Apache module DSO?", NULL);
diff --git a/usr.sbin/httpd/src/support/Makefile.tmpl b/usr.sbin/httpd/src/support/Makefile.tmpl
index 04d78cb5b79..216d9657ea4 100644
--- a/usr.sbin/httpd/src/support/Makefile.tmpl
+++ b/usr.sbin/httpd/src/support/Makefile.tmpl
@@ -41,6 +41,12 @@ apxs: apxs.pl
suexec: suexec.o
$(CC) $(CFLAGS) suexec.o -o suexec $(LDFLAGS) $(LIBS)
+ca-fix: ca-fix.c
+ $(CC) $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) \
+ $(LDFLAGS) $(SSL_LDFLAGS) \
+ -o ca-fix ca-fix.c \
+ $(LIBS) $(SSL_LIBS)
+
clean:
rm -f $(TARGETS) *.o
diff --git a/usr.sbin/httpd/src/support/apachectl b/usr.sbin/httpd/src/support/apachectl
index 7ea46467259..a3ea6fdc695 100644
--- a/usr.sbin/httpd/src/support/apachectl
+++ b/usr.sbin/httpd/src/support/apachectl
@@ -75,6 +75,18 @@ do
ERROR=3
fi
;;
+ startssl|sslstart|start-SSL)
+ 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,6 +165,7 @@ do
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
diff --git a/usr.sbin/httpd/src/support/apxs.pl b/usr.sbin/httpd/src/support/apxs.pl
index 8c0f802f2c1..f08450cdab4 100644
--- a/usr.sbin/httpd/src/support/apxs.pl
+++ b/usr.sbin/httpd/src/support/apxs.pl
@@ -618,5 +618,11 @@ module MODULE_VAR_EXPORT %NAME%_module = {
NULL, /* child_init */
NULL, /* child_exit */
NULL /* [#0] post read-request */
+#ifdef EAPI
+ ,NULL, /* EAPI: add_module */
+ NULL, /* EAPI: remove_module */
+ NULL, /* EAPI: rewrite_command */
+ NULL /* EAPI: new_connection */
+#endif
};
diff --git a/usr.sbin/httpd/src/support/ca-fix.c b/usr.sbin/httpd/src/support/ca-fix.c
new file mode 100644
index 00000000000..dab40933a15
--- /dev/null
+++ b/usr.sbin/httpd/src/support/ca-fix.c
@@ -0,0 +1,609 @@
+/*
+** ca-fix, X.509 Certificate Patch Utility / Version 0.41
+**
+** Copyright (c) 1997-1998
+** Dr Stephen N. Henson <shenson@drh-consultancy.demon.co.uk>
+** http://www.drh-consultancy.demon.co.uk/
+**
+** Commercial and non-commercial use is permitted.
+**
+** Any software using this code must include the following message in its
+** startup code or documentation and in any advertising material:
+** "This Product includes cryptographic software written by Dr S N Henson
+** (shenson@bigfoot.com)"
+**
+** This software is allowed to be used in the mod_ssl package
+** without the above advertisment clause with permission by Dr S N Henson as
+** long as it's used under build-time only and never gets installed as part
+** of neither the Apache nor the mod_ssl package.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <bio.h>
+#include <objects.h>
+#include <asn1.h>
+#include <asn1_mac.h>
+#include <x509.h>
+#include <err.h>
+#include <crypto.h>
+#include <stack.h>
+#include <evp.h>
+#include <pem.h>
+
+#if SSLEAY_VERSION_NUMBER < 0x0900
+#define OBJ_create(a,b,c) OBJ_create_and_add_object(a,b,c)
+#endif
+
+typedef struct {
+ int ca;
+ ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **);
+ASN1_OBJECT *__OBJ_txt2obj(char *);
+
+int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **pp)
+{
+ M_ASN1_I2D_vars(a);
+ if (a->ca)
+ M_ASN1_I2D_len(a->ca, i2d_ASN1_BOOLEAN);
+ M_ASN1_I2D_len(a->pathlen, i2d_ASN1_INTEGER);
+
+ M_ASN1_I2D_seq_total();
+ if (a->ca)
+ M_ASN1_I2D_put(a->ca, i2d_ASN1_BOOLEAN);
+ M_ASN1_I2D_put(a->pathlen, i2d_ASN1_INTEGER);
+ M_ASN1_I2D_finish();
+}
+
+typedef struct {
+ char *name;
+ char *value;
+ char flag;
+#define CERT_CRIT 0x1
+#define CERT_RAW 0x2
+#define CERT_RAW_FILE 0x4
+} EXT_ADD;
+
+STACK *exts;
+STACK *extusage;
+
+void add_ext(char *, char *, char);
+
+unsigned char extbuf[10240];
+
+int main(int argc, char **argv)
+{
+ char *infile = NULL, *outfile = NULL, *keyname = NULL;
+ BIO *in = NULL, *out = NULL, *inkey = NULL, *bio_err = NULL;
+ char **args;
+ int i;
+ int badarg = 0;
+ int bconsadd = 0, bconsdel = 0;
+ int nset = 0, nsclr = 0;
+ unsigned char ntype = 0, noout = 0, exthex = 0, extparse = 0;
+ unsigned char bscrit = 0, nscrit = 0, keycrit = 0, print = 0, sign = 1;
+ unsigned char setkey = 0;
+ X509 *cert;
+ EVP_PKEY *pkey = NULL;
+ BASIC_CONSTRAINTS bcons = {0, NULL};
+ EVP_MD *dgst;
+
+ if (bio_err == NULL)
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ ERR_load_crypto_strings();
+ args = argv + 1;
+
+ while (*args) {
+ if (*args[0] == '-') {
+ if (!strcmp(*args, "-caset")) {
+ bconsadd = 1;
+ bcons.ca = 0xff;
+ }
+ else if (!strcmp(*args, "-caunset")) {
+ if (bcons.ca)
+ badarg = 1;
+ else
+ bconsadd = 1;
+ }
+ else if (!strcmp(*args, "-caclr"))
+ bconsdel = 1;
+ else if (!strcmp(*args, "-setkey"))
+ setkey = 1;
+ else if (!strcmp(*args, "-print"))
+ print = 1;
+ else if (!strcmp(*args, "-noout"))
+ noout = 1;
+ else if (!strcmp(*args, "-nosign"))
+ sign = 0;
+ else if (!strcmp(*args, "-exthex"))
+ exthex = 1;
+ else if (!strcmp(*args, "-extparse"))
+ extparse = 1;
+ else if (!strcmp(*args, "-nsclr"))
+ nsclr = 1;
+ else if (!strcmp(*args, "-nobscrit"))
+ bscrit = 0;
+ else if (!strcmp(*args, "-bscrit"))
+ bscrit = 1;
+ else if (!strcmp(*args, "-nscrit"))
+ nscrit = 1;
+ else if (!strcmp(*args, "-extcrit"))
+ keycrit = 1;
+ else if (!strcmp(*args, "-pathlen")) {
+ if (args[1]) {
+ args++;
+ bconsadd = 1;
+ bcons.ca = 0xff;
+ bcons.pathlen = ASN1_INTEGER_new();
+ ASN1_INTEGER_set(bcons.pathlen,
+ strtol(*args, NULL, 0));
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-nscertype")) {
+ if (args[1]) {
+ args++;
+ nset = 1;
+ ntype = (unsigned char) strtol(*args, NULL, 0);
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-rawfile")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], CERT_RAW_FILE);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-Crawfile")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], CERT_RAW_FILE | CERT_CRIT);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-rawext")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], CERT_RAW);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-Crawext")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], CERT_RAW | CERT_CRIT);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-ext")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], 0);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-Cext")) {
+ if (args[1] && args[2]) {
+ add_ext(args[1], args[2], CERT_CRIT);
+ args += 2;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-extusage")) {
+ if (args[1]) {
+ ASN1_OBJECT *obj;
+ if (!extusage)
+ extusage = sk_new(NULL);
+ obj = __OBJ_txt2obj(args[1]);
+ if (!obj) {
+ BIO_printf(bio_err, "Error parsing extended usage object\n");
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ else
+ sk_push(extusage, (char *) obj);
+ args++;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-delext")) {
+ if (args[1]) {
+ add_ext(args[1], NULL, 0);
+ args++;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-inkey")) {
+ if (args[1]) {
+ args++;
+ keyname = *args;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-in")) {
+ if (args[1]) {
+ args++;
+ infile = *args;
+ }
+ else
+ badarg = 1;
+ }
+ else if (!strcmp(*args, "-out")) {
+ if (args[1]) {
+ args++;
+ outfile = *args;
+ }
+ else
+ badarg = 1;
+ }
+ else
+ badarg = 1;
+ }
+ else
+ badarg = 1;
+ args++;
+ }
+
+ if (badarg || (bconsadd && bconsdel)) {
+ BIO_printf(bio_err, "ca-fix version 0.41, certificate patcher\n");
+ BIO_printf(bio_err, "Written by Dr. S N Henson (shenson@bigfoot.com)\n");
+ BIO_printf(bio_err, "ca-fix [args]\n");
+ BIO_printf(bio_err, "-in cert.pem input certificate.\n");
+ BIO_printf(bio_err, "-out cert.pem output certificate.\n");
+ BIO_printf(bio_err, "-noout don't output certificate\n");
+ BIO_printf(bio_err, "-nosign don't sign certificate\n");
+ BIO_printf(bio_err, "-print print certificate\n");
+ BIO_printf(bio_err, "-extparse ASN1 parse extensions\n");
+ BIO_printf(bio_err, "-exthex hex dump extensions\n");
+ BIO_printf(bio_err, "-caset set cA flag, add basic constraints\n");
+ BIO_printf(bio_err, "-caunset don't set cA flag, add basic constraints\n");
+ BIO_printf(bio_err, "-caclr delete basic constraints\n");
+ BIO_printf(bio_err, "-pathlen n set path length to \'n\'\n");
+ BIO_printf(bio_err, "-bscrit make basic constraints critical\n");
+ BIO_printf(bio_err, "-nscrit make nscertype critical (not recommended)\n");
+ BIO_printf(bio_err, "-nscertype num set nscertype to num\n");
+ BIO_printf(bio_err, "-nsclr delete nscertype\n");
+ BIO_printf(bio_err, "-inkey pkey.pem private key of signer\n");
+ BIO_printf(bio_err, "Expert options:\n");
+ BIO_printf(bio_err, "-setkey changed certificate public key to match signer\n");
+ BIO_printf(bio_err, "-delext ext delete extension (can use OID)\n");
+ BIO_printf(bio_err, "-ext genopt val add several extensions\n");
+ BIO_printf(bio_err, "-Cext genopt val add several critical extensions\n");
+ BIO_printf(bio_err, "genopt can be: keyUsage, nsCertType, nsBaseUrl, nsRevocationUrl,\n");
+ BIO_printf(bio_err, " nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,\n");
+ BIO_printf(bio_err, " nsSslServerName, nsComment\n");
+ BIO_printf(bio_err, "-rawext opt HEX add raw extension (can use OID)\n");
+ BIO_printf(bio_err, "-Crawext opt HEX add critical raw extension (can use OID)\n");
+ BIO_printf(bio_err, "-Crawfile opt fn add raw extension from file (can use OID)\n");
+ BIO_printf(bio_err, "-rawfile opt fn add critical raw extension from file (can use OID)\n");
+ BIO_printf(bio_err, "-extusage OID add extended key usage extension\n");
+ BIO_printf(bio_err, "-extcrit make extended key usage extension critical\n");
+ exit(1);
+ }
+
+ SSLeay_add_all_algorithms();
+ X509v3_add_netscape_extensions();
+ X509v3_add_standard_extensions();
+
+ in = BIO_new(BIO_s_file());
+ out = BIO_new(BIO_s_file());
+
+ if (!infile)
+ BIO_set_fp(in, stdin, BIO_NOCLOSE);
+ else {
+ if (!keyname)
+ keyname = infile;
+ if (BIO_read_filename(in, infile) <= 0) {
+ perror(infile);
+ exit(1);
+ }
+ }
+
+ if (keyname) {
+ inkey = BIO_new(BIO_s_file());
+ if (BIO_read_filename(inkey, keyname) <= 0) {
+ perror(keyname);
+ exit(1);
+ }
+ }
+
+ if (!outfile)
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+ else {
+ if (BIO_write_filename(out, outfile) <= 0) {
+ perror(outfile);
+ exit(1);
+ }
+ }
+
+ cert = PEM_read_bio_X509(in, NULL, NULL);
+ if (!cert) {
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+
+ if (sign || setkey) {
+ pkey = PEM_read_bio_PrivateKey(inkey ? inkey : in, NULL, NULL);
+ if (!pkey) {
+ BIO_printf(bio_err, "Error loading private key\n");
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ }
+
+ /* OK we've got the certificate: now fix it up */
+
+ /* Make it a V3 certificate */
+ X509_set_version(cert, 2);
+
+ if (setkey)
+ X509_set_pubkey(cert, pkey);
+
+ if (bconsadd || bconsdel) {
+ int index;
+ index = X509_get_ext_by_NID(cert, NID_basic_constraints, -1);
+ if (index >= 0)
+ X509_delete_ext(cert, index);
+ }
+ if (nset || nsclr) {
+ int index;
+ index = X509_get_ext_by_NID(cert, NID_netscape_cert_type, -1);
+ if (index >= 0)
+ X509_delete_ext(cert, index);
+ }
+
+ if (bconsadd) {
+ ASN1_OCTET_STRING *bcons_ext;
+ X509_EXTENSION *x;
+ unsigned char *bcons_der, *p;
+ int bcons_len;
+
+ /* generate encoding of extension */
+ bcons_len = i2d_BASIC_CONSTRAINTS(&bcons, NULL);
+ bcons_der = malloc(bcons_len);
+ p = bcons_der;
+ i2d_BASIC_CONSTRAINTS(&bcons, &p);
+
+ bcons_ext = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(bcons_ext, bcons_der, bcons_len);
+ free(bcons_der);
+ x = X509_EXTENSION_create_by_NID(NULL, NID_basic_constraints, bscrit,
+ bcons_ext);
+ ASN1_OCTET_STRING_free(bcons_ext);
+ if (!x) {
+ BIO_printf(bio_err, "Error creating extension\n");
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ X509_add_ext(cert, x, -1);
+ X509_EXTENSION_free(x);
+ }
+
+ if (nset) {
+ X509_EXTENSION *x;
+ ASN1_OCTET_STRING *str;
+ int data_type;
+ str = NULL;
+ data_type = X509v3_data_type_by_NID(NID_netscape_cert_type);
+ X509v3_pack_string(&str, data_type, &ntype, 1);
+ x = X509_EXTENSION_create_by_NID(NULL, NID_netscape_cert_type,
+ nscrit, str);
+ X509_add_ext(cert, x, -1);
+ X509_EXTENSION_free(x);
+ /*ASN1_OCTET_STRING_free(str); */
+ }
+ /* Handle the generic extensions */
+ if (exts) {
+ while (sk_num(exts)) {
+ EXT_ADD *tmpext;
+ int ext_nid, index;
+ char *ext_str;
+ unsigned char ext_bit;
+ ASN1_OCTET_STRING *str;
+ X509_EXTENSION *x;
+ ASN1_OBJECT *extobj;
+ tmpext = (EXT_ADD *) sk_pop(exts);
+ extobj = __OBJ_txt2obj(tmpext->name);
+ if (!extobj) {
+ fprintf(stderr, "Invalid object %s\n", tmpext->name);
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ /* Delete extension if already present */
+ index = X509_get_ext_by_OBJ(cert, extobj, -1);
+ if (index >= 0)
+ X509_delete_ext(cert, index);
+ if (!tmpext->value)
+ continue;
+ ext_nid = OBJ_obj2nid(extobj);
+ if (tmpext->flag & CERT_RAW) {
+ /* Covert hex extension into an OCTET STRING */
+ unsigned char *rawext, *p, *q, tmphex[3];
+ long rawlen;
+ rawlen = strlen(tmpext->value);
+ if (rawlen & 1) {
+ fprintf(stderr, "Invalid raw extension length\n");
+ exit(1);
+ }
+ for (p = (unsigned char *)tmpext->value; *p; p++)
+ if (!isxdigit(*p)) {
+ fprintf(stderr, "Extension %s invalid hex digit %c\n",
+ tmpext->value, *p);
+ exit(1);
+ }
+ rawlen >>= 1;
+ rawext = Malloc(rawlen);
+ tmphex[2] = 0;
+ for (p = (unsigned char *)tmpext->value, q = rawext; *p; p += 2, q++) {
+ tmphex[0] = p[0];
+ tmphex[1] = p[1];
+ *q = (unsigned char)strtol((const char *)tmphex, NULL, 16);
+ }
+ str = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(str, rawext, rawlen);
+ Free(rawext);
+ }
+ else if (tmpext->flag & CERT_RAW_FILE) {
+ BIO *tmpin;
+ int extlen;
+ if (!(tmpin = BIO_new_file(tmpext->value, "rb"))) {
+ BIO_printf(bio_err, "Error opening file %s\n", tmpext->value);
+ ERR_print_errors(bio_err);
+ }
+ extlen = BIO_read(tmpin, (char *)extbuf, sizeof(extbuf));
+ str = ASN1_STRING_new();
+ ASN1_OCTET_STRING_set(str, extbuf, extlen);
+ }
+ else {
+ /* Get extension type */
+ switch (ext_nid) {
+
+ case NID_key_usage:
+ case NID_netscape_cert_type:
+
+ ext_bit = (unsigned char) strtol(tmpext->value, NULL, 0);
+ ext_str = NULL;
+
+ break;
+
+ case NID_netscape_base_url:
+ case NID_netscape_revocation_url:
+ case NID_netscape_ca_revocation_url:
+ case NID_netscape_renewal_url:
+ case NID_netscape_ca_policy_url:
+ case NID_netscape_ssl_server_name:
+ case NID_netscape_comment:
+
+ ext_str = tmpext->value;
+
+ break;
+
+ default:
+
+ fprintf(stderr, "Unsuported extension %s\n", tmpext->name);
+ exit(1);
+ break;
+ }
+
+ if (ext_str)
+ str = X509v3_pack_string(NULL, V_ASN1_IA5STRING,
+ (unsigned char *)tmpext->value,
+ strlen(tmpext->value));
+ else
+ str = X509v3_pack_string(NULL, V_ASN1_BIT_STRING,
+ &ext_bit, 1);
+ }
+ x = X509_EXTENSION_create_by_NID(NULL, ext_nid,
+ tmpext->flag & CERT_CRIT, str);
+ X509_add_ext(cert, x, -1);
+ X509_EXTENSION_free(x);
+ }
+ }
+
+ /* Handle extended key usage */
+ if (extusage) {
+ int extlen;
+ unsigned char *extder, *p;
+ ASN1_OCTET_STRING *extkey;
+ X509_EXTENSION *x;
+ ASN1_OBJECT *extobj;
+
+
+ extobj = __OBJ_txt2obj("2.5.29.37");
+ /* generate encoding of extension */
+ extlen = i2d_ASN1_SET(extusage, NULL, i2d_ASN1_OBJECT, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+ extder = malloc(extlen);
+ p = extder;
+ i2d_ASN1_SET(extusage, &p, i2d_ASN1_OBJECT, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+ extkey = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(extkey, extder, extlen);
+ free(extder);
+ x = X509_EXTENSION_create_by_OBJ(NULL, extobj, keycrit,
+ extkey);
+ if (!x) {
+ BIO_printf(bio_err, "Error creating extension\n");
+ ERR_print_errors(bio_err);
+ exit(1);
+ }
+ X509_add_ext(cert, x, -1);
+ X509_EXTENSION_free(x);
+ sk_pop_free(extusage, ASN1_OBJECT_free);
+ ASN1_OBJECT_free(extobj);
+ }
+
+
+ /* OK we've modified the certificate so it will have to be re-signed */
+ dgst = EVP_get_digestbyobj(cert->sig_alg->algorithm);
+ if (sign)
+ X509_sign(cert, pkey, dgst);
+ if (print)
+ X509_print(out, cert);
+ if (extparse || exthex) {
+ BIO_printf(out, "X509 V3 Extensions.\n");
+ for (i = 0; i < X509_get_ext_count(cert); i++) {
+ X509_EXTENSION *tmpext;
+ ASN1_OCTET_STRING *octval;
+ tmpext = X509_get_ext(cert, i);
+ octval = X509_EXTENSION_get_data(tmpext);
+ i2a_ASN1_OBJECT(out, X509_EXTENSION_get_object(tmpext));
+ BIO_printf(out, ":\n");
+ if (exthex) {
+ int j;
+ for (j = 0; j < octval->length; j++)
+ BIO_printf(out, "%02X", octval->data[j]);
+ BIO_printf(out, "\n");
+ }
+ if (extparse)
+ ASN1_parse(out, octval->data, octval->length, 0);
+ }
+ }
+ if (!noout)
+ PEM_write_bio_X509(out, cert);
+
+ return (0);
+
+}
+
+void add_ext(char *name, char *val, char flag)
+{
+ EXT_ADD *tmpext;
+ if (!exts)
+ exts = sk_new(NULL);
+ tmpext = (EXT_ADD *) Malloc(sizeof(EXT_ADD));
+ tmpext->name = name;
+ tmpext->value = val;
+ tmpext->flag = flag;
+ sk_push(exts, (char *) tmpext);
+}
+
+ASN1_OBJECT *__OBJ_txt2obj(char *name)
+{
+ int obj_nid;
+ ASN1_OBJECT *obj;
+ obj_nid = OBJ_sn2nid(name);
+ if (obj_nid != NID_undef)
+ return OBJ_nid2obj(obj_nid);
+ obj_nid = OBJ_create(name, name, name);
+ if (obj_nid <= 0)
+ return NULL;
+ obj = OBJ_nid2obj(obj_nid);
+ obj->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ return obj;
+}
+
diff --git a/usr.sbin/httpd/src/support/httpd.exp b/usr.sbin/httpd/src/support/httpd.exp
index e11e3b2849a..63faaa3fbea 100644
--- a/usr.sbin/httpd/src/support/httpd.exp
+++ b/usr.sbin/httpd/src/support/httpd.exp
@@ -355,3 +355,16 @@ ap_vformatter
ap_vsnprintf
core_module
top_module
+ap_add_config_define
+ap_global_ctx
+ap_ctx_new
+ap_ctx_get
+ap_ctx_set
+ap_hook_init
+ap_hook_kill
+ap_hook_configure
+ap_hook_register_I
+ap_hook_unregister_I
+ap_hook_status
+ap_hook_use
+ap_hook_call
diff --git a/usr.sbin/httpd/src/support/mkcert.sh b/usr.sbin/httpd/src/support/mkcert.sh
new file mode 100644
index 00000000000..26b4506e024
--- /dev/null
+++ b/usr.sbin/httpd/src/support/mkcert.sh
@@ -0,0 +1,659 @@
+#!/bin/sh
+##
+## mkcert.sh -- Make SSL Certificate Files for `make certificate' command
+## Copyright (c) 1998-1999 Ralf S. Engelschall, All Rights Reserved.
+##
+
+# parameters
+make="$1"
+mflags="$2"
+ssleay="$3"
+support="$4"
+type="$5"
+crt="$6"
+key="$7"
+
+# we can operate only inside the Apache 1.3 source
+# tree and only when mod_ssl+SSLeay is actually configured.
+if [ ! -f "../README.configure" ]; then
+ echo "mkcert.sh:Error: Cannot operate outside the Apache 1.3 source tree." 1>&2
+ echo "mkcert.sh:Hint: You have to stay inside apache_1.3.x/src." 1>&2
+ exit 1
+fi
+if [ ".$ssleay" = . ]; then
+ echo "mkcert.sh:Error: mod_ssl/SSLeay has to be configured before using this utility." 1>&2
+ echo "mkcert.sh:Hint: Configure mod_ssl with --enable-module=ssl in APACI, first." 1>&2
+ exit 1
+fi
+
+# configuration
+# WE ARE CALLED FROM THE PARENT DIR!
+sslcrtdir="../conf/ssl.crt"
+sslcsrdir="../conf/ssl.csr"
+sslkeydir="../conf/ssl.key"
+
+# some optional terminal sequences
+case $TERM in
+ xterm|xterm*|vt220|vt220*)
+ T_MD=`echo dummy | awk '{ printf("%c%c%c%c", 27, 91, 49, 109); }'`
+ T_ME=`echo dummy | awk '{ printf("%c%c%c", 27, 91, 109); }'`
+ ;;
+ vt100|vt100*)
+ T_MD=`echo dummy | awk '{ printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }'`
+ T_ME=`echo dummy | awk '{ printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }'`
+ ;;
+ default)
+ T_MD=''
+ T_ME=''
+ ;;
+esac
+
+# display header
+echo "${T_MD}SSL Certificate Generation Utility${T_ME} (mkcert.sh)"
+echo "Copyright (c) 1998 Ralf S. Engelschall, All Rights Reserved."
+
+# find some random files
+# (do not use /dev/random here, because this device
+# doesn't work as expected on all platforms)
+echo " + finding random files on your platform"
+randfiles=''
+for file in /var/log/messages /var/adm/messages \
+ /kernel /vmunix /vmlinuz \
+ /etc/hosts /etc/resolv.conf; do
+ if [ -f $file ]; then
+ if [ ".$randfiles" = . ]; then
+ randfiles="$file"
+ else
+ randfiles="${randfiles}:$file"
+ fi
+ fi
+done
+
+# on-demand compile the ca-fix only
+case $type in
+ test|custom)
+ cd $support
+ if [ ! -f ca-fix ]; then
+ echo " + building ca-fix auxiliary tool"
+ $make $mflags ca-fix >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ $make $mflags ca-fix
+ echo "**FAILED"
+ exit 1
+ fi
+ fi
+ cd ..
+ cafix="$support/ca-fix"
+ ;;
+esac
+
+# processing
+case $type in
+
+ dummy)
+ echo ""
+ echo "${T_MD}Generating self-signed Snake Oil certificate [DUMMY]${T_ME}"
+ echo "______________________________________________________________________"
+ echo ""
+ cp $sslcrtdir/snakeoil.crt $sslcrtdir/server.crt
+ cp $sslkeydir/snakeoil.key $sslkeydir/server.key
+ echo "${T_MD}RESULT: Server Certification Files${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.key/server.key${T_ME}"
+ echo " The PEM-encoded RSA private certificate file which you configure"
+ echo " with the 'SSLCertificateKeyFile' directive (automatically done"
+ echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}"
+ echo " The PEM-encoded X.509 server certificate file which you configure"
+ echo " with the 'SSLCertificateFile' directive (automatically done"
+ echo " when you install via APACI)."
+ echo ""
+ echo "WARNING: Do not use this for real-life/production systems"
+ echo ""
+ ;;
+
+ test)
+ echo ""
+ echo "${T_MD}Generating test certificate signed by Snake Oil CA [TEST]${T_ME}"
+ echo "WARNING: Do not use this for real-life/production systems"
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 1: Generating RSA private key (1024 bit) [server.key]${T_ME}"
+ if [ ! -f $HOME/.rnd ]; then
+ touch $HOME/.rnd
+ fi
+ if [ ".$randfiles" != . ]; then
+ $ssleay genrsa -rand $randfiles \
+ -out $sslkeydir/server.key \
+ 1024
+ else
+ $ssleay genrsa -out $sslkeydir/server.key \
+ 1024
+ fi
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 2: Generating X.509 certificate signing request [server.csr]${T_ME}"
+ cat >.mkcert.cfg <<EOT
+[ req ]
+default_bits = 1024
+distinguished_name = req_DN
+[ req_DN ]
+countryName = "1. Country Name (2 letter code)"
+countryName_default = XY
+countryName_min = 2
+countryName_max = 2
+stateOrProvinceName = "2. State or Province Name (full name) "
+stateOrProvinceName_default = Snake Desert
+localityName = "3. Locality Name (eg, city) "
+localityName_default = Snake Town
+0.organizationName = "4. Organization Name (eg, company) "
+0.organizationName_default = Snake Oil, Ltd
+organizationalUnitName = "5. Organizational Unit Name (eg, section) "
+organizationalUnitName_default = Webserver Team
+commonName = "6. Common Name (eg, FQDN) "
+commonName_max = 64
+commonName_default = www.snakeoil.dom
+emailAddress = "7. Email Address (eg, name@FQDN)"
+emailAddress_max = 40
+emailAddress_default = www@snakeoil.dom
+EOT
+ $ssleay req -config .mkcert.cfg \
+ -new \
+ -key $sslkeydir/server.key \
+ -out $sslcsrdir/server.csr
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
+ exit 1
+ fi
+ rm -f .mkcert.cfg
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 3: Generating X.509 certificate signed by Snake Oil CA [server.crt]${T_ME}"
+ echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:"
+ read certversion
+ if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
+ certversion=3
+ else
+ certversion=1
+ fi
+ if [ ! -f .mkcert.serial ]; then
+ echo '01' >.mkcert.serial
+ fi
+ $ssleay x509 -days 365 \
+ -CAserial .mkcert.serial \
+ -CA $sslcrtdir/snakeoil-ca.crt \
+ -CAkey $sslkeydir/snakeoil-ca.key \
+ -in $sslcsrdir/server.csr -req \
+ -out $sslcrtdir/server.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2
+ exit 1
+ fi
+ if [ ".$certversion" = .3 ]; then
+ echo "Converting X.509 v1 to v3 certificate"
+ $cafix -nscertype 0x40 \
+ -nobscrit \
+ -nosign \
+ -in $sslcrtdir/server.crt \
+ -inkey $sslkeydir/server.key \
+ -out $sslcrtdir/server.crt.fixed
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to fixup X.509 certificate contents" 1>&2
+ exit 1
+ fi
+ cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt
+ rm -f $sslcrtdir/server.crt.fixed
+ $cafix -inkey $sslkeydir/snakeoil-ca.key \
+ -in $sslcrtdir/server.crt \
+ -out $sslcrtdir/server.crt.fixed
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to fixup X.509 certificate signature" 1>&2
+ exit 1
+ fi
+ cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt
+ rm -f $sslcrtdir/server.crt.fixed
+ fi
+ echo "Verify: matching certificate & key modulus"
+ modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/server.crt`
+ modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/server.key`
+ if [ ".$modcrt" != ".$modkey" ]; then
+ echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "Verify: matching certificate signature"
+ $ssleay verify -CAfile $sslcrtdir/snakeoil-ca.crt $sslcrtdir/server.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 4: Enrypting RSA private key with a pass phrase for security [server.key]${T_ME}"
+ echo "The contents of the server.key file (the generated private key) has to be"
+ echo "kept secret. So we strongly recommend you to encrypt the server.key file"
+ echo "with a Triple-DES cipher and a Pass Phrase."
+ while [ 1 ]; do
+ echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
+ read rc
+ if [ ".$rc" = .n -o ".$rc" = .N ]; then
+ rc="n"
+ break
+ fi
+ if [ ".$rc" = .y -o ".$rc" = .Y -o ".$rc" = . ]; then
+ rc="y"
+ break
+ fi
+ done
+ if [ ".$rc" = .y ]; then
+ $ssleay rsa -des3 \
+ -in $sslkeydir/server.key \
+ -out $sslkeydir/server.key.crypt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2
+ exit 1
+ fi
+ cp $sslkeydir/server.key.crypt $sslkeydir/server.key
+ rm -f $sslkeydir/server.key.crypt
+ echo "Fine, you're using an encrypted private key."
+ else
+ echo "Warning, you're using an unencrypted private key."
+ echo "Please notice this fact and do this on your own risk."
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}RESULT: Server Certification Files${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.key/server.key${T_ME}"
+ echo " The PEM-encoded RSA private certificate file which you configure"
+ echo " with the 'SSLCertificateKeyFile' directive (automatically done"
+ echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}"
+ echo " The PEM-encoded X.509 server certificate file which you configure"
+ echo " with the 'SSLCertificateFile' directive (automatically done"
+ echo " when you install via APACI)."
+ echo ""
+ echo "o ${T_MD}conf/ssl.csr/server.csr${T_ME}"
+ echo " The PEM-encoded X.509 certificate signing request file which"
+ echo " you can send to an official Certificate Authority (CA) in order"
+ echo " to request a real server certificate (signed by this CA instead"
+ echo " of our demonstration-only Snake Oil CA) which later can replace"
+ echo " the conf/ssl.crt/server.crt file."
+ echo ""
+ echo "WARNING: Do not use this for real-life/production systems"
+ echo ""
+ ;;
+
+ custom)
+ echo ""
+ echo "${T_MD}Generating custom certificate signed by own CA [CUSTOM]${T_ME}"
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 1: Generating RSA private key for CA (1024 bit) [ca.key]${T_ME}"
+ if [ ! -f $HOME/.rnd ]; then
+ touch $HOME/.rnd
+ fi
+ if [ ".$randfiles" != . ]; then
+ $ssleay genrsa -rand $randfiles \
+ -out $sslkeydir/ca.key \
+ 1024
+ else
+ $ssleay genrsa -out $sslkeydir/ca.key \
+ 1024
+ fi
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 2: Generating X.509 certificate signing request for CA [ca.csr]${T_ME}"
+ cat >.mkcert.cfg <<EOT
+[ req ]
+default_bits = 1024
+distinguished_name = req_DN
+[ req_DN ]
+countryName = "1. Country Name (2 letter code)"
+countryName_default = XY
+countryName_min = 2
+countryName_max = 2
+stateOrProvinceName = "2. State or Province Name (full name) "
+stateOrProvinceName_default = Snake Desert
+localityName = "3. Locality Name (eg, city) "
+localityName_default = Snake Town
+0.organizationName = "4. Organization Name (eg, company) "
+0.organizationName_default = Snake Oil, Ltd
+organizationalUnitName = "5. Organizational Unit Name (eg, section) "
+organizationalUnitName_default = Certificate Authority
+commonName = "6. Common Name (eg, CA name) "
+commonName_max = 64
+commonName_default = Snake Oil CA
+emailAddress = "7. Email Address (eg, name@FQDN)"
+emailAddress_max = 40
+emailAddress_default = ca@snakeoil.dom
+EOT
+ $ssleay req -config .mkcert.cfg \
+ -new \
+ -key $sslkeydir/ca.key \
+ -out $sslcsrdir/ca.csr
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
+ exit 1
+ fi
+ rm -f .mkcert.cfg
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 3: Generating X.509 certificate for CA signed by itself [ca.crt]${T_ME}"
+ echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:"
+ read certversion
+ if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
+ certversion=3
+ else
+ certversion=1
+ fi
+ $ssleay x509 -days 365 \
+ -signkey $sslkeydir/ca.key \
+ -in $sslcsrdir/ca.csr -req \
+ -out $sslcrtdir/ca.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate self-signed CA certificate" 1>&2
+ exit 1
+ fi
+ if [ ".$certversion" = .3 ]; then
+ $cafix -caset \
+ -nscertype 0x07 \
+ -pathlen 0 \
+ -nobscrit \
+ -in $sslcrtdir/ca.crt \
+ -inkey $sslkeydir/ca.key \
+ -out $sslcrtdir/ca.crt.fixed
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to fixup X.509 CA certificate" 1>&2
+ exit 1
+ fi
+ cp $sslcrtdir/ca.crt.fixed $sslcrtdir/ca.crt
+ rm -f $sslcrtdir/ca.crt.fixed
+ fi
+ echo "Verify: matching certificate & key modulus"
+ modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/ca.crt`
+ modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/ca.key`
+ if [ ".$modcrt" != ".$modkey" ]; then
+ echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "Verify: matching certificate signature"
+ $ssleay verify $sslcrtdir/ca.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 4: Generating RSA private key for SERVER (1024 bit) [server.key]${T_ME}"
+ if [ ! -f $HOME/.rnd ]; then
+ touch $HOME/.rnd
+ fi
+ if [ ".$randfiles" != . ]; then
+ $ssleay genrsa -rand $randfiles \
+ -out $sslkeydir/server.key \
+ 1024
+ else
+ $ssleay genrsa -out $sslkeydir/server.key \
+ 1024
+ fi
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 5: Generating X.509 certificate signing request for SERVER [server.csr]${T_ME}"
+ cat >.mkcert.cfg <<EOT
+[ req ]
+default_bits = 1024
+distinguished_name = req_DN
+[ req_DN ]
+countryName = "1. Country Name (2 letter code)"
+countryName_default = XY
+countryName_min = 2
+countryName_max = 2
+stateOrProvinceName = "2. State or Province Name (full name) "
+stateOrProvinceName_default = Snake Desert
+localityName = "3. Locality Name (eg, city) "
+localityName_default = Snake Town
+0.organizationName = "4. Organization Name (eg, company) "
+0.organizationName_default = Snake Oil, Ltd
+organizationalUnitName = "5. Organizational Unit Name (eg, section) "
+organizationalUnitName_default = Webserver Team
+commonName = "6. Common Name (eg, FQDN) "
+commonName_max = 64
+commonName_default = www.snakeoil.dom
+emailAddress = "7. Email Address (eg, name@fqdn)"
+emailAddress_max = 40
+emailAddress_default = www@snakeoil.dom
+EOT
+ $ssleay req -config .mkcert.cfg \
+ -new \
+ -key $sslkeydir/server.key \
+ -out $sslcsrdir/server.csr
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2
+ exit 1
+ fi
+ rm -f .mkcert.cfg
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 6: Generating X.509 certificate signed by own CA [server.crt]${T_ME}"
+ echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:"
+ read certversion
+ if [ ".$certversion" = .3 -o ".$certversion" = . ]; then
+ certversion=3
+ else
+ certversion=1
+ fi
+ if [ ! -f .mkcert.serial ]; then
+ echo '01' >.mkcert.serial
+ fi
+ $ssleay x509 -days 365 \
+ -CAserial .mkcert.serial \
+ -CA $sslcrtdir/ca.crt \
+ -CAkey $sslkeydir/ca.key \
+ -in $sslcsrdir/server.csr -req \
+ -out $sslcrtdir/server.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2
+ exit 1
+ fi
+ if [ ".$certversion" = .3 ]; then
+ $cafix -nscertype 0x40 \
+ -nobscrit \
+ -nosign \
+ -in $sslcrtdir/server.crt \
+ -inkey $sslkeydir/server.key \
+ -out $sslcrtdir/server.crt.fixed
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to fixup X.509 certificate contents" 1>&2
+ exit 1
+ fi
+ cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt
+ rm -f $sslcrtdir/server.crt.fixed
+ $cafix -inkey $sslkeydir/ca.key \
+ -in $sslcrtdir/server.crt \
+ -out $sslcrtdir/server.crt.fixed
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to fixup X.509 certificate signature" 1>&2
+ exit 1
+ fi
+ cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt
+ rm -f $sslcrtdir/server.crt.fixed
+ fi
+ echo "Verify: matching certificate & key modulus"
+ modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/server.crt`
+ modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/server.key`
+ if [ ".$modcrt" != ".$modkey" ]; then
+ echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "Verify: matching certificate signature"
+ $ssleay verify -CAfile $sslcrtdir/ca.crt $sslcrtdir/server.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2
+ exit 1
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 7: Enrypting RSA private key of CA with a pass phrase for security [ca.key]${T_ME}"
+ echo "The contents of the ca.key file (the generated private key) has to be"
+ echo "kept secret. So we strongly recommend you to encrypt the server.key file"
+ echo "with a Triple-DES cipher and a Pass Phrase."
+ while [ 1 ]; do
+ echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
+ read rc
+ if [ ".$rc" = .n -o ".$rc" = .N ]; then
+ rc="n"
+ break
+ fi
+ if [ ".$rc" = .y -o ".$rc" = .Y -o ".$rc" = . ]; then
+ rc="y"
+ break
+ fi
+ done
+ if [ ".$rc" = .y ]; then
+ $ssleay rsa -des3 \
+ -in $sslkeydir/ca.key \
+ -out $sslkeydir/ca.key.crypt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2
+ exit 1
+ fi
+ cp $sslkeydir/ca.key.crypt $sslkeydir/ca.key
+ rm -f $sslkeydir/ca.key.crypt
+ echo "Fine, you're using an encrypted private key."
+ else
+ echo "Warning, you're using an unencrypted private key."
+ echo "Please notice this fact and do this on your own risk."
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}STEP 8: Enrypting RSA private key of SERVER with a pass phrase for security [server.key]${T_ME}"
+ echo "The contents of the server.key file (the generated private key) has to be"
+ echo "kept secret. So we strongly recommend you to encrypt the server.key file"
+ echo "with a Triple-DES cipher and a Pass Phrase."
+ while [ 1 ]; do
+ echo dummy | awk '{ printf("Encrypt the private key now? [Y/n]: "); }'
+ read rc
+ if [ ".$rc" = .n -o ".$rc" = .N ]; then
+ rc="n"
+ break
+ fi
+ if [ ".$rc" = .y -o ".$rc" = .Y -o ".$rc" = . ]; then
+ rc="y"
+ break
+ fi
+ done
+ if [ ".$rc" = .y ]; then
+ $ssleay rsa -des3 \
+ -in $sslkeydir/server.key \
+ -out $sslkeydir/server.key.crypt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2
+ exit 1
+ fi
+ cp $sslkeydir/server.key.crypt $sslkeydir/server.key
+ rm -f $sslkeydir/server.key.crypt
+ echo "Fine, you're using an encrypted private key."
+ else
+ echo "Warning, you're using an unencrypted private key."
+ echo "Please notice this fact and do this on your own risk."
+ fi
+ echo "______________________________________________________________________"
+ echo ""
+ echo "${T_MD}RESULT: Server and CA Certification Files${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.key/ca.key${T_ME}"
+ echo " The PEM-encoded RSA private certificate file of the CA which you can"
+ echo " use to sign other servers or clients. ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.crt/ca.crt${T_ME}"
+ echo " The PEM-encoded X.509 CA server certificate file which you use to"
+ echo " sign other servers or clients. When you sign clients with it (for"
+ echo " SSL client authentication) you can configure this file with the"
+ echo " 'SSLCACertificateFile' directive."
+ echo ""
+ echo "o ${T_MD}conf/ssl.key/server.key${T_ME}"
+ echo " The PEM-encoded RSA private certificate file which you configure"
+ echo " with the 'SSLCertificateKeyFile' directive (automatically done"
+ echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}"
+ echo " The PEM-encoded X.509 server certificate file which you configure"
+ echo " with the 'SSLCertificateFile' directive (automatically done"
+ echo " when you install via APACI)."
+ echo ""
+ echo "o ${T_MD}conf/ssl.csr/server.csr${T_ME}"
+ echo " The PEM-encoded X.509 certificate signing request file which"
+ echo " you can send to an official Certificate Authority (CA) in order"
+ echo " to request a real server certificate (signed by this CA instead"
+ echo " of our own CA) which later can replace the conf/ssl.crt/server.crt"
+ echo " file."
+ echo ""
+ echo "Congratulations that you establish your server with real certificates."
+ echo ""
+ ;;
+
+ existing)
+ echo ""
+ echo "${T_MD}Using existing custom certificate [EXISTING]${T_ME}"
+ echo "______________________________________________________________________"
+ echo ""
+ if [ ".$crt" = . ]; then
+ echo "mkcert.sh: No certificate file given" 1>&2
+ exit 1
+ fi
+ if [ ! -f "$crt" ]; then
+ echo "mkcert.sh: Cannot find certificate file: $crt" 1>&2
+ exit 1
+ fi
+ if [ ".$key" != . ]; then
+ if [ ! -f "$key" ]; then
+ echo "mkcert.sh: Cannot find private key file: $key" 1>&2
+ exit 1
+ fi
+ cp $crt $sslcrtdir/server.crt
+ cp $key $sslkeydir/server.key
+ else
+ key=$crt
+ sed -e '/-----BEGIN CERTIFICATE/,/-----END CERTIFICATE/p' -e '/.*/d' \
+ <$crt >$sslcrtdir/server.crt
+ sed -e '/-----BEGIN RSA PRIVATE KEY/,/-----END RSA PRIVATE KEY/p' -e '/.*/d' \
+ <$key >$sslkeydir/server.key
+ fi
+ $ssleay x509 -noout -in $sslcrtdir/server.crt
+ if [ $? -ne 0 ]; then
+ echo "mkcert.sh:Error: Failed to check certificate contents: $crt" 1>&2
+ exit 1
+ fi
+ echo "${T_MD}RESULT: Server Certification Files${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.key/server.key${T_ME}"
+ echo " The PEM-encoded RSA private certificate file which you configure"
+ echo " with the 'SSLCertificateKeyFile' directive (automatically done"
+ echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}"
+ echo ""
+ echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}"
+ echo " The PEM-encoded X.509 server certificate file which you configure"
+ echo " with the 'SSLCertificateFile' directive (automatically done"
+ echo " when you install via APACI)."
+ echo ""
+ echo "Congratulations that you establish your server with real certificates."
+ echo ""
+ ;;
+
+esac
+
+##EOF##
diff --git a/usr.sbin/httpd/src/support/suexec.c b/usr.sbin/httpd/src/support/suexec.c
index a260fc5e342..45fdf0d021b 100644
--- a/usr.sbin/httpd/src/support/suexec.c
+++ b/usr.sbin/httpd/src/support/suexec.c
@@ -214,7 +214,13 @@ static void clean_env(void)
cidx++;
for (ep = environ; *ep && cidx < AP_ENVBUF-1; 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++;
}