⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_engine_kernel.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//*                      _             _ *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL * | | | | | | (_) | (_| |   \__ \__ \ | * |_| |_| |_|\___/ \__,_|___|___/___/_| *                      |_____| *  ssl_engine_kernel.c *  The SSL engine kernel */                             /* ``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"/* *  Post Read Request Handler */int ssl_hook_ReadReq(request_rec *r){    SSLConnRec *sslconn = myConnConfig(r->connection);    SSL *ssl;    if (!sslconn) {        return DECLINED;    }    if (sslconn->non_ssl_request) {        const char *errmsg;        char *thisurl;        char *thisport = "";        int port = ap_get_server_port(r);        if (!ap_is_default_port(port, r)) {            thisport = apr_psprintf(r->pool, ":%u", port);        }        thisurl = ap_escape_html(r->pool,                                 apr_psprintf(r->pool, "https://%s%s/",                                              ap_get_server_name(r),                                              thisport));        errmsg = apr_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);        apr_table_setn(r->notes, "error-notes", errmsg);        /* Now that we have caught this error, forget it. we are done         * with using SSL on this request.         */        sslconn->non_ssl_request = 0;                return HTTP_BAD_REQUEST;    }    /*     * Get the SSL connection structure and perform the     * delayed interlinking from SSL back to request_rec     */    if ((ssl = sslconn->ssl)) {        SSL_set_app_data2(ssl, r);    }    return DECLINED;}/* * Move SetEnvIf information from request_rec to conn_rec/BUFF * to allow the close connection handler to use them. */static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn){    int i;    const apr_array_header_t *arr = apr_table_elts(r->subprocess_env);    const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts;    sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;    for (i = 0; i < arr->nelts; i++) {        const char *key = elts[i].key;        switch (*key) {          case 's':            /* being case-sensitive here.             * and not checking for the -shutdown since these are the only             * SetEnvIf "flags" we support             */            if (!strncmp(key+1, "sl-", 3)) {                key += 4;                if (!strncmp(key, "unclean", 7)) {                    sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;                }                else if (!strncmp(key, "accurate", 8)) {                    sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_ACCURATE;                }                return; /* should only ever be one ssl-*-shutdown */            }            break;        }    }}/* *  URL Translation Handler */int ssl_hook_Translate(request_rec *r){    SSLConnRec *sslconn = myConnConfig(r->connection);    if (!(sslconn && sslconn->ssl)) {        return DECLINED;    }    /*     * Log information about incoming HTTPS requests     */    if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) {        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,                     "%s HTTPS request received for child %ld (server %s)",                     (r->connection->keepalives <= 0 ?                     "Initial (No.1)" :                     apr_psprintf(r->pool, "Subsequent (No.%d)",                                  r->connection->keepalives+1)),                     r->connection->id,                     ssl_util_vhostid(r->pool, r->server));    }    /* SetEnvIf ssl-*-shutdown flags can only be per-server,     * so they won't change across keepalive requests     */    if (sslconn->shutdown_type == SSL_SHUTDOWN_TYPE_UNSET) {        ssl_configure_env(r, sslconn);    }    return DECLINED;}/* *  Access Handler */int ssl_hook_Access(request_rec *r){    SSLDirConfigRec *dc = myDirConfig(r);    SSLSrvConfigRec *sc = mySrvConfig(r->server);    SSLConnRec *sslconn = myConnConfig(r->connection);    SSL *ssl            = sslconn ? sslconn->ssl : NULL;    SSL_CTX *ctx = NULL;    apr_array_header_t *requires;    ssl_require_t *ssl_requires;    char *cp;    int ok, i;    BOOL renegotiate = FALSE, renegotiate_quick = FALSE;    X509 *cert;    X509 *peercert;    X509_STORE *cert_store = NULL;    X509_STORE_CTX cert_store_ctx;    STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;    SSL_CIPHER *cipher = NULL;    int depth, verify_old, verify, n;    if (ssl) {        ctx = SSL_get_SSL_CTX(ssl);    }    /*     * Support for SSLRequireSSL directive     */    if (dc->bSSLRequired && !ssl) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                       "access to %s failed, reason: %s",                      r->filename, "SSL connection required");        /* remember forbidden access for strict require option */        apr_table_setn(r->notes, "ssl-access-forbidden", "1");        return HTTP_FORBIDDEN;    }    /*     * Check to see if SSL protocol is on     */    if (!(sc->enabled || ssl)) {        return DECLINED;    }    /*     * Support for per-directory reconfigured 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 here, because when internal sub-requests occur     * we nevertheless should avoid multiple unnecessary SSL handshakes (they     * require extra network I/O and especially time to perform).      *      * But the optimization for filtering out the unnecessary handshakes isn't     * obvious and trivial.  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 explicitly _ask_ 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 OpenSSL) or (in optimized way) at least when     * the reconfigured parameter suite is stronger (more restrictions) than     * the currently active one.     */    /*     * Override of SSLCipherSuite     *     * We provide two options here:     *     * o The paranoid and default approach where we force a renegotiation when     *   the cipher suite changed in _any_ way (which is straight-forward but     *   often forces renegotiations too often and is perhaps not what the     *   user actually wanted).     *     * o The optimized and still secure way where we force a renegotiation     *   only if the currently active cipher is no longer contained in the     *   reconfigured/new cipher suite. Any other changes are not important     *   because it's the servers choice to select a cipher from the ones the     *   client supports. So as long as the current cipher is still in the new     *   cipher suite we're happy. Because we can assume we would have     *   selected it again even when other (better) ciphers exists now in the     *   new cipher suite. This approach is fine because the user explicitly     *   has to enable this via ``SSLOptions +OptRenegotiate''. So we do no     *   implicit optimizations.     */    if (dc->szCipherSuite) {        /* remember old state */        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {            cipher = SSL_get_current_cipher(ssl);        }        else {            cipher_list_old = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);            if (cipher_list_old) {                cipher_list_old = sk_SSL_CIPHER_dup(cipher_list_old);            }        }        /* configure new state */        if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) {            ap_log_error(APLOG_MARK, APLOG_WARNING, 0,                         r->server,                         "Unable to reconfigure (per-directory) "                         "permitted SSL ciphers");            ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);            if (cipher_list_old) {                sk_SSL_CIPHER_free(cipher_list_old);            }            return HTTP_FORBIDDEN;        }        /* determine whether a renegotiation has to be forced */        cipher_list = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {            /* optimized way */            if ((!cipher && cipher_list) ||                (cipher && !cipher_list))            {                renegotiate = TRUE;            }            else if (cipher && cipher_list &&                     (sk_SSL_CIPHER_find(cipher_list, cipher) < 0))            {                renegotiate = TRUE;            }        }        else {            /* paranoid way */            if ((!cipher_list_old && cipher_list) ||                (cipher_list_old && !cipher_list))            {                renegotiate = TRUE;            }            else if (cipher_list_old && cipher_list) {                for (n = 0;                     !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list));                     n++)                {                    SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n);                    if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) {                        renegotiate = TRUE;                    }                }                for (n = 0;                     !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old));                     n++)                {                    SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n);                    if (sk_SSL_CIPHER_find(cipher_list, value) < 0) {                        renegotiate = TRUE;                    }                }            }        }        /* cleanup */        if (cipher_list_old) {            sk_SSL_CIPHER_free(cipher_list_old);        }        /* tracing */        if (renegotiate) {            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                         "Reconfigured cipher suite will force renegotiation");        }    }    /*     * override of SSLVerifyDepth     *     * The depth checks are handled by us manually inside the verify callback     * function and not by OpenSSL internally (and our function is aware of     * both the per-server and per-directory contexts). So we cannot ask     * OpenSSL about the currently verify depth. Instead we remember it in our     * ap_ctx attached to the SSL* of OpenSSL.  We've to force the     * renegotiation if the reconfigured/new verify depth is less than the     * currently active/remembered verify depth (because this means more     * restriction on the certificate chain).     */    if (dc->nVerifyDepth != UNSET) {        /* XXX: doesnt look like sslconn->verify_depth is actually used */        if (!(n = sslconn->verify_depth)) {            sslconn->verify_depth = n = sc->server->auth.verify_depth;        }        /* determine whether a renegotiation has to be forced */        if (dc->nVerifyDepth < n) {            renegotiate = TRUE;            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                         "Reduced client verification depth will force "                         "renegotiation");        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -