summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2015-10-22 15:23:28 +0200
committerStefan Eissing <icing@apache.org>2015-10-22 15:23:28 +0200
commit306542f55f696caf5ae1ce0e679d894e1bb78ad6 (patch)
tree00c2982c5c5cf3ebcd43febd3bc39e3ec6362b4e
parentmod_ssl: check request-server for TLS settings compatible to handshake server... (diff)
downloadapache2-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.c23
-rw-r--r--modules/http2/h2_from_h1.c6
-rw-r--r--modules/http2/h2_h2.c8
-rw-r--r--modules/http2/h2_h2.h21
-rw-r--r--modules/http2/h2_io.c11
-rw-r--r--modules/http2/h2_io.h5
-rw-r--r--modules/http2/h2_mplx.c5
-rw-r--r--modules/http2/h2_response.c18
-rw-r--r--modules/http2/h2_response.h8
-rw-r--r--modules/http2/h2_task.c6
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");