📄 ssl_engine_kernel.c
字号:
else { /* * Ok, anything else is a fatal error */ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR|SSL_ADD_ERRNO, "SSL handshake failed (server %s, client %s)", cpVHostID, conn->remote_ip != NULL ? conn->remote_ip : "unknown"); /* * 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); SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); conn->aborted = 1; ap_set_callback_and_alarm(NULL, 0); ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)FALSE); return; } } /* * Check for failed client authentication */ if ( SSL_get_verify_result(ssl) != X509_V_OK || ap_ctx_get(fb->ctx, "ssl::verify::error") != NULL) { cp = (char *)ap_ctx_get(fb->ctx, "ssl::verify::error"); ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR, "SSL client authentication failed: %s", cp != NULL ? cp : "unknown reason"); 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); conn->aborted = 1; ap_set_callback_and_alarm(NULL, 0); ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)FALSE); return; } /* * Remember the peer certificate's DN */ if ((xs = SSL_get_peer_certificate(ssl)) != NULL) { cp = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0); ap_ctx_set(fb->ctx, "ssl::client::dn", ap_pstrdup(conn->pool, cp)); OPENSSL_free(cp); X509_free(xs); } /* * 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); SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); conn->aborted = 1; ap_set_callback_and_alarm(NULL, 0); ap_ctx_set(ap_global_ctx, "ssl::handshake::timeout", (void *)FALSE); 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 * OpenSSL's read-ahead functionality * (don't used under Win32, because * there we use select()) */#ifndef WIN32 SSL_set_read_ahead(ssl, TRUE);#endif#ifdef SSL_VENDOR /* Allow vendors to do more things on connection time... */ ap_hook_use("ap::mod_ssl::vendor::new_connection", AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL, conn);#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 * (called immediately _before_ the socket is closed) */void ssl_hook_CloseConnection(conn_rec *conn){ SSL *ssl; char *cpType; ssl = ap_ctx_get(conn->client->ctx, "ssl"); if (ssl == NULL) return; /* * First make sure that no more data is pending in Apache's BUFF, * because when it's (implicitly) flushed later by the ap_bclose() * calls of Apache it would lead to an I/O error in the browser due * to the fact that the SSL layer was already removed by us. */ ap_bflush(conn->client); /* * Now close the SSL layer of the connection. We've to take * the TLSv1 standard into account here: * * | 7.2.1. Closure alerts * | * | The client and the server must share knowledge that the connection is * | ending in order to avoid a truncation attack. Either party may * | initiate the exchange of closing messages. * | * | close_notify * | This message notifies the recipient that the sender will not send * | any more messages on this connection. The session becomes * | unresumable if any connection is terminated without proper * | close_notify messages with level equal to warning. * | * | Either party may initiate a close by sending a close_notify alert. * | Any data received after a closure alert is ignored. * | * | Each party is required to send a close_notify alert before closing * | the write side of the connection. It is required that the other party * | respond with a close_notify alert of its own and close down the * | connection immediately, discarding any pending writes. It is not * | required for the initiator of the close to wait for the responding * | close_notify alert before closing the read side of the connection. * * This means we've to send a close notify message, but haven't to wait * for the close notify of the client. Actually we cannot wait for the * close notify of the client because some clients (including Netscape * 4.x) don't send one, so we would hang. */ /* * exchange close notify messages, but allow the user * to force the type of handshake via SetEnvIf directive */ if (ap_ctx_get(conn->client->ctx, "ssl::flag::unclean-shutdown") == PTRUE) { /* perform no close notify handshake at all (violates the SSL/TLS standard!) */ SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); cpType = "unclean"; } else if (ap_ctx_get(conn->client->ctx, "ssl::flag::accurate-shutdown") == PTRUE) { /* send close notify and wait for clients close notify (standard compliant, but usually causes connection hangs) */ SSL_set_shutdown(ssl, 0); cpType = "accurate"; } else { /* send close notify, but don't wait for clients close notify (standard compliant and safe, so it's the DEFAULT!) */ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); cpType = "standard"; } SSL_smart_shutdown(ssl); /* deallocate the SSL connection */ SSL_free(ssl); ap_ctx_set(conn->client->ctx, "ssl", NULL); /* and finally log the fact that we've closed the connection */ ssl_log(conn->server, SSL_LOG_INFO, "Connection to child %d closed with %s shutdown (server %s, client %s)", conn->child_num, cpType, ssl_util_vhostid(conn->pool, conn->server), conn->remote_ip != NULL ? conn->remote_ip : "unknown"); return;}/* * Post Read Request Handler */int ssl_hook_ReadReq(request_rec *r){ SSL *ssl; ap_ctx *apctx; /* * 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) { apctx = SSL_get_app_data2(ssl); ap_ctx_set(apctx, "ssl::request_rec", 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;}/* * URL Translation Handler */int ssl_hook_Translate(request_rec *r){ if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) return DECLINED; /* * Log information about incoming HTTPS requests */ if (ap_is_initial_req(r)) ssl_log(r->server, SSL_LOG_INFO, "%s HTTPS request received for child %d (server %s)", r->connection->keepalives <= 0 ? "Initial (No.1)" : ap_psprintf(r->pool, "Subsequent (No.%d)", r->connection->keepalives+1), r->connection->child_num, ssl_util_vhostid(r->pool, r->server)); /* * Move SetEnvIf information from request_rec to conn_rec/BUFF * to allow the close connection handler to use them. */ if (ap_table_get(r->subprocess_env, "ssl-unclean-shutdown") != NULL) ap_ctx_set(r->connection->client->ctx, "ssl::flag::unclean-shutdown", PTRUE); else ap_ctx_set(r->connection->client->ctx, "ssl::flag::unclean-shutdown", PFALSE); if (ap_table_get(r->subprocess_env, "ssl-accurate-shutdown") != NULL) ap_ctx_set(r->connection->client->ctx, "ssl::flag::accurate-shutdown", PTRUE); else ap_ctx_set(r->connection->client->ctx, "ssl::flag::accurate-shutdown", PFALSE); 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_escape_html(r->pool, 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;}/* * Access Handler */int ssl_hook_Access(request_rec *r){ SSLDirConfigRec *dc; SSLSrvConfigRec *sc; SSL *ssl; SSL_CTX *ctx = NULL; array_header *apRequirement; ssl_require_t *pRequirements; ssl_require_t *pRequirement; char *cp; int ok; int i; BOOL renegotiate; BOOL renegotiate_quick;#ifdef SSL_EXPERIMENTAL_PERDIRCA BOOL reconfigured_locations; STACK_OF(X509_NAME) *skCAList; char *cpCAPath; char *cpCAFile;#endif X509 *cert; STACK_OF(X509) *certstack; X509_STORE *certstore; X509_STORE_CTX certstorectx; int depth; STACK_OF(SSL_CIPHER) *skCipherOld; STACK_OF(SSL_CIPHER) *skCipher = NULL; SSL_CIPHER *pCipher; ap_ctx *apctx; int nVerifyOld; int nVerify; int n; void *vp; int rc; dc = myDirConfig(r);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -