]> granicus.if.org Git - apache/blob - modules/ssl/mod_ssl.c
rollback 1844001.
[apache] / modules / ssl / mod_ssl.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*                      _             _
18  *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
19  * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
20  * | | | | | | (_) | (_| |   \__ \__ \ |
21  * |_| |_| |_|\___/ \__,_|___|___/___/_|
22  *                      |_____|
23  *  mod_ssl.c
24  *  Apache API interface structures
25  */
26
27 #include "ssl_private.h"
28 #include "mod_ssl.h"
29 #include "mod_ssl_openssl.h"
30 #include "util_md5.h"
31 #include "util_mutex.h"
32 #include "ap_provider.h"
33 #include "http_config.h"
34
35 #include "apr_crypto.h"
36 #include "apr_version.h"
37 #if APR_VERSION_AT_LEAST(2,0,0) && \
38     defined(APU_HAVE_CRYPTO) && APU_HAVE_CRYPTO && \
39     defined(APU_HAVE_OPENSSL) && APU_HAVE_OPENSSL
40 #define USE_APR_CRYPTO_LIB_INIT 1
41 #else
42 #define USE_APR_CRYPTO_LIB_INIT 0
43 #endif
44
45 #include "mod_proxy.h" /* for proxy_hook_section_post_config() */
46
47 #include <assert.h>
48
49 #if HAVE_VALGRIND
50 #include <valgrind.h>
51 int ssl_running_on_valgrind = 0;
52 #endif
53 static int modssl_running_statically = 0;
54
55 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, pre_handshake,
56                                     (conn_rec *c,SSL *ssl,int is_proxy),
57                                     (c,ssl,is_proxy), OK, DECLINED);
58
59 /*
60  *  the table of configuration directives we provide
61  */
62
63 #define SSL_CMD_ALL(name, args, desc) \
64         AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
65                        NULL, RSRC_CONF|OR_AUTHCFG, desc),
66
67 #define SSL_CMD_SRV(name, args, desc) \
68         AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
69                        NULL, RSRC_CONF, desc),
70
71 #define SSL_CMD_PXY(name, args, desc) \
72         AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
73                        NULL, RSRC_CONF|PROXY_CONF, desc),
74
75 #define SSL_CMD_DIR(name, type, args, desc) \
76         AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
77                        NULL, OR_##type, desc),
78
79 #define AP_END_CMD { NULL }
80
81 static const command_rec ssl_config_cmds[] = {
82     /*
83      * Global (main-server) context configuration directives
84      */
85     SSL_CMD_SRV(PassPhraseDialog, TAKE1,
86                 "SSL dialog mechanism for the pass phrase query "
87                 "('builtin', '|/path/to/pipe_program', "
88                 "or 'exec:/path/to/cgi_program')")
89     SSL_CMD_SRV(SessionCache, TAKE1,
90                 "SSL Session Cache storage "
91                 "('none', 'nonenotnull', 'dbm:/path/to/file')")
92 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
93     SSL_CMD_SRV(CryptoDevice, TAKE1,
94                 "SSL external Crypto Device usage "
95                 "('builtin', '...')")
96 #endif
97     SSL_CMD_SRV(RandomSeed, TAKE23,
98                 "SSL Pseudo Random Number Generator (PRNG) seeding source "
99                 "('startup|connect builtin|file:/path|exec:/path [bytes]')")
100
101     /*
102      * Per-server context configuration directives
103      */
104     SSL_CMD_SRV(Engine, TAKE1,
105                 "SSL switch for the protocol engine "
106                 "('on', 'off')")
107     SSL_CMD_SRV(FIPS, FLAG,
108                 "Enable FIPS-140 mode "
109                 "(`on', `off')")
110     SSL_CMD_ALL(CipherSuite, TAKE12,
111                 "Colon-delimited list of permitted SSL Ciphers, optional preceeded "
112                 "by protocol identifier ('XXX:...:XXX' - see manual)")
113     SSL_CMD_SRV(CertificateFile, TAKE1,
114                 "SSL Server Certificate file "
115                 "('/path/to/file' - PEM or DER encoded)")
116     SSL_CMD_SRV(CertificateKeyFile, TAKE1,
117                 "SSL Server Private Key file "
118                 "('/path/to/file' - PEM or DER encoded)")
119     SSL_CMD_SRV(CertificateChainFile, TAKE1,
120                 "SSL Server CA Certificate Chain file "
121                 "('/path/to/file' - PEM encoded)")
122 #ifdef HAVE_TLS_SESSION_TICKETS
123     SSL_CMD_SRV(SessionTicketKeyFile, TAKE1,
124                 "TLS session ticket encryption/decryption key file (RFC 5077) "
125                 "('/path/to/file' - file with 48 bytes of random data)")
126 #endif
127     SSL_CMD_ALL(CACertificatePath, TAKE1,
128                 "SSL CA Certificate path "
129                 "('/path/to/dir' - contains PEM encoded files)")
130     SSL_CMD_ALL(CACertificateFile, TAKE1,
131                 "SSL CA Certificate file "
132                 "('/path/to/file' - PEM encoded)")
133     SSL_CMD_SRV(CADNRequestPath, TAKE1,
134                 "SSL CA Distinguished Name path "
135                 "('/path/to/dir' - symlink hashes to PEM of acceptable CA names to request)")
136     SSL_CMD_SRV(CADNRequestFile, TAKE1,
137                 "SSL CA Distinguished Name file "
138                 "('/path/to/file' - PEM encoded to derive acceptable CA names to request)")
139     SSL_CMD_SRV(CARevocationPath, TAKE1,
140                 "SSL CA Certificate Revocation List (CRL) path "
141                 "('/path/to/dir' - contains PEM encoded files)")
142     SSL_CMD_SRV(CARevocationFile, TAKE1,
143                 "SSL CA Certificate Revocation List (CRL) file "
144                 "('/path/to/file' - PEM encoded)")
145     SSL_CMD_SRV(CARevocationCheck, RAW_ARGS,
146                 "SSL CA Certificate Revocation List (CRL) checking mode")
147     SSL_CMD_ALL(VerifyClient, TAKE1,
148                 "SSL Client verify type "
149                 "('none', 'optional', 'require', 'optional_no_ca')")
150     SSL_CMD_ALL(VerifyDepth, TAKE1,
151                 "SSL Client verify depth "
152                 "('N' - number of intermediate certificates)")
153     SSL_CMD_SRV(SessionCacheTimeout, TAKE1,
154                 "SSL Session Cache object lifetime "
155                 "('N' - number of seconds)")
156 #ifdef OPENSSL_NO_SSL3
157 #define SSLv3_PROTO_PREFIX ""
158 #else
159 #define SSLv3_PROTO_PREFIX "SSLv3|"
160 #endif
161 #ifdef HAVE_TLSV1_X
162 #define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1|TLSv1.1|TLSv1.2"
163 #else
164 #define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1"
165 #endif
166     SSL_CMD_SRV(Protocol, RAW_ARGS,
167                 "Enable or disable various SSL protocols "
168                 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
169     SSL_CMD_SRV(HonorCipherOrder, FLAG,
170                 "Use the server's cipher ordering preference")
171     SSL_CMD_SRV(Compression, FLAG,
172                 "Enable SSL level compression "
173                 "(`on', `off')")
174     SSL_CMD_SRV(SessionTickets, FLAG,
175                 "Enable or disable TLS session tickets"
176                 "(`on', `off')")
177     SSL_CMD_SRV(InsecureRenegotiation, FLAG,
178                 "Enable support for insecure renegotiation")
179     SSL_CMD_ALL(UserName, TAKE1,
180                 "Set user name to SSL variable value")
181     SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
182                 "Strict SNI virtual host checking")
183
184 #ifdef HAVE_SRP
185     SSL_CMD_SRV(SRPVerifierFile, TAKE1,
186                 "SRP verifier file "
187                 "('/path/to/file' - created by srptool)")
188     SSL_CMD_SRV(SRPUnknownUserSeed, TAKE1,
189                 "SRP seed for unknown users (to avoid leaking a user's existence) "
190                 "('some secret text')")
191 #endif
192
193     /*
194      * Proxy configuration for remote SSL connections
195      */
196     SSL_CMD_PXY(ProxyEngine, FLAG,
197                 "SSL switch for the proxy protocol engine "
198                 "('on', 'off')")
199     SSL_CMD_PXY(ProxyProtocol, RAW_ARGS,
200                "SSL Proxy: enable or disable SSL protocol flavors "
201                 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
202     SSL_CMD_PXY(ProxyCipherSuite, TAKE12,
203                "SSL Proxy: colon-delimited list of permitted SSL ciphers "
204                ", optionally preceeded by protocol specifier ('XXX:...:XXX' - see manual)")
205     SSL_CMD_PXY(ProxyVerify, TAKE1,
206                "SSL Proxy: whether to verify the remote certificate "
207                "('on' or 'off')")
208     SSL_CMD_PXY(ProxyVerifyDepth, TAKE1,
209                "SSL Proxy: maximum certificate verification depth "
210                "('N' - number of intermediate certificates)")
211     SSL_CMD_PXY(ProxyCACertificateFile, TAKE1,
212                "SSL Proxy: file containing server certificates "
213                "('/path/to/file' - PEM encoded certificates)")
214     SSL_CMD_PXY(ProxyCACertificatePath, TAKE1,
215                "SSL Proxy: directory containing server certificates "
216                "('/path/to/dir' - contains PEM encoded certificates)")
217     SSL_CMD_PXY(ProxyCARevocationPath, TAKE1,
218                 "SSL Proxy: CA Certificate Revocation List (CRL) path "
219                 "('/path/to/dir' - contains PEM encoded files)")
220     SSL_CMD_PXY(ProxyCARevocationFile, TAKE1,
221                 "SSL Proxy: CA Certificate Revocation List (CRL) file "
222                 "('/path/to/file' - PEM encoded)")
223     SSL_CMD_PXY(ProxyCARevocationCheck, RAW_ARGS,
224                 "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
225     SSL_CMD_PXY(ProxyMachineCertificateFile, TAKE1,
226                "SSL Proxy: file containing client certificates "
227                "('/path/to/file' - PEM encoded certificates)")
228     SSL_CMD_PXY(ProxyMachineCertificatePath, TAKE1,
229                "SSL Proxy: directory containing client certificates "
230                "('/path/to/dir' - contains PEM encoded certificates)")
231     SSL_CMD_PXY(ProxyMachineCertificateChainFile, TAKE1,
232                "SSL Proxy: file containing issuing certificates "
233                "of the client certificate "
234                "(`/path/to/file' - PEM encoded certificates)")
235     SSL_CMD_PXY(ProxyCheckPeerExpire, FLAG,
236                 "SSL Proxy: check the peer certificate's expiration date")
237     SSL_CMD_PXY(ProxyCheckPeerCN, FLAG,
238                 "SSL Proxy: check the peer certificate's CN")
239     SSL_CMD_PXY(ProxyCheckPeerName, FLAG,
240                 "SSL Proxy: check the peer certificate's name "
241                 "(must be present in subjectAltName extension or CN")
242
243     /*
244      * Per-directory context configuration directives
245      */
246     SSL_CMD_DIR(Options, OPTIONS, RAW_ARGS,
247                "Set one or more options to configure the SSL engine"
248                "('[+-]option[=value] ...' - see manual)")
249     SSL_CMD_DIR(RequireSSL, AUTHCFG, NO_ARGS,
250                "Require the SSL protocol for the per-directory context "
251                "(no arguments)")
252     SSL_CMD_DIR(Require, AUTHCFG, RAW_ARGS,
253                "Require a boolean expression to evaluate to true for granting access"
254                "(arbitrary complex boolean expression - see manual)")
255     SSL_CMD_DIR(RenegBufferSize, AUTHCFG, TAKE1,
256                 "Configure the amount of memory that will be used for buffering the "
257                 "request body if a per-location SSL renegotiation is required due to "
258                 "changed access control requirements")
259
260     SSL_CMD_SRV(OCSPEnable, RAW_ARGS,
261                "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')")
262     SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
263                "URL of the default OCSP Responder")
264     SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
265                "Force use of the default responder URL ('on', 'off')")
266     SSL_CMD_SRV(OCSPResponseTimeSkew, TAKE1,
267                 "Maximum time difference in OCSP responses")
268     SSL_CMD_SRV(OCSPResponseMaxAge, TAKE1,
269                 "Maximum age of OCSP responses")
270     SSL_CMD_SRV(OCSPResponderTimeout, TAKE1,
271                 "OCSP responder query timeout")
272     SSL_CMD_SRV(OCSPUseRequestNonce, FLAG,
273                 "Whether OCSP queries use a nonce or not ('on', 'off')")
274     SSL_CMD_SRV(OCSPProxyURL, TAKE1,
275                 "Proxy URL to use for OCSP requests")
276
277 /* Define OCSP Responder Certificate Verification Directive */
278     SSL_CMD_SRV(OCSPNoVerify, FLAG,
279                 "Do not verify OCSP Responder certificate ('on', 'off')")
280 /* Define OCSP Responder File Configuration Directive */
281     SSL_CMD_SRV(OCSPResponderCertificateFile, TAKE1,
282                "Trusted OCSP responder certificates"
283                "(`/path/to/file' - PEM encoded certificates)")
284
285 #ifdef HAVE_OCSP_STAPLING
286     /*
287      * OCSP Stapling options
288      */
289     SSL_CMD_SRV(StaplingCache, TAKE1,
290                 "SSL Stapling Response Cache storage "
291                 "(`dbm:/path/to/file')")
292     SSL_CMD_SRV(UseStapling, FLAG,
293                 "SSL switch for the OCSP Stapling protocol " "(`on', `off')")
294     SSL_CMD_SRV(StaplingResponseTimeSkew, TAKE1,
295                 "SSL stapling option for maximum time difference in OCSP responses")
296     SSL_CMD_SRV(StaplingResponderTimeout, TAKE1,
297                 "SSL stapling option for OCSP responder timeout")
298     SSL_CMD_SRV(StaplingResponseMaxAge, TAKE1,
299                 "SSL stapling option for maximum age of OCSP responses")
300     SSL_CMD_SRV(StaplingStandardCacheTimeout, TAKE1,
301                 "SSL stapling option for normal OCSP Response Cache Lifetime")
302     SSL_CMD_SRV(StaplingReturnResponderErrors, FLAG,
303                 "SSL stapling switch to return Status Errors Back to Client"
304                 "(`on', `off')")
305     SSL_CMD_SRV(StaplingFakeTryLater, FLAG,
306                 "SSL stapling switch to send tryLater response to client on error "
307                 "(`on', `off')")
308     SSL_CMD_SRV(StaplingErrorCacheTimeout, TAKE1,
309                 "SSL stapling option for OCSP Response Error Cache Lifetime")
310     SSL_CMD_SRV(StaplingForceURL, TAKE1,
311                 "SSL stapling option to Force the OCSP Stapling URL")
312 #endif
313
314 #ifdef HAVE_SSL_CONF_CMD
315     SSL_CMD_SRV(OpenSSLConfCmd, TAKE2,
316                 "OpenSSL configuration command")
317 #endif
318
319     /* Deprecated directives. */
320     AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL,
321       "SSLLog directive is no longer supported - use ErrorLog."),
322     AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL,
323       "SSLLogLevel directive is no longer supported - use LogLevel."),
324
325     AP_INIT_TAKE1("SSLPolicy", ssl_cmd_SSLPolicyApply, NULL, RSRC_CONF, 
326                 "Apply the SSL* (not the SSLProxy*) settings from the policy with the given name."),
327     AP_END_CMD
328 };
329
330 /*
331  *  the various processing hooks
332  */
333 static int modssl_is_prelinked(void)
334 {
335     apr_size_t i = 0;
336     const module *mod;
337     while ((mod = ap_prelinked_modules[i++])) {
338         if (strcmp(mod->name, "mod_ssl.c") == 0) {
339             return 1;
340         }
341     }
342     return 0;
343 }
344
345 #if !USE_APR_CRYPTO_LIB_INIT
346 static apr_status_t ssl_cleanup_pre_config(void *data)
347 {
348     /*
349      * Try to kill the internals of the SSL library.
350      */
351 #ifdef HAVE_FIPS
352     FIPS_mode_set(0);
353 #endif
354     /* Corresponds to OBJ_create()s */
355     OBJ_cleanup();
356     /* Corresponds to OPENSSL_load_builtin_modules() */
357     CONF_modules_free();
358     /* Corresponds to SSL_library_init: */
359     EVP_cleanup();
360 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
361     ENGINE_cleanup();
362 #endif
363 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
364 #ifndef OPENSSL_NO_COMP
365     SSL_COMP_free_compression_methods();
366 #endif
367 #endif
368
369     /* Usually needed per thread, but this parent process is single-threaded */
370 #if MODSSL_USE_OPENSSL_PRE_1_1_API
371 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
372     ERR_remove_thread_state(NULL);
373 #else
374     ERR_remove_state(0);
375 #endif
376 #endif
377
378     /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
379      * actually loaded the error strings once per process due to static
380      * variable abuse in OpenSSL. */
381 #if (OPENSSL_VERSION_NUMBER >= 0x00090805f)
382     ERR_free_strings();
383 #endif
384
385     /* Also don't call CRYPTO_cleanup_all_ex_data when linked statically here;
386      * any registered ex_data indices may have been cached in static variables
387      * in OpenSSL; removing them may cause havoc.  Notably, with OpenSSL
388      * versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
389      * could result in a per-connection memory leak (!). */
390     if (!modssl_running_statically) {
391         CRYPTO_cleanup_all_ex_data();
392     }
393
394     /*
395      * TODO: determine somewhere we can safely shove out diagnostics
396      *       (when enabled) at this late stage in the game:
397      * CRYPTO_mem_leaks_fp(stderr);
398      */
399     return APR_SUCCESS;
400 }
401 #endif /* !USE_APR_CRYPTO_LIB_INIT */
402
403 static int ssl_hook_pre_config(apr_pool_t *pconf,
404                                apr_pool_t *plog,
405                                apr_pool_t *ptemp)
406 {
407 #if HAVE_VALGRIND
408     ssl_running_on_valgrind = RUNNING_ON_VALGRIND;
409 #endif
410     modssl_running_statically = modssl_is_prelinked();
411
412 #if USE_APR_CRYPTO_LIB_INIT
413     {
414         /* When mod_ssl is builtin, no need to unload openssl on restart,
415          * so use pglobal.
416          */
417         apr_pool_t *p = modssl_running_statically ? ap_pglobal : pconf;
418         apr_status_t rv = apr_crypto_lib_init("openssl", NULL, NULL, p);
419         if (rv != APR_SUCCESS && rv != APR_EREINIT) {
420             ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pconf, APLOGNO(10155)
421                           "mod_ssl: can't initialize OpenSSL library");
422             return !OK;
423         }
424     }
425 #else /* USE_APR_CRYPTO_LIB_INIT */
426     {
427         /* We must register the library in full, to ensure our configuration
428          * code can successfully test the SSL environment.
429          */
430 /* Both undefined (or no-op) with LibreSSL */
431 #if !defined(LIBRESSL_VERSION_NUMBER)
432 #if MODSSL_USE_OPENSSL_PRE_1_1_API
433         CRYPTO_malloc_init();
434 #else
435         OPENSSL_malloc_init();
436 #endif
437 #endif
438         ERR_load_crypto_strings();
439 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
440         ENGINE_load_builtin_engines();
441 #endif
442         OpenSSL_add_all_algorithms();
443         OPENSSL_load_builtin_modules();
444
445         SSL_load_error_strings();
446         SSL_library_init();
447
448         /*
449          * Let us cleanup the ssl library when the module is unloaded
450          */
451         apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config,
452                                                apr_pool_cleanup_null);
453     }
454
455 #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
456     /* Some OpenSSL internals are allocated per-thread, make sure they
457      * are associated to the/our same thread-id until cleaned up. Then
458      * initialize all the thread locking stuff needed by the lib.
459      */
460     ssl_util_thread_id_setup(pconf);
461     ssl_util_thread_setup(pconf);
462 #endif
463 #endif /* USE_APR_CRYPTO_LIB_INIT */
464
465     if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) {
466         (void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV",
467                          "SRVName otherName form");
468     }
469
470     /* Start w/o errors (e.g. OBJ_txt2nid() above) */
471     ERR_clear_error();
472
473     /* Register us to handle mod_log_config %c/%x variables */
474     ssl_var_log_config_register(pconf);
475
476     /* Register to handle mod_status status page generation */
477     ssl_scache_status_register(pconf);
478
479     /* Register mutex type names so they can be configured with Mutex */
480     ap_mutex_register(pconf, SSL_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
481 #ifdef HAVE_OCSP_STAPLING
482     ap_mutex_register(pconf, SSL_STAPLING_CACHE_MUTEX_TYPE, NULL,
483                       APR_LOCK_DEFAULT, 0);
484     ap_mutex_register(pconf, SSL_STAPLING_REFRESH_MUTEX_TYPE, NULL,
485                       APR_LOCK_DEFAULT, 0);
486 #endif
487
488     return OK;
489 }
490
491 static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
492                                            ap_conf_vector_t *per_dir_config)
493 {
494     SSLConnRec *sslconn = myConnConfig(c);
495     SSLSrvConfigRec *sc;
496
497     if (sslconn) {
498         return sslconn;
499     }
500
501     sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
502
503     if (per_dir_config) {
504         sslconn->dc = ap_get_module_config(per_dir_config, &ssl_module);
505     }
506     else {
507         sslconn->dc = ap_get_module_config(c->base_server->lookup_defaults,
508                                            &ssl_module);
509     }
510
511     sslconn->server = c->base_server;
512     sslconn->verify_depth = UNSET;
513     sc = mySrvConfig(c->base_server);
514     sslconn->cipher_suite = sc->server->auth.cipher_suite;
515
516     myConnConfigSet(c, sslconn);
517
518     return sslconn;
519 }
520
521 static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
522 {
523     if (c->master) {
524         return DECLINED;
525     }
526     if (sslconn) {
527         if (sslconn->disabled) {
528             return SUSPENDED;
529         }
530         if (sslconn->is_proxy) {
531             if (!sslconn->dc->proxy_enabled) {
532                 return DECLINED;
533             }
534         }
535         else {
536             if (mySrvConfig(sslconn->server)->enabled != SSL_ENABLED_TRUE) {
537                 return DECLINED;
538             }
539         }
540     }
541     else {
542         if (mySrvConfig(c->base_server)->enabled != SSL_ENABLED_TRUE) {
543             return DECLINED;
544         }
545     }
546     return OK;
547 }
548
549 static int ssl_engine_set(conn_rec *c,
550                           ap_conf_vector_t *per_dir_config,
551                           int proxy, int enable)
552 {
553     SSLConnRec *sslconn;
554     int status;
555     
556     if (proxy) {
557         sslconn = ssl_init_connection_ctx(c, per_dir_config);
558         sslconn->is_proxy = 1;
559     }
560     else {
561         sslconn = myConnConfig(c);
562     }
563
564     status = ssl_engine_status(c, sslconn);
565
566     if (proxy && status == DECLINED) {
567         if (enable) {
568             SSLSrvConfigRec *sc = mySrvConfig(sslconn->server);
569             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
570                           "SSL Proxy requested for %s but not enabled "
571                           "[Hint: SSLProxyEngine]", sc->vhost_id);
572         }
573         sslconn->disabled = 1;
574     }
575     else if (sslconn) {
576         sslconn->disabled = !enable;
577     }
578
579     return status != DECLINED;
580 }
581
582 static int ssl_proxy_enable(conn_rec *c)
583 {
584     return ssl_engine_set(c, NULL, 1, 1);
585 }
586
587 static int ssl_engine_disable(conn_rec *c)
588 {
589     return ssl_engine_set(c, NULL, 0, 0);
590 }
591
592 int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
593 {
594     SSLSrvConfigRec *sc;
595     SSL *ssl;
596     SSLConnRec *sslconn;
597     char *vhost_md5;
598     int rc;
599     modssl_ctx_t *mctx;
600     server_rec *server;
601
602     /*
603      * Create or retrieve SSL context
604      */
605     sslconn = ssl_init_connection_ctx(c, r ? r->per_dir_config : NULL);
606     server = sslconn->server;
607     sc = mySrvConfig(server);
608
609     /*
610      * Seed the Pseudo Random Number Generator (PRNG)
611      */
612     ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT,
613                   sslconn->is_proxy ? "Proxy: " : "Server: ");
614
615     mctx = myCtxConfig(sslconn, sc);
616
617     /*
618      * Create a new SSL connection with the configured server SSL context and
619      * attach this to the socket. Additionally we register this attachment
620      * so we can detach later.
621      */
622     if (!(sslconn->ssl = ssl = SSL_new(mctx->ssl_ctx))) {
623         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01962)
624                       "Unable to create a new SSL connection from the SSL "
625                       "context");
626         ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
627
628         c->aborted = 1;
629
630         return DECLINED; /* XXX */
631     }
632
633     rc = ssl_run_pre_handshake(c, ssl, sslconn->is_proxy ? 1 : 0);
634     if (rc != OK && rc != DECLINED) {
635         return rc;
636     }
637
638     vhost_md5 = ap_md5_binary(c->pool, (unsigned char *)sc->vhost_id,
639                               sc->vhost_id_len);
640
641     if (!SSL_set_session_id_context(ssl, (unsigned char *)vhost_md5,
642                                     APR_MD5_DIGESTSIZE*2))
643     {
644         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01963)
645                       "Unable to set session id context to '%s'", vhost_md5);
646         ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
647
648         c->aborted = 1;
649
650         return DECLINED; /* XXX */
651     }
652
653     SSL_set_app_data(ssl, c);
654     modssl_set_app_data2(ssl, NULL); /* will be request_rec */
655
656     SSL_set_verify_result(ssl, X509_V_OK);
657
658     ssl_io_filter_init(c, r, ssl);
659
660     return APR_SUCCESS;
661 }
662
663 static const char *ssl_hook_http_scheme(const request_rec *r)
664 {
665     return modssl_request_is_tls(r, NULL) ? "https" : NULL;
666 }
667
668 static apr_port_t ssl_hook_default_port(const request_rec *r)
669 {
670     return modssl_request_is_tls(r, NULL) ? 443 : 0;
671 }
672
673 static int ssl_hook_pre_connection(conn_rec *c, void *csd)
674 {
675     SSLSrvConfigRec *sc;
676     SSLConnRec *sslconn = myConnConfig(c);
677
678     /*
679      * Immediately stop processing if SSL is disabled for this connection
680      */
681     if (ssl_engine_status(c, sslconn) != OK) {
682         return DECLINED;
683     }
684
685     if (sslconn) {
686         sc = mySrvConfig(sslconn->server);
687     }
688     else {
689         sc = mySrvConfig(c->base_server);
690     }
691
692     /*
693      * Remember the connection information for
694      * later access inside callback functions
695      */
696
697     ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(01964)
698                   "Connection to child %ld established "
699                   "(server %s)", c->id, sc->vhost_id);
700
701     return ssl_init_ssl_connection(c, NULL);
702 }
703
704 static int ssl_hook_process_connection(conn_rec* c)
705 {
706     SSLConnRec *sslconn = myConnConfig(c);
707
708     if (sslconn && !sslconn->disabled) {
709         /* On an active SSL connection, let the input filters initialize
710          * themselves which triggers the handshake, which again triggers
711          * all kinds of useful things such as SNI and ALPN.
712          */
713         apr_bucket_brigade* temp;
714
715         temp = apr_brigade_create(c->pool, c->bucket_alloc);
716         ap_get_brigade(c->input_filters, temp,
717                        AP_MODE_INIT, APR_BLOCK_READ, 0);
718         apr_brigade_destroy(temp);
719     }
720     
721     return DECLINED;
722 }
723
724 /*
725  *  the module registration phase
726  */
727
728 static void ssl_register_hooks(apr_pool_t *p)
729 {
730     /* ssl_hook_ReadReq needs to use the BrowserMatch settings so must
731      * run after mod_setenvif's post_read_request hook. */
732     static const char *pre_prr[] = { "mod_setenvif.c", NULL };
733     /* The ssl_init_Module post_config hook should run before mod_proxy's
734      * for the ssl proxy main configs to be merged with vhosts' before being
735      * themselves merged with mod_proxy's in proxy_hook_section_post_config.
736      */
737     static const char *b_pc[] = { "mod_proxy.c", NULL};
738
739
740     ssl_io_filter_register(p);
741
742     ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);
743     ap_hook_process_connection(ssl_hook_process_connection, 
744                                                    NULL, NULL, APR_HOOK_MIDDLE);
745     ap_hook_test_config   (ssl_hook_ConfigTest,    NULL,NULL, APR_HOOK_MIDDLE);
746     ap_hook_post_config   (ssl_init_Module,        NULL,b_pc, APR_HOOK_MIDDLE);
747     ap_hook_http_scheme   (ssl_hook_http_scheme,   NULL,NULL, APR_HOOK_MIDDLE);
748     ap_hook_default_port  (ssl_hook_default_port,  NULL,NULL, APR_HOOK_MIDDLE);
749     ap_hook_pre_config    (ssl_hook_pre_config,    NULL,NULL, APR_HOOK_MIDDLE);
750     ap_hook_child_init    (ssl_init_Child,         NULL,NULL, APR_HOOK_MIDDLE);
751     ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE);
752     ap_hook_check_access  (ssl_hook_Access,        NULL,NULL, APR_HOOK_MIDDLE,
753                            AP_AUTH_INTERNAL_PER_CONF);
754     ap_hook_check_authn   (ssl_hook_UserCheck,     NULL,NULL, APR_HOOK_FIRST,
755                            AP_AUTH_INTERNAL_PER_CONF);
756     ap_hook_check_authz   (ssl_hook_Auth,          NULL,NULL, APR_HOOK_MIDDLE,
757                            AP_AUTH_INTERNAL_PER_CONF);
758     ap_hook_fixups        (ssl_hook_Fixup,         NULL,NULL, APR_HOOK_MIDDLE);
759
760     APR_OPTIONAL_HOOK(proxy, section_post_config,
761                       ssl_proxy_section_post_config, NULL, NULL,
762                       APR_HOOK_MIDDLE);
763
764     ssl_var_register(p);
765
766     APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
767     APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
768     APR_REGISTER_OPTIONAL_FN(ssl_engine_set);
769
770     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
771                               AUTHZ_PROVIDER_VERSION,
772                               &ssl_authz_provider_require_ssl,
773                               AP_AUTH_INTERNAL_PER_CONF);
774
775     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-verify-client",
776                               AUTHZ_PROVIDER_VERSION,
777                               &ssl_authz_provider_verify_client,
778                               AP_AUTH_INTERNAL_PER_CONF);
779 }
780
781 module AP_MODULE_DECLARE_DATA ssl_module = {
782     STANDARD20_MODULE_STUFF,
783     ssl_config_perdir_create,   /* create per-dir    config structures */
784     ssl_config_perdir_merge,    /* merge  per-dir    config structures */
785     ssl_config_server_create,   /* create per-server config structures */
786     ssl_config_server_merge,    /* merge  per-server config structures */
787     ssl_config_cmds,            /* table of configuration directives   */
788     ssl_register_hooks          /* register hooks */
789 #if defined(AP_MODULE_HAS_FLAGS)
790    ,AP_MODULE_FLAG_ALWAYS_MERGE /* flags */
791 #endif
792 };