diff options
author | Stefan Eissing <icing@apache.org> | 2015-10-22 15:23:28 +0200 |
---|---|---|
committer | Stefan Eissing <icing@apache.org> | 2015-10-22 15:23:28 +0200 |
commit | 306542f55f696caf5ae1ce0e679d894e1bb78ad6 (patch) | |
tree | 00c2982c5c5cf3ebcd43febd3bc39e3ec6362b4e | |
parent | mod_ssl: check request-server for TLS settings compatible to handshake server... (diff) | |
download | apache2-306542f55f696caf5ae1ce0e679d894e1bb78ad6.tar.xz apache2-306542f55f696caf5ae1ce0e679d894e1bb78ad6.zip |
mod_http2: no longer messing with mod_ssl config in slave connections, special RST_STREAM failures when 403 responses are due to prohibited TLS renegotiations
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1710014 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | modules/http2/h2_conn.c | 23 | ||||
-rw-r--r-- | modules/http2/h2_from_h1.c | 6 | ||||
-rw-r--r-- | modules/http2/h2_h2.c | 8 | ||||
-rw-r--r-- | modules/http2/h2_h2.h | 21 | ||||
-rw-r--r-- | modules/http2/h2_io.c | 11 | ||||
-rw-r--r-- | modules/http2/h2_io.h | 5 | ||||
-rw-r--r-- | modules/http2/h2_mplx.c | 5 | ||||
-rw-r--r-- | modules/http2/h2_response.c | 18 | ||||
-rw-r--r-- | modules/http2/h2_response.h | 8 | ||||
-rw-r--r-- | modules/http2/h2_task.c | 6 |
10 files changed, 61 insertions, 50 deletions
diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c index c2feeefdf7..31029d6a10 100644 --- a/modules/http2/h2_conn.c +++ b/modules/http2/h2_conn.c @@ -44,7 +44,6 @@ static apr_status_t h2_session_process(h2_session *session); static h2_mpm_type_t mpm_type = H2_MPM_UNKNOWN; static module *mpm_module; -static module *ssl_module; static int checked; static void check_modules(void) @@ -65,9 +64,6 @@ static void check_modules(void) mpm_type = H2_MPM_PREFORK; mpm_module = m; } - else if (!strcmp("mod_ssl.c", m->name)) { - ssl_module = m; - } } checked = 1; } @@ -104,9 +100,6 @@ apr_status_t h2_conn_child_init(apr_pool_t *pool, server_rec *s) mpm_type = H2_MPM_PREFORK; mpm_module = m; } - else if (!strcmp("mod_ssl.c", m->name)) { - ssl_module = m; - } } if (minw <= 0) { @@ -422,22 +415,12 @@ apr_status_t h2_conn_setup(h2_task_env *env, struct h2_worker *worker) env->c.conn_config = ap_create_conn_config(env->pool); env->c.notes = apr_table_make(env->pool, 5); + /* In order to do this in 2.4.x, we need to add a member to conn_rec */ + env->c.master = master; + ap_set_module_config(env->c.conn_config, &core_module, h2_worker_get_socket(worker)); - /* If we serve http:// requests over a TLS connection, we do - * not want any mod_ssl vars to be visible. - */ - if (ssl_module && (!env->scheme || strcmp("http", env->scheme))) { - /* See #19, there is a range of SSL variables to be gotten from - * the main connection that should be available in request handlers - */ - void *sslcfg = ap_get_module_config(master->conn_config, ssl_module); - if (sslcfg) { - ap_set_module_config(env->c.conn_config, ssl_module, sslcfg); - } - } - /* This works for mpm_worker so far. Other mpm modules have * different needs, unfortunately. The most interesting one * being mpm_event... diff --git a/modules/http2/h2_from_h1.c b/modules/http2/h2_from_h1.c index be11f5c317..2b77db2f00 100644 --- a/modules/http2/h2_from_h1.c +++ b/modules/http2/h2_from_h1.c @@ -78,9 +78,9 @@ h2_response *h2_from_h1_get_response(h2_from_h1 *from_h1) static apr_status_t make_h2_headers(h2_from_h1 *from_h1, request_rec *r) { - from_h1->response = h2_response_create(from_h1->stream_id, - from_h1->status, from_h1->hlines, - from_h1->pool); + from_h1->response = h2_response_create(from_h1->stream_id, 0, + from_h1->status, from_h1->hlines, + from_h1->pool); if (from_h1->response == NULL) { ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, r->connection, APLOGNO(02915) diff --git a/modules/http2/h2_h2.c b/modules/http2/h2_h2.c index ec2daf126f..6ee067dedc 100644 --- a/modules/http2/h2_h2.c +++ b/modules/http2/h2_h2.c @@ -437,14 +437,6 @@ int h2_h2_is_tls(conn_rec *c) return opt_ssl_is_https && opt_ssl_is_https(c); } -int h2_tls_disable(conn_rec *c) -{ - if (opt_ssl_engine_disable) { - return opt_ssl_engine_disable(c); - } - return 0; -} - int h2_is_acceptable_connection(conn_rec *c, int require_all) { int is_tls = h2_h2_is_tls(c); diff --git a/modules/http2/h2_h2.h b/modules/http2/h2_h2.h index 1b3bbf4a97..50f2614b29 100644 --- a/modules/http2/h2_h2.h +++ b/modules/http2/h2_h2.h @@ -34,6 +34,21 @@ extern const char *h2_tls_protos[]; */ extern const char *H2_MAGIC_TOKEN; +#define H2_ERR_NO_ERROR (0x00) +#define H2_ERR_PROTOCOL_ERROR (0x01) +#define H2_ERR_INTERNAL_ERROR (0x02) +#define H2_ERR_FLOW_CONTROL_ERROR (0x03) +#define H2_ERR_SETTINGS_TIMEOUT (0x04) +#define H2_ERR_STREAM_CLOSED (0x05) +#define H2_ERR_FRAME_SIZE_ERROR (0x06) +#define H2_ERR_REFUSED_STREAM (0x07) +#define H2_ERR_CANCEL (0x08) +#define H2_ERR_COMPRESSION_ERROR (0x09) +#define H2_ERR_CONNECT_ERROR (0x0a) +#define H2_ERR_ENHANCE_YOUR_CALM (0x0b) +#define H2_ERR_INADEQUATE_SECURITY (0x0c) +#define H2_ERR_HTTP_1_1_REQUIRED (0x0d) + /* * One time, post config intialization. */ @@ -43,12 +58,6 @@ apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s); */ int h2_h2_is_tls(conn_rec *c); -/* Disable SSL for this connection, can only be invoked in a pre- - * connection hook before mod_ssl. - * @return != 0 iff disable worked - */ -int h2_tls_disable(conn_rec *c); - /* Register apache hooks for h2 protocol */ void h2_h2_register_hooks(void); diff --git a/modules/http2/h2_io.c b/modules/http2/h2_io.c index 9f699aa9b5..4e61c0882b 100644 --- a/modules/http2/h2_io.c +++ b/modules/http2/h2_io.c @@ -47,6 +47,17 @@ void h2_io_destroy(h2_io *io) h2_io_cleanup(io); } +void h2_io_set_response(h2_io *io, h2_response *response) +{ + AP_DEBUG_ASSERT(response); + AP_DEBUG_ASSERT(!io->response); + io->response = h2_response_copy(io->pool, response); + if (response->rst_error) { + h2_io_rst(io, response->rst_error); + } +} + + void h2_io_rst(h2_io *io, int error) { io->rst_error = error; diff --git a/modules/http2/h2_io.h b/modules/http2/h2_io.h index 23655d21df..c8315efa8d 100644 --- a/modules/http2/h2_io.h +++ b/modules/http2/h2_io.h @@ -61,6 +61,11 @@ h2_io *h2_io_create(int id, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc); void h2_io_destroy(h2_io *io); /** + * Set the response of this stream. + */ +void h2_io_set_response(h2_io *io, struct h2_response *response); + +/** * Reset the stream with the given error code. */ void h2_io_rst(h2_io *io, int error); diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c index 6c4ae9f4c4..aec9f3606c 100644 --- a/modules/http2/h2_mplx.c +++ b/modules/http2/h2_mplx.c @@ -591,8 +591,7 @@ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_response *response, m->id, stream_id, response->status); } - io->response = h2_response_copy(io->pool, response); - AP_DEBUG_ASSERT(io->response); + h2_io_set_response(io, response); h2_io_set_add(m->ready_ios, io); if (bb) { status = out_write(m, io, f, bb, iowait); @@ -680,7 +679,7 @@ apr_status_t h2_mplx_out_close(h2_mplx *m, int stream_id) * insert an error one so that our streams can properly * reset. */ - h2_response *r = h2_response_create(stream_id, + h2_response *r = h2_response_create(stream_id, 0, "500", NULL, m->pool); status = out_open(m, stream_id, r, NULL, NULL, NULL); ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, m->c, diff --git a/modules/http2/h2_response.c b/modules/http2/h2_response.c index 9cedd85561..bd0a5fba97 100644 --- a/modules/http2/h2_response.c +++ b/modules/http2/h2_response.c @@ -25,6 +25,7 @@ #include <nghttp2/nghttp2.h> #include "h2_private.h" +#include "h2_h2.h" #include "h2_util.h" #include "h2_response.h" @@ -41,6 +42,7 @@ static int ignore_header(const char *name) } h2_response *h2_response_create(int stream_id, + int rst_error, const char *http_status, apr_array_header_t *hlines, apr_pool_t *pool) @@ -53,7 +55,8 @@ h2_response *h2_response_create(int stream_id, } response->stream_id = stream_id; - response->status = http_status; + response->rst_error = rst_error; + response->status = http_status? http_status : "500"; response->content_length = -1; if (hlines) { @@ -112,6 +115,19 @@ h2_response *h2_response_rcreate(int stream_id, request_rec *r, response->status = apr_psprintf(pool, "%d", r->status); response->content_length = -1; response->rheader = header; + + if (r->status == HTTP_FORBIDDEN) { + const char *cause = apr_table_get(r->notes, "ssl-renegotiate-forbidden"); + if (cause) { + /* This request triggered a TLS renegotiation that is now allowed + * in HTTP/2. Tell the client that it should use HTTP/1.1 for this. + */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r->status, r, + "h2_response(%ld-%d): renegotiate forbidden, cause: %s", + (long)r->connection->id, stream_id, cause); + response->rst_error = H2_ERR_HTTP_1_1_REQUIRED; + } + } return response; } diff --git a/modules/http2/h2_response.h b/modules/http2/h2_response.h index 456d2226ed..64d68cc9c2 100644 --- a/modules/http2/h2_response.h +++ b/modules/http2/h2_response.h @@ -26,6 +26,7 @@ typedef struct h2_ngheader { typedef struct h2_response { int stream_id; + int rst_error; const char *status; apr_off_t content_length; apr_table_t *rheader; @@ -33,9 +34,10 @@ typedef struct h2_response { } h2_response; h2_response *h2_response_create(int stream_id, - const char *http_status, - apr_array_header_t *hlines, - apr_pool_t *pool); + int rst_error, + const char *http_status, + apr_array_header_t *hlines, + apr_pool_t *pool); h2_response *h2_response_rcreate(int stream_id, request_rec *r, apr_table_t *header, apr_pool_t *pool); diff --git a/modules/http2/h2_task.c b/modules/http2/h2_task.c index 58b39c5397..60dade84d3 100644 --- a/modules/http2/h2_task.c +++ b/modules/http2/h2_task.c @@ -121,12 +121,6 @@ static int h2_task_pre_conn(conn_rec* c, void *arg) if (h2_ctx_is_task(ctx)) { h2_task_env *env = h2_ctx_get_task(ctx); - /* This connection is a pseudo-connection used for a h2_task. - * Since we read/write directly from it ourselves, we need - * to disable a possible ssl connection filter. - */ - h2_tls_disable(c); - ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, pre_connection, found stream task"); |