1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-07 04:02:58 +03:00

remove #if 0-ed ssl_hook_NewConnection code; was only left for reference,

no longer needed
remove #if 0-ed ssl_hook_TimeoutConnection code; ssl no longer talks directly
to the socket
PR:
Obtained from:
Submitted by:    madhu
Reviewed by:	 dougm


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90511 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug MacEachern
2001-08-22 21:37:15 +00:00
parent 8a61898a77
commit d792836690
3 changed files with 1 additions and 316 deletions

View File

@@ -63,318 +63,6 @@
-- Unknown */
#include "mod_ssl.h"
#if 0 /* XXX */
/* _________________________________________________________________
**
** 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;
ap_ctx *apctx;
SSL *ssl;
char *cp;
char *cpVHostID;
char *cpVHostMD5;
X509 *xs;
int rc;
/*
* 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
*/
cpVHostID = ssl_util_vhostid(conn->pool, srvr);
ssl_log(srvr, SSL_LOG_INFO, "Connection to child %d established "
"(server %s, client %s)", conn->child_num, cpVHostID,
conn->remote_ip != NULL ? conn->remote_ip : "unknown");
/*
* Seed the Pseudo Random Number Generator (PRNG)
*/
ssl_rand_seed(srvr, conn->pool, SSL_RSCTX_CONNECT, "");
/*
* 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.
*/
if ((ssl = SSL_new(sc->pSSLCtx)) == NULL) {
ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
"Unable to create a new SSL connection from the SSL context");
ap_ctx_set(fb->ctx, "ssl", NULL);
ap_bsetflag(fb, B_EOF|B_EOUT, 1);
conn->aborted = 1;
return;
}
SSL_clear(ssl);
cpVHostMD5 = ap_md5(conn->pool, (unsigned char *)cpVHostID);
if (!SSL_set_session_id_context(ssl, (unsigned char *)cpVHostMD5, strlen(cpVHostMD5))) {
ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
"Unable to set session id context to `%s'", cpVHostMD5);
ap_ctx_set(fb->ctx, "ssl", NULL);
ap_bsetflag(fb, B_EOF|B_EOUT, 1);
conn->aborted = 1;
return;
}
SSL_set_app_data(ssl, conn);
apctx = ap_ctx_new(conn->pool);
ap_ctx_set(apctx, "ssl::request_rec", NULL);
ap_ctx_set(apctx, "ssl::verify::depth", AP_CTX_NUM2PTR(0));
SSL_set_app_data2(ssl, apctx);
SSL_set_fd(ssl, fb->fd);
ap_ctx_set(fb->ctx, "ssl", ssl);
/*
* Configure callbacks for SSL connection
*/
SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH);
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);
}
/*
* Predefine some client verification results
*/
ap_ctx_set(fb->ctx, "ssl::client::dn", NULL);
ap_ctx_set(fb->ctx, "ssl::verify::error", NULL);
ap_ctx_set(fb->ctx, "ssl::verify::info", NULL);
SSL_set_verify_result(ssl, X509_V_OK);
/*
* 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);
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;
return;
}
else if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
/*
* The case where OpenSSL 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: OpenSSL 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.
*
*/
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);
SSL_smart_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 != NULL ? conn->remote_ip : "unknown", cpVHostID);
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;
return;
}
else if (SSL_get_error(ssl, rc) == SSL_ERROR_SYSCALL) {
if (errno == EINTR)
continue;
if (errno > 0)
ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR|SSL_ADD_ERRNO,
"SSL handshake interrupted by system "
"[Hint: Stop button pressed in browser?!]");
else
ssl_log(srvr, SSL_LOG_INFO|SSL_ADD_SSLERR|SSL_ADD_ERRNO,
"Spurious SSL handshake interrupt"
"[Hint: Usually just one of those OpenSSL confusions!?]");
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;
return;
}
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;
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;
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));
free(cp);
}
/*
* 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;
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
*/
SSL_set_read_ahead(ssl, TRUE);
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;
}
#endif /* XXX */
/*
* Close the SSL part of the socket connection
* (called immediately _before_ the socket is closed)