summaryrefslogtreecommitdiffstats
path: root/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
diff options
context:
space:
mode:
authorhenning <henning@openbsd.org>2014-04-22 14:47:23 +0000
committerhenning <henning@openbsd.org>2014-04-22 14:47:23 +0000
commitd98f7e048a396e24ae64ddd378bc54773464aaaa (patch)
treef51a6e7ca8ee49dc43679c82497118fddcd7dff3 /usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
parentFinally remove KERBEROS5? from the Makefile infrastructure. (diff)
downloadwireguard-openbsd-d98f7e048a396e24ae64ddd378bc54773464aaaa.tar.xz
wireguard-openbsd-d98f7e048a396e24ae64ddd378bc54773464aaaa.zip
this commit is really florian@'s, since he's the one who made removal
of our forked apache possible by his work on nginx and slowcgi, but he doesn't want it - so it is my pleasure to tedu it. I spent so much work on chroot in it 10 years ago - and am very happy to see it go now, nginx is a far better choice today. Bye bye, Apache, won't miss you.
Diffstat (limited to 'usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c')
-rw-r--r--usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c812
1 files changed, 0 insertions, 812 deletions
diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
deleted file mode 100644
index 60ebc6f8cbc..00000000000
--- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/* _ _
-** _ __ ___ ___ __| | ___ ___| | mod_ssl
-** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
-** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
-** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
-** |_____|
-** ssl_engine_ext.c
-** Extensions to other Apache parts
-*/
-
-/* ====================================================================
- * Copyright (c) 1998-2003 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.modssl.org/)."
- *
- * 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.modssl.org/)."
- *
- * 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);
-static void ssl_ext_ms_register(void);
-static void ssl_ext_ms_unregister(void);
-
-void ssl_ext_register(void)
-{
- ssl_ext_mlc_register();
- ssl_ext_mr_register();
- ssl_ext_mp_register();
- ssl_ext_ms_register();
- return;
-}
-
-void ssl_ext_unregister(void)
-{
- ssl_ext_mlc_unregister();
- ssl_ext_mr_unregister();
- ssl_ext_mp_unregister();
- ssl_ext_ms_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 (strEQ(a, "version"))
- result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_PROTOCOL");
- else if (strEQ(a, "cipher"))
- result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");
- else if (strEQ(a, "subjectdn") || strEQ(a, "clientcert"))
- result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_S_DN");
- else if (strEQ(a, "issuerdn") || strEQ(a, "cacert"))
- result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_I_DN");
- else if (strEQ(a, "errcode"))
- result = "-";
- else if (strEQ(a, "errstr"))
- 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 *, char *);
-static int ssl_ext_mp_handler(request_rec *, void *, char *, char *, int, char *);
-static int ssl_ext_mp_set_destport(request_rec *);
-static char *ssl_ext_mp_new_connection(request_rec *, BUFF *, char *);
-static void ssl_ext_mp_close_connection(void *);
-static int ssl_ext_mp_write_host_header(request_rec *, BUFF *, char *, char *, char *);
-#ifdef SSL_EXPERIMENTAL_PROXY
-static void ssl_ext_mp_init(server_rec *, pool *);
-static int ssl_ext_mp_verify_cb(int, X509_STORE_CTX *);
-static int ssl_ext_mp_clientcert_cb(SSL *, X509 **, EVP_PKEY **);
-#endif
-
-/*
- * register us ...
- */
-static void ssl_ext_mp_register(void)
-{
-#ifdef SSL_EXPERIMENTAL_PROXY
- ap_hook_register("ap::mod_proxy::init",
- ssl_ext_mp_init, AP_HOOK_NOCTX);
-#endif
- 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)
-{
-#ifdef SSL_EXPERIMENTAL_PROXY
- ap_hook_unregister("ap::mod_proxy::init", ssl_ext_mp_init);
-#endif
- 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;
-}
-
-/*
- * SSL proxy initialization
- */
-#ifdef SSL_EXPERIMENTAL_PROXY
-static void ssl_ext_mp_init(server_rec *s, pool *p)
-{
- SSLSrvConfigRec *sc;
- char *cpVHostID;
- int nVerify;
- SSL_CTX *ctx;
- char *cp;
- STACK_OF(X509_INFO) *sk;
-
- /*
- * Initialize each virtual server
- */
- ERR_clear_error();
- for (; s != NULL; s = s->next) {
- sc = mySrvConfig(s);
- cpVHostID = ssl_util_vhostid(p, s);
-
- if (sc->bProxyVerify == UNSET)
- sc->bProxyVerify = FALSE;
-
- /*
- * Create new SSL context and configure callbacks
- */
- if (sc->nProxyProtocol == SSL_PROTOCOL_NONE) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) No Proxy SSL protocols available [hint: SSLProxyProtocol]",
- cpVHostID);
- ssl_die();
- }
- cp = ap_pstrcat(p, (sc->nProxyProtocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
- (sc->nProxyProtocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
- (sc->nProxyProtocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), NULL);
- cp[strlen(cp)-2] = NUL;
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Creating new proxy SSL context (protocols: %s)",
- cpVHostID, cp);
- if (sc->nProxyProtocol == SSL_PROTOCOL_SSLV2)
- ctx = SSL_CTX_new(SSLv2_client_method()); /* only SSLv2 is left */
- else
- ctx = SSL_CTX_new(SSLv23_client_method()); /* be more flexible */
- if (ctx == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to create SSL Proxy context", cpVHostID);
- ssl_die();
- }
- sc->pSSLProxyCtx = ctx;
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
- if (!(sc->nProxyProtocol & SSL_PROTOCOL_SSLV2))
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
- if (!(sc->nProxyProtocol & SSL_PROTOCOL_SSLV3))
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
- if (!(sc->nProxyProtocol & SSL_PROTOCOL_TLSV1))
- SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
-
- if (sc->szProxyClientCertificateFile || sc->szProxyClientCertificatePath) {
- sk = sk_X509_INFO_new_null();
- if (sc->szProxyClientCertificateFile)
- SSL_load_CrtAndKeyInfo_file(p, sk, sc->szProxyClientCertificateFile);
- if (sc->szProxyClientCertificatePath)
- SSL_load_CrtAndKeyInfo_path(p, sk, sc->szProxyClientCertificatePath);
- ssl_log(s, SSL_LOG_TRACE, "Init: (%s) loaded %d client certs for SSL proxy",
- cpVHostID, sk_X509_INFO_num(sk));
- if (sk_X509_INFO_num(sk) > 0) {
- SSL_CTX_set_client_cert_cb(ctx, ssl_ext_mp_clientcert_cb);
- sc->skProxyClientCerts = sk;
- }
- }
-
- /*
- * Calculate OpenSSL verify type for verifying the remote server
- * certificate. We either verify it against our list of CA's, or don't
- * bother at all.
- */
- nVerify = SSL_VERIFY_NONE;
- if (sc->bProxyVerify)
- nVerify |= SSL_VERIFY_PEER;
- if ( nVerify & SSL_VERIFY_PEER
- && sc->szProxyCACertificateFile == NULL
- && sc->szProxyCACertificatePath == NULL) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) SSLProxyVerify set to On but no CA certificates configured",
- cpVHostID);
- ssl_die();
- }
- if ( nVerify & SSL_VERIFY_NONE
- && ( sc->szProxyCACertificateFile != NULL
- || sc->szProxyCACertificatePath != NULL)) {
- ssl_log(s, SSL_LOG_WARN,
- "init: (%s) CA certificates configured but ignored because SSLProxyVerify is Off",
- cpVHostID);
- }
- SSL_CTX_set_verify(ctx, nVerify, ssl_ext_mp_verify_cb);
-
- /*
- * Enable session caching. We can safely use the same cache
- * as used for communicating with the other clients.
- */
- SSL_CTX_sess_set_new_cb(sc->pSSLProxyCtx, ssl_callback_NewSessionCacheEntry);
- SSL_CTX_sess_set_get_cb(sc->pSSLProxyCtx, ssl_callback_GetSessionCacheEntry);
- SSL_CTX_sess_set_remove_cb(sc->pSSLProxyCtx, ssl_callback_DelSessionCacheEntry);
-
- /*
- * Configure SSL Cipher Suite
- */
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring permitted SSL ciphers for SSL proxy", cpVHostID);
- if (sc->szProxyCipherSuite != NULL) {
- if (!SSL_CTX_set_cipher_list(sc->pSSLProxyCtx, sc->szProxyCipherSuite)) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure permitted SSL ciphers for SSL Proxy",
- cpVHostID);
- ssl_die();
- }
- }
-
- /*
- * Configure Client Authentication details
- */
- if (sc->szProxyCACertificateFile != NULL || sc->szProxyCACertificatePath != NULL) {
- ssl_log(s, SSL_LOG_DEBUG,
- "Init: (%s) Configuring client verification locations for SSL Proxy",
- cpVHostID);
- if (!SSL_CTX_load_verify_locations(sc->pSSLProxyCtx,
- sc->szProxyCACertificateFile,
- sc->szProxyCACertificatePath)) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure SSL verify locations for SSL proxy",
- cpVHostID);
- ssl_die();
- }
- }
- }
- return;
-}
-#endif /* SSL_EXPERIMENTAL_PROXY */
-
-static int ssl_ext_mp_canon(request_rec *r, char *url)
-{
- int rc;
-
- if (strcEQn(url, "https:", 6)) {
- 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 (strcEQ(protocol, "https")) {
- ap_ctx_set(r->ctx, "ssl::proxy::enabled", PTRUE);
- ap_hook_call("ap::mod_proxy::http::handler",
- &rc, r, cr, url, proxyhost, proxyport);
- return rc;
- }
- else {
- ap_ctx_set(r->ctx, "ssl::proxy::enabled", PFALSE);
- }
- return DECLINED;
-}
-
-static int ssl_ext_mp_set_destport(request_rec *r)
-{
- if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PTRUE)
- return DEFAULT_HTTPS_PORT;
- else
- return DEFAULT_HTTP_PORT;
-}
-
-static char *ssl_ext_mp_new_connection(request_rec *r, BUFF *fb,
- char *peer)
-{
-#ifndef SSL_EXPERIMENTAL_PROXY
- SSL_CTX *ssl_ctx;
-#endif
- SSL *ssl;
- char *errmsg;
- int rc;
- char *cpVHostID;
- char *cpVHostMD5;
-#ifdef SSL_EXPERIMENTAL_PROXY
- SSLSrvConfigRec *sc;
- char *cp;
-#endif
-
- if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PFALSE)
- return NULL;
-
- /*
- * Find context
- */
-#ifdef SSL_EXPERIMENTAL_PROXY
- sc = mySrvConfig(r->server);
-#endif
- cpVHostID = ssl_util_vhostid(r->pool, r->server);
-
- /*
- * Create a SSL context and handle
- */
-#ifdef SSL_EXPERIMENTAL_PROXY
- ssl = SSL_new(sc->pSSLProxyCtx);
-#else
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- ssl = SSL_new(ssl_ctx);
-#endif
- if (ssl == NULL) {
- errmsg = ap_psprintf(r->pool, "SSL proxy new failed (%s): peer %s: %s",
- cpVHostID, peer, ERR_reason_error_string(ERR_get_error()));
- ap_ctx_set(fb->ctx, "ssl", NULL);
- return errmsg;
- }
- SSL_clear(ssl);
- cpVHostMD5 = ap_md5(r->pool, (unsigned char *)cpVHostID);
- if (!SSL_set_session_id_context(ssl, (unsigned char *)cpVHostMD5, strlen(cpVHostMD5))) {
- errmsg = ap_psprintf(r->pool, "Unable to set session id context to `%s': peer %s: %s",
- cpVHostMD5, peer, ERR_reason_error_string(ERR_get_error()));
- ap_ctx_set(fb->ctx, "ssl", NULL);
- return errmsg;
- }
- SSL_set_fd(ssl, fb->fd);
-#ifdef SSL_EXPERIMENTAL_PROXY
- SSL_set_app_data(ssl, fb->ctx);
-#endif
- ap_ctx_set(fb->ctx, "ssl", ssl);
-#ifdef SSL_EXPERIMENTAL_PROXY
- ap_ctx_set(fb->ctx, "ssl::proxy::server_rec", r->server);
- ap_ctx_set(fb->ctx, "ssl::proxy::peer", peer);
- ap_ctx_set(fb->ctx, "ssl::proxy::servername", cpVHostID);
- ap_ctx_set(fb->ctx, "ssl::proxy::verifyerror", NULL);
-#endif
-
- /*
- * Give us a chance to gracefully close the connection
- */
- 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) {
-#ifdef SSL_EXPERIMENTAL_PROXY
- if ((cp = (char *)ap_ctx_get(fb->ctx, "ssl::proxy::verifyerror")) != NULL) {
- SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
- SSL_smart_shutdown(ssl);
- SSL_free(ssl);
- ap_ctx_set(fb->ctx, "ssl", NULL);
- ap_bsetflag(fb, B_EOF|B_EOUT, 1);
- return NULL;
- }
-#endif
- errmsg = ap_psprintf(r->pool, "SSL proxy connect failed (%s): peer %s: %s",
- cpVHostID, peer, ERR_reason_error_string(ERR_get_error()));
- ssl_log(r->server, SSL_LOG_ERROR, "%s", errmsg);
- SSL_free(ssl);
- ap_ctx_set(fb->ctx, "ssl", NULL);
- return errmsg;
- }
-
- return NULL;
-}
-
-static void ssl_ext_mp_close_connection(void *_fb)
-{
- BUFF *fb = _fb;
- SSL *ssl;
-#ifndef SSL_EXPERIMENTAL_PROXY
- SSL_CTX *ctx;
-#endif
-
- ssl = ap_ctx_get(fb->ctx, "ssl");
- if (ssl != NULL) {
-#ifndef SSL_EXPERIMENTAL_PROXY
- ctx = SSL_get_SSL_CTX(ssl);
-#endif
- SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
- SSL_smart_shutdown(ssl);
- SSL_free(ssl);
- ap_ctx_set(fb->ctx, "ssl", NULL);
-#ifndef SSL_EXPERIMENTAL_PROXY
- if (ctx != NULL)
- SSL_CTX_free(ctx);
-#endif
- }
- return;
-}
-
-static int ssl_ext_mp_write_host_header(
- request_rec *r, BUFF *fb, char *host, char *port, char *portstr)
-{
- char defport[16];
-
- if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PFALSE)
- return DECLINED;
-
- ap_snprintf(defport, sizeof(defport), "%d", DEFAULT_HTTPS_PORT);
- if (portstr != NULL && strcmp(portstr, defport)) {
- ap_bvputs(fb, "Host: ", host, ":", portstr, "\r\n", NULL);
- return OK;
- }
- return DECLINED;
-}
-
-#ifdef SSL_EXPERIMENTAL_PROXY
-
-/*
- * Callback for client certificate stuff.
- * If the remote site sent us a SSLv3 list of acceptable CA's then trawl the
- * table of client certs and send the first one that matches.
- */
-static int ssl_ext_mp_clientcert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
-{
- SSLSrvConfigRec *sc;
- X509_NAME *xnx;
- X509_NAME *issuer;
- X509_INFO *xi;
- char *peer;
- char *servername;
- server_rec *s;
- ap_ctx *pCtx;
- STACK_OF(X509_NAME) *sk;
- STACK_OF(X509_INFO) *pcerts;
- char *cp;
- int i, j;
-
- pCtx = (ap_ctx *)SSL_get_app_data(ssl);
- s = ap_ctx_get(pCtx, "ssl::proxy::server_rec");
- peer = ap_ctx_get(pCtx, "ssl::proxy::peer");
- servername = ap_ctx_get(pCtx, "ssl::proxy::servername");
-
- sc = mySrvConfig(s);
- pcerts = sc->skProxyClientCerts;
-
- ssl_log(s, SSL_LOG_DEBUG,
- "Proxy client certificate callback: (%s) entered", servername);
-
- if ((pcerts == NULL) || (sk_X509_INFO_num(pcerts) <= 0)) {
- ssl_log(s, SSL_LOG_TRACE,
- "Proxy client certificate callback: (%s) "
- "site wanted client certificate but none available",
- servername);
- return 0;
- }
-
- sk = SSL_get_client_CA_list(ssl);
-
- if ((sk == NULL) || (sk_X509_NAME_num(sk) <= 0)) {
- /*
- * remote site didn't send us a list of acceptable CA certs,
- * so lets send the first one we came across
- */
- xi = sk_X509_INFO_value(pcerts, 0);
- cp = X509_NAME_oneline(X509_get_subject_name(xi->x509), NULL, 0);
- ssl_log(s, SSL_LOG_DEBUG,
- "SSL Proxy: (%s) no acceptable CA list, sending %s",
- servername, cp != NULL ? cp : "-unknown-");
- OPENSSL_free(cp);
- /* export structures to the caller */
- *x509 = xi->x509;
- *pkey = xi->x_pkey->dec_pkey;
- /* prevent OpenSSL freeing these structures */
- CRYPTO_add(&((*x509)->references), +1, CRYPTO_LOCK_X509_PKEY);
- CRYPTO_add(&((*pkey)->references), +1, CRYPTO_LOCK_X509_PKEY);
- return 1;
- }
-
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- xnx = sk_X509_NAME_value(sk, i);
- for (j = 0; j < sk_X509_INFO_num(pcerts); j++) {
- xi = sk_X509_INFO_value(pcerts,j);
- issuer = X509_get_issuer_name(xi->x509);
- if (X509_NAME_cmp(issuer, xnx) == 0) {
- cp = X509_NAME_oneline(X509_get_subject_name(xi->x509), NULL, 0);
- ssl_log(s, SSL_LOG_DEBUG, "SSL Proxy: (%s) sending %s",
- servername, cp != NULL ? cp : "-unknown-");
- OPENSSL_free(cp);
- /* export structures to the caller */
- *x509 = xi->x509;
- *pkey = xi->x_pkey->dec_pkey;
- /* prevent OpenSSL freeing these structures */
- CRYPTO_add(&((*x509)->references), +1, CRYPTO_LOCK_X509_PKEY);
- CRYPTO_add(&((*pkey)->references), +1, CRYPTO_LOCK_X509_PKEY);
- return 1;
- }
- }
- }
- ssl_log(s, SSL_LOG_TRACE,
- "Proxy client certificate callback: (%s) "
- "no client certificate found!?", servername);
- return 0;
-}
-
-/*
- * This is the verify callback when we are connecting to a remote SSL server
- * from the proxy. Information is passed in via the SSL "ctx" app_data
- * mechanism. We pass in an Apache context in this field, which contains
- * server_rec of the server making the proxy connection from the
- * "ssl::proxy::server_rec" context.
- *
- * The result of the verification is passed back out to SSLERR via the return
- * value. We also store the error message in the "proxyverifyfailed" context,
- * so the caller of SSL_connect() can log a detailed error message.
- */
-static int ssl_ext_mp_verify_cb(int ok, X509_STORE_CTX *ctx)
-{
- SSLSrvConfigRec *sc;
- X509 *xs;
- int errnum;
- int errdepth;
- char *cp, *cp2;
- ap_ctx *pCtx;
- server_rec *s;
- SSL *ssl;
- char *peer;
- char *servername;
-
- ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
- pCtx = (ap_ctx *)SSL_get_app_data(ssl);
- s = ap_ctx_get(pCtx, "ssl::proxy::server_rec");
- peer = ap_ctx_get(pCtx, "ssl::proxy::peer");
- servername = ap_ctx_get(pCtx, "ssl::proxy::servername");
- sc = mySrvConfig(s);
-
- /*
- * Unless stated otherwise by the configuration, we really don't
- * care if the verification was okay or not, so lets return now
- * before we do anything involving memory or time.
- */
- if (sc->bProxyVerify == FALSE)
- return ok;
-
- /*
- * 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_DEBUG,
- "SSL Proxy: (%s) Certificate Verification for remote server %s: "
- "depth: %d, subject: %s, issuer: %s",
- servername, peer != NULL ? peer : "-unknown-",
- errdepth, cp != NULL ? cp : "-unknown-",
- cp2 != NULL ? cp2 : "-unknown");
- OPENSSL_free(cp);
- OPENSSL_free(cp2);
-
- /*
- * If we already know it's not ok, log the real reason
- */
- if (!ok) {
- ssl_log(s, SSL_LOG_ERROR,
- "SSL Proxy: (%s) Certificate Verification failed for %s: "
- "Error (%d): %s", servername,
- peer != NULL ? peer : "-unknown-",
- errnum, X509_verify_cert_error_string(errnum));
- ap_ctx_set(pCtx, "ssl::proxy::verifyerror",
- (void *)X509_verify_cert_error_string(errnum));
- return ok;
- }
-
- /*
- * Check the depth of the certificate chain
- */
- if (sc->nProxyVerifyDepth > 0) {
- if (errdepth > sc->nProxyVerifyDepth) {
- ssl_log(s, SSL_LOG_ERROR,
- "SSL Proxy: (%s) Certificate Verification failed for %s: "
- "Certificate Chain too long "
- "(chain has %d certificates, but maximum allowed are only %d)",
- servername, peer, errdepth, sc->nProxyVerifyDepth);
- ap_ctx_set(pCtx, "ssl::proxy::verifyerror",
- (void *)X509_verify_cert_error_string(X509_V_ERR_CERT_CHAIN_TOO_LONG));
- ok = FALSE;
- }
- }
-
- /*
- * And finally signal OpenSSL the (perhaps changed) state
- */
- return (ok);
-}
-
-#endif /* SSL_EXPERIMENTAL_PROXY */
-
-/* _________________________________________________________________
-**
-** SSL Extension to mod_status
-** _________________________________________________________________
-*/
-
-static void ssl_ext_ms_display(request_rec *, int, int);
-
-static void ssl_ext_ms_register(void)
-{
- ap_hook_register("ap::mod_status::display", ssl_ext_ms_display, AP_HOOK_NOCTX);
- return;
-}
-
-static void ssl_ext_ms_unregister(void)
-{
- ap_hook_unregister("ap::mod_status::display", ssl_ext_ms_display);
- return;
-}
-
-static void ssl_ext_ms_display_cb(char *str, void *_r)
-{
- request_rec *r = (request_rec *)_r;
- if (str != NULL)
- ap_rputs(str, r);
- return;
-}
-
-static void ssl_ext_ms_display(request_rec *r, int no_table_report, int short_report)
-{
- SSLSrvConfigRec *sc = mySrvConfig(r->server);
-
- if (sc == NULL)
- return;
- if (short_report)
- return;
- ap_rputs("<hr>\n", r);
- ap_rputs("<table cellspacing=0 cellpadding=0>\n", r);
- ap_rputs("<tr><td bgcolor=\"#000000\">\n", r);
- ap_rputs("<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">SSL/TLS Session Cache Status:</font></b>\r", r);
- ap_rputs("</td></tr>\n", r);
- ap_rputs("<tr><td bgcolor=\"#ffffff\">\n", r);
- ssl_scache_status(r->server, r->pool, ssl_ext_ms_display_cb, r);
- ap_rputs("</td></tr>\n", r);
- ap_rputs("</table>\n", r);
- return;
-}
-