Bug#307298: apache2-common: mod_proxy_connect bypasses mod_ssl at tunnel setup
Package: apache2-common
Version: 2.0.54-2
Severity: normal
Tags: patch
Currently it is not possible to successfully issue an HTTP CONNECT
request to apache2 with mod_ssl; mod_proxy_connect talks directly to
the client socket and bypasses mod_ssl.
Further discussion of this bug is at:
http://issues.apache.org/bugzilla/show_bug.cgi?id=29744
I have included a patch by Brad Boyer (see above discussion) which
fixes this problem for me.
-- System Information:
Debian Release: 3.1
APT prefers testing
APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i586)
Kernel: Linux 2.6.11.7-grsec
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)
Versions of packages apache2-common depends on:
ii apache2-utils 2.0.54-2 utility programs for webservers
ii debconf 1.4.30.13 Debian configuration management sy
ii debianutils 2.8.4 Miscellaneous utilities specific t
ii libc6 2.3.2.ds1-21 GNU C Library: Shared libraries an
ii libdb4.2 4.2.52-18 Berkeley v4.2 Database Libraries [
ii libexpat1 1.95.8-3 XML parsing C library - runtime li
ii libgcc1 1:3.4.3-12 GCC support library
ii libmagic1 4.12-1 File type determination library us
ii mime-support 3.28-1 MIME files 'mime.types' & 'mailcap
ii net-tools 1.60-10 The NET-3 networking toolkit
ii openssl 0.9.7e-3 Secure Socket Layer (SSL) binary a
ii ssl-cert 1.0-11 Simple debconf wrapper for openssl
-- no debconf information
--- build-tree.orig/apache2/modules/proxy/proxy_connect.c 2004-02-09 12:53:19.000000000 -0800
+++ build-tree/apache2/modules/proxy/proxy_connect.c 2004-10-20 16:09:26.000000000 -0700
@@ -83,10 +83,14 @@
{
apr_pool_t *p = r->pool;
apr_socket_t *sock;
+ conn_rec *c = r->connection;
+ conn_rec *backconn;
+ apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
+
apr_status_t err, rv;
apr_size_t i, o, nbytes;
char buffer[HUGE_STRING_LEN];
- apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module);
+ apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module);
int failed;
apr_pollfd_t *pollfd;
apr_int32_t pollcnt;
@@ -211,7 +215,23 @@
* We add the NULL filter to the stack to do this...
*/
r->output_filters = NULL;
- r->connection->output_filters = NULL;
+
+ backconn = ap_run_create_connection(c->pool, r->server, sock,
+ c->id, c->sbh, c->bucket_alloc);
+ if(!backconn) {
+ /* peer reset */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy: an error occurred creating a new connection "
+ "to %pI (%s)", connect_addr, connectname);
+ apr_socket_close(sock);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ ap_proxy_ssl_disable(backconn);
+ ap_run_pre_connection(backconn, sock);
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "proxy: connection complete to %pI (%s)",
+ connect_addr, connectname);
/* If we are connecting through a remote proxy, we need to pass
@@ -222,12 +242,12 @@
*/
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: CONNECT: sending the CONNECT request to the remote proxy");
- nbytes = apr_snprintf(buffer, sizeof(buffer),
+
+ ap_fprintf(backconn->output_filters, bb,
"CONNECT %s HTTP/1.0" CRLF, r->uri);
- apr_send(sock, buffer, &nbytes);
- nbytes = apr_snprintf(buffer, sizeof(buffer),
- "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
- apr_send(sock, buffer, &nbytes);
+ ap_fprintf(backconn->output_filters, bb,
+ "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
+ ap_fflush(backconn->output_filters, bb);
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
@@ -235,11 +255,12 @@
nbytes = apr_snprintf(buffer, sizeof(buffer),
"HTTP/1.0 200 Connection Established" CRLF);
ap_xlate_proto_to_ascii(buffer, nbytes);
- apr_send(client_socket, buffer, &nbytes);
+ ap_fwrite(c->output_filters, bb, buffer, nbytes);
nbytes = apr_snprintf(buffer, sizeof(buffer),
"Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
ap_xlate_proto_to_ascii(buffer, nbytes);
- apr_send(client_socket, buffer, &nbytes);
+ ap_fwrite(c->output_filters, bb, buffer, nbytes);
+ ap_fflush(c->output_filters, bb);
#if 0
/* This is safer code, but it doesn't work yet. I'm leaving it
* here so that I can fix it later.
@@ -293,23 +314,13 @@
/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: CONNECT: sock was set");*/
nbytes = sizeof(buffer);
- if (apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) {
- o = 0;
- i = nbytes;
- while(i > 0)
- {
- nbytes = i;
- /* This is just plain wrong. No module should ever write directly
- * to the client. For now, this works, but this is high on my list of
- * things to fix. The correct line is:
- * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0)
- * rbb
- */
- if (apr_send(client_socket, buffer + o, &nbytes) != APR_SUCCESS)
- break;
- o += nbytes;
- i -= nbytes;
- }
+ apr_brigade_cleanup(bb);
+ if (ap_get_brigade(backconn->input_filters, bb,
+ AP_MODE_READBYTES, APR_NONBLOCK_READ,
+ nbytes) == APR_SUCCESS) {
+ if (ap_pass_brigade(c->output_filters, bb) != APR_SUCCESS)
+ break;
+ ap_fflush(c->output_filters, bb);
}
else
break;
@@ -323,17 +334,13 @@
/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy: CONNECT: client was set");*/
nbytes = sizeof(buffer);
- if (apr_recv(client_socket, buffer, &nbytes) == APR_SUCCESS) {
- o = 0;
- i = nbytes;
- while(i > 0)
- {
- nbytes = i;
- if (apr_send(sock, buffer + o, &nbytes) != APR_SUCCESS)
- break;
- o += nbytes;
- i -= nbytes;
- }
+ apr_brigade_cleanup(bb);
+ if (ap_get_brigade(c->input_filters, bb, AP_MODE_READBYTES,
+ APR_NONBLOCK_READ, nbytes) == APR_SUCCESS) {
+ if (ap_pass_brigade(backconn->output_filters, bb)
+ != APR_SUCCESS)
+ break;
+ ap_fflush(backconn->output_filters, bb);
}
else
break;
Reply to: