diff options
author | 1999-03-01 04:27:46 +0000 | |
---|---|---|
committer | 1999-03-01 04:27:46 +0000 | |
commit | da4e2a805b85b1e03ee77f85b14e50055c16e437 (patch) | |
tree | 1b45eae4a3a05003ba7cf157f7388b789dfae8bc /usr.sbin/httpd/src | |
parent | tweak for 2.5 (diff) | |
download | wireguard-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')
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++; } |