diff options
author | manu <manu@pkgsrc.org> | 2013-07-05 15:36:25 +0000 |
---|---|---|
committer | manu <manu@pkgsrc.org> | 2013-07-05 15:36:25 +0000 |
commit | ec16a2f876e46b660d6ece2c88b968323d67ee8b (patch) | |
tree | fa0d713fd72e8012f6689caedc821f8ffb8c49ae /www | |
parent | b9f625b4539e853a1a3f6702da304e96b9b95aa0 (diff) | |
download | pkgsrc-ec16a2f876e46b660d6ece2c88b968323d67ee8b.tar.gz |
Patch from upstream (fixed in trunk and 2.4 branch):
https://issues.apache.org/bugzilla/show_bug.cgi?id=29744
When using CONNECT inside a SSL connexion, fix a bug that caused
apache to reply in plain text.
Diffstat (limited to 'www')
-rw-r--r-- | www/apache22/Makefile | 4 | ||||
-rw-r--r-- | www/apache22/distinfo | 3 | ||||
-rw-r--r-- | www/apache22/patches/patch-modules_proxy_mod_proxy_connect.c | 333 |
3 files changed, 337 insertions, 3 deletions
diff --git a/www/apache22/Makefile b/www/apache22/Makefile index df5aae9e8a1..4425d6e8ac5 100644 --- a/www/apache22/Makefile +++ b/www/apache22/Makefile @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.89 2013/05/31 12:42:31 wiz Exp $ +# $NetBSD: Makefile,v 1.90 2013/07/05 15:36:25 manu Exp $ DISTNAME= httpd-2.2.24 PKGNAME= ${DISTNAME:S/httpd/apache/} -PKGREVISION= 2 +PKGREVISION= 3 CATEGORIES= www MASTER_SITES= ${MASTER_SITE_APACHE:=httpd/} \ http://archive.apache.org/dist/httpd/ \ diff --git a/www/apache22/distinfo b/www/apache22/distinfo index c9ae5f8efeb..6cf33a55cd9 100644 --- a/www/apache22/distinfo +++ b/www/apache22/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.55 2013/05/30 22:58:14 tron Exp $ +$NetBSD: distinfo,v 1.56 2013/07/05 15:36:25 manu Exp $ SHA1 (httpd-2.2.24.tar.bz2) = f73bce14832ec40c1aae68f4f8c367cab2266241 RMD160 (httpd-2.2.24.tar.bz2) = 4c31b23615236c407779a23cbfcc8e05ba011224 @@ -16,5 +16,6 @@ SHA1 (patch-aw) = ca53d67beeb2c2c4d9adb04d3d79e24a8c427fd4 SHA1 (patch-docs_man_apxs.8) = 70797ea73ae6379492971bec1106a8427ae7fdaa SHA1 (patch-lock.c) = 770ca03f1cb4421879bd5baa5a7c30cc91acb6e1 SHA1 (patch-modules_mappers_mod_rewrite.c) = a1cee8c7c97936e15a1596a54ddc1839a5b1038d +SHA1 (patch-modules_proxy_mod_proxy_connect.c) = 6d5ed1e075bc3d727c4940078a3a8b2abeb4b324 SHA1 (patch-modules_ssl_ssl__engine__kernel.c) = fd6f425d18231f0daca9fc2553638891a7241a4a SHA1 (patch-repos.c) = 0e0361b91d4b0fe6c7c55a12fdfd2e6aacc710e1 diff --git a/www/apache22/patches/patch-modules_proxy_mod_proxy_connect.c b/www/apache22/patches/patch-modules_proxy_mod_proxy_connect.c new file mode 100644 index 00000000000..bd21f88cf34 --- /dev/null +++ b/www/apache22/patches/patch-modules_proxy_mod_proxy_connect.c @@ -0,0 +1,333 @@ +--- modules/proxy/mod_proxy_connect.c ++++ modules/proxy/mod_proxy_connect.c +@@ -21,6 +21,8 @@ + #include "mod_proxy.h" + #include "apr_poll.h" + ++#define CONN_BLKSZ AP_IOBUFSIZE ++ + module AP_MODULE_DECLARE_DATA proxy_connect_module; + + /* +@@ -71,6 +73,50 @@ + return OK; + } + ++/* read available data (in blocks of CONN_BLKSZ) from c_i and copy to c_o */ ++static int proxy_connect_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, ++ apr_bucket_brigade *bb, char *name) ++{ ++ int rv; ++#ifdef DEBUGGING ++ apr_off_t len; ++#endif ++ ++ do { ++ apr_brigade_cleanup(bb); ++ rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES, ++ APR_NONBLOCK_READ, CONN_BLKSZ); ++ if (rv == APR_SUCCESS) { ++ if (APR_BRIGADE_EMPTY(bb)) ++ break; ++#ifdef DEBUGGING ++ len = -1; ++ apr_brigade_length(bb, 0, &len); ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: read %" APR_OFF_T_FMT ++ " bytes from %s", len, name); ++#endif ++ rv = ap_pass_brigade(c_o->output_filters, bb); ++ if (rv == APR_SUCCESS) { ++ ap_fflush(c_o->output_filters, bb); ++ } else { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, ++ "proxy: CONNECT: error on %s - ap_pass_brigade", ++ name); ++ } ++ } else if (!APR_STATUS_IS_EAGAIN(rv)) { ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, ++ "proxy: CONNECT: error on %s - ap_get_brigade", ++ name); ++ } ++ } while (rv == APR_SUCCESS); ++ ++ if (APR_STATUS_IS_EAGAIN(rv)) { ++ rv = APR_SUCCESS; ++ } ++ return rv; ++} ++ + /* CONNECT handler */ + static int proxy_connect_handler(request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, +@@ -79,11 +125,15 @@ + { + 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); +- int failed; ++ apr_socket_t *client_socket = ap_get_module_config(c->conn_config, &core_module); ++ int failed, rc; + apr_pollset_t *pollset; + apr_pollfd_t pollfd; + const apr_pollfd_t *signalled; +@@ -158,12 +208,10 @@ + case APR_URI_SNEWS_DEFAULT_PORT: + break; + default: +- /* XXX can we call ap_proxyerror() here to get a nice log message? */ +- return HTTP_FORBIDDEN; ++ return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); + } + } else if(!allowed_port(conf, uri.port)) { +- /* XXX can we call ap_proxyerror() here to get a nice log message? */ +- return HTTP_FORBIDDEN; ++ return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); + } + + /* +@@ -205,18 +253,57 @@ + } + } + ++ /* setup polling for connection */ ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: setting up poll()"); ++ ++ if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { ++ apr_socket_close(sock); ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, ++ "proxy: CONNECT: error apr_pollset_create()"); ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } ++ ++ /* Add client side to the poll */ ++ pollfd.p = r->pool; ++ pollfd.desc_type = APR_POLL_SOCKET; ++ pollfd.reqevents = APR_POLLIN; ++ pollfd.desc.s = client_socket; ++ pollfd.client_data = NULL; ++ apr_pollset_add(pollset, &pollfd); ++ ++ /* Add the server side to the poll */ ++ pollfd.desc.s = sock; ++ apr_pollset_add(pollset, &pollfd); ++ + /* + * Step Three: Send the Request + * + * Send the HTTP/1.1 CONNECT request to the remote server + */ + +- /* we are acting as a tunnel - the output filter stack should +- * be completely empty, because when we are done here we are done completely. +- * 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_rerror(APLOG_MARK, APLOG_INFO, 0, r, ++ "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); ++ rc = ap_run_pre_connection(backconn, sock); ++ if (rc != OK && rc != DONE) { ++ backconn->aborted = 1; ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: pre_connection setup failed (%d)", rc); ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } ++ ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: connection complete to %pI (%s)", ++ connect_addr, connectname); + + + /* If we are connecting through a remote proxy, we need to pass +@@ -227,12 +314,11 @@ + */ + 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_socket_send(sock, buffer, &nbytes); +- nbytes = apr_snprintf(buffer, sizeof(buffer), +- "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); +- apr_socket_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, +@@ -240,11 +326,12 @@ + nbytes = apr_snprintf(buffer, sizeof(buffer), + "HTTP/1.0 200 Connection Established" CRLF); + ap_xlate_proto_to_ascii(buffer, nbytes); +- apr_socket_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_banner()); + ap_xlate_proto_to_ascii(buffer, nbytes); +- apr_socket_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. +@@ -265,27 +352,15 @@ + * Handle two way transfer of data over the socket (this is a tunnel). + */ + ++ /* we are now acting as a tunnel - the input/output filter stacks should ++ * not contain any non-connection filters. ++ */ ++ r->output_filters = c->output_filters; ++ r->proto_output_filters = c->output_filters; ++ r->input_filters = c->input_filters; ++ r->proto_input_filters = c->input_filters; + /* r->sent_bodyct = 1;*/ + +- if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { +- apr_socket_close(sock); +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, +- "proxy: CONNECT: error apr_pollset_create()"); +- return HTTP_INTERNAL_SERVER_ERROR; +- } +- +- /* Add client side to the poll */ +- pollfd.p = r->pool; +- pollfd.desc_type = APR_POLL_SOCKET; +- pollfd.reqevents = APR_POLLIN; +- pollfd.desc.s = client_socket; +- pollfd.client_data = NULL; +- apr_pollset_add(pollset, &pollfd); +- +- /* Add the server side to the poll */ +- pollfd.desc.s = sock; +- apr_pollset_add(pollset, &pollfd); +- + while (1) { /* Infinite loop until error (one side closes the connection) */ + if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rv)) { +@@ -297,7 +372,7 @@ + } + #ifdef DEBUGGING + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, +- "proxy: CONNECT: woke from select(), i=%d", pollcnt); ++ "proxy: CONNECT: woke from poll(), i=%d", pollcnt); + #endif + + for (pi = 0; pi < pollcnt; pi++) { +@@ -307,72 +382,32 @@ + pollevent = cur->rtnevents; + if (pollevent & APR_POLLIN) { + #ifdef DEBUGGING +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, +- "proxy: CONNECT: sock was set"); ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: sock was readable"); + #endif +- nbytes = sizeof(buffer); +- rv = apr_socket_recv(sock, buffer, &nbytes); +- if (rv == 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 +- */ +- rv = apr_socket_send(client_socket, buffer + o, &nbytes); +- if (rv != APR_SUCCESS) +- break; +- o += nbytes; +- i -= nbytes; +- } ++ rv = proxy_connect_transfer(r, backconn, c, bb, "sock"); + } +- else +- break; ++ else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { ++ rv = APR_EPIPE; ++ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "proxy: CONNECT: err/hup on backconn"); + } +- else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) +- break; + } + else if (cur->desc.s == client_socket) { + pollevent = cur->rtnevents; + if (pollevent & APR_POLLIN) { + #ifdef DEBUGGING +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, +- "proxy: CONNECT: client was set"); +-#endif +- nbytes = sizeof(buffer); +- rv = apr_socket_recv(client_socket, buffer, &nbytes); +- if (rv == APR_SUCCESS) { +- o = 0; +- i = nbytes; +-#ifdef DEBUGGING +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, +- "proxy: CONNECT: read %d from client", i); ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ++ "proxy: CONNECT: client was readable"); + #endif +- while(i > 0) +- { +- nbytes = i; +- rv = apr_socket_send(sock, buffer + o, &nbytes); +- if (rv != APR_SUCCESS) +- break; +- o += nbytes; +- i -= nbytes; +- } +- } +- else +- break; ++ rv = proxy_connect_transfer(r, c, backconn, bb, "client"); + } +- else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) { +- rv = APR_EOF; +- break; + } ++ else { ++ rv = APR_EBADF; ++ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, ++ "proxy: CONNECT: unknown socket in pollset"); + } +- else +- break; ++ + } + if (rv != APR_SUCCESS) { + break; +@@ -388,7 +423,9 @@ + * Close the socket and clean up + */ + +- apr_socket_close(sock); ++ ap_lingering_close(backconn); ++ ++ c->aborted = 1; + + return OK; + } |