diff --git a/.gitignore b/.gitignore index 8020585..6188d89 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/httpd-2.4.12.tar.bz2 +SOURCES/httpd-2.4.18.tar.bz2 diff --git a/.httpd24-httpd.metadata b/.httpd24-httpd.metadata index 2f41236..bd783d7 100644 --- a/.httpd24-httpd.metadata +++ b/.httpd24-httpd.metadata @@ -1 +1 @@ -bc4681bfd63accec8d82d3cc440fbc8264ce0f17 SOURCES/httpd-2.4.12.tar.bz2 +271a129f2f04e3aa694e5c2091df9b707bf8ef80 SOURCES/httpd-2.4.18.tar.bz2 diff --git a/SOURCES/00-base.conf b/SOURCES/00-base.conf index 9ec0adf..c109de6 100644 --- a/SOURCES/00-base.conf +++ b/SOURCES/00-base.conf @@ -25,6 +25,7 @@ LoadModule authz_user_module modules/mod_authz_user.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule cache_module modules/mod_cache.so LoadModule cache_disk_module modules/mod_cache_disk.so +LoadModule cache_socache_module modules/mod_cache_socache.so LoadModule data_module modules/mod_data.so LoadModule dbd_module modules/mod_dbd.so LoadModule deflate_module modules/mod_deflate.so @@ -36,10 +37,12 @@ LoadModule expires_module modules/mod_expires.so LoadModule ext_filter_module modules/mod_ext_filter.so LoadModule filter_module modules/mod_filter.so LoadModule headers_module modules/mod_headers.so +LoadModule http2_module modules/mod_http2.so LoadModule include_module modules/mod_include.so LoadModule info_module modules/mod_info.so LoadModule log_config_module modules/mod_log_config.so LoadModule logio_module modules/mod_logio.so +LoadModule macro_module modules/mod_macro.so LoadModule mime_magic_module modules/mod_mime_magic.so LoadModule mime_module modules/mod_mime.so LoadModule negotiation_module modules/mod_negotiation.so diff --git a/SOURCES/00-optional.conf b/SOURCES/00-optional.conf index b8c43c6..70bda5e 100644 --- a/SOURCES/00-optional.conf +++ b/SOURCES/00-optional.conf @@ -3,7 +3,9 @@ # which are not enabled by default. # +#LoadModule asis_module modules/mod_asis.so #LoadModule buffer_module modules/mod_buffer.so +#LoadModule file_cache_module modules/mod_file_cache.so #LoadModule watchdog_module modules/mod_watchdog.so #LoadModule heartbeat_module modules/mod_heartbeat.so #LoadModule heartmonitor_module modules/mod_heartmonitor.so @@ -11,6 +13,7 @@ #LoadModule dialup_module modules/mod_dialup.so #LoadModule charset_lite_module modules/mod_charset_lite.so #LoadModule log_debug_module modules/mod_log_debug.so +#LoadModule log_forensic_module modules/mod_log_forensic.so #LoadModule ratelimit_module modules/mod_ratelimit.so #LoadModule reflector_module modules/mod_reflector.so #LoadModule sed_module modules/mod_sed.so diff --git a/SOURCES/00-proxy.conf b/SOURCES/00-proxy.conf index a446822..cc0bca0 100644 --- a/SOURCES/00-proxy.conf +++ b/SOURCES/00-proxy.conf @@ -13,3 +13,4 @@ LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_scgi_module modules/mod_proxy_scgi.so +LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so diff --git a/SOURCES/action-configtest.sh b/SOURCES/action-configtest.sh index 08deca1..d1cc989 100644 --- a/SOURCES/action-configtest.sh +++ b/SOURCES/action-configtest.sh @@ -1,2 +1,2 @@ #!/bin/sh -exec $sbindir/apachectl configtest "$@" +exec $sbindir/apachectl configtest diff --git a/SOURCES/action-graceful.sh b/SOURCES/action-graceful.sh index 33f5330..5d3c87a 100644 --- a/SOURCES/action-graceful.sh +++ b/SOURCES/action-graceful.sh @@ -1,2 +1,2 @@ #!/bin/sh -exec $sbindir/apachectl -k graceful "$@" +exec $sbindir/apachectl graceful diff --git a/SOURCES/htcacheclean.init b/SOURCES/htcacheclean.init index 028ad9b..ebf8d68 100644 --- a/SOURCES/htcacheclean.init +++ b/SOURCES/htcacheclean.init @@ -65,7 +65,9 @@ case "$1" in stop ;; status) - status $binary + # `status' checks lockfile only in /var/lock/subsys by default. + # To workaround that, move outside that directory first. + status -l ../../../${lockfile} $binary RETVAL=$? ;; restart) @@ -73,7 +75,9 @@ case "$1" in start ;; condrestart|try-restart) - if status $binary >&/dev/null; then + # `status' checks lockfile only in /var/lock/subsys by default. + # To workaround that, move outside that directory first. + if status -l ../../../${lockfile} $binary >&/dev/null; then stop start fi diff --git a/SOURCES/httpd-2.4.12-CVE-2015-0228.patch b/SOURCES/httpd-2.4.12-CVE-2015-0228.patch deleted file mode 100644 index 09d3cd6..0000000 --- a/SOURCES/httpd-2.4.12-CVE-2015-0228.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/modules/lua/lua_request.c 2015/03/04 19:17:32 1664117 -+++ b/modules/lua/lua_request.c 2015/03/04 19:18:27 1664118 -@@ -2229,6 +2229,7 @@ - { - apr_socket_t *sock; - apr_status_t rv; -+ int do_read = 1; - int n = 0; - apr_size_t len = 1; - apr_size_t plen = 0; -@@ -2246,6 +2247,8 @@ - mask_bytes = apr_pcalloc(r->pool, 4); - sock = ap_get_conn_socket(r->connection); - -+ while (do_read) { -+ do_read = 0; - /* Get opcode and FIN bit */ - if (plaintext) { - rv = apr_socket_recv(sock, &byte, &len); -@@ -2379,10 +2382,11 @@ - frame[0] = 0x8A; - frame[1] = 0; - apr_socket_send(sock, frame, &plen); /* Pong! */ -- lua_websocket_read(L); /* read the next frame instead */ -+ do_read = 1; - } - } - } -+ } - return 0; - } - diff --git a/SOURCES/httpd-2.4.12-CVE-2015-0253.patch b/SOURCES/httpd-2.4.12-CVE-2015-0253.patch deleted file mode 100644 index ec67a02..0000000 --- a/SOURCES/httpd-2.4.12-CVE-2015-0253.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/server/protocol.c 2015/03/24 13:07:30 1668878 -+++ b/server/protocol.c 2015/03/24 13:08:44 1668879 -@@ -599,8 +599,6 @@ - */ - if (APR_STATUS_IS_ENOSPC(rv)) { - r->status = HTTP_REQUEST_URI_TOO_LARGE; -- r->proto_num = HTTP_VERSION(1,0); -- r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); - } - else if (APR_STATUS_IS_TIMEUP(rv)) { - r->status = HTTP_REQUEST_TIME_OUT; -@@ -608,6 +606,8 @@ - else if (APR_STATUS_IS_EINVAL(rv)) { - r->status = HTTP_BAD_REQUEST; - } -+ r->proto_num = HTTP_VERSION(1,0); -+ r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); - return 0; - } - } while ((len <= 0) && (++num_blank_lines < max_blank_lines)); diff --git a/SOURCES/httpd-2.4.12-CVE-2015-3183.patch b/SOURCES/httpd-2.4.12-CVE-2015-3183.patch deleted file mode 100644 index 593faf3..0000000 --- a/SOURCES/httpd-2.4.12-CVE-2015-3183.patch +++ /dev/null @@ -1,906 +0,0 @@ -diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c -index 733e9c8..ed8749f 100644 ---- a/modules/http/http_filters.c -+++ b/modules/http/http_filters.c -@@ -57,24 +57,29 @@ - - APLOG_USE_MODULE(http); - --#define INVALID_CHAR -2 -- --static long get_chunk_size(char *); -- --typedef struct http_filter_ctx { -+typedef struct http_filter_ctx -+{ - apr_off_t remaining; - apr_off_t limit; - apr_off_t limit_used; -- enum { -- BODY_NONE, -- BODY_LENGTH, -- BODY_CHUNK, -- BODY_CHUNK_PART -+ apr_int32_t chunk_used; -+ apr_int32_t chunk_bws; -+ apr_int32_t chunkbits; -+ enum -+ { -+ BODY_NONE, /* streamed data */ -+ BODY_LENGTH, /* data constrained by content length */ -+ BODY_CHUNK, /* chunk expected */ -+ BODY_CHUNK_PART, /* chunk digits */ -+ BODY_CHUNK_EXT, /* chunk extension */ -+ BODY_CHUNK_CR, /* got space(s) after digits, expect [CR]LF or ext */ -+ BODY_CHUNK_LF, /* got CR after digits or ext, expect LF */ -+ BODY_CHUNK_DATA, /* data constrained by chunked encoding */ -+ BODY_CHUNK_END, /* chunked data terminating CRLF */ -+ BODY_CHUNK_END_LF, /* got CR after data, expect LF */ -+ BODY_CHUNK_TRAILER /* trailers */ - } state; -- int eos_sent; -- char chunk_ln[32]; -- char *pos; -- apr_off_t linesize; -+ unsigned int eos_sent :1; - apr_bucket_brigade *bb; - } http_ctx_t; - -@@ -119,117 +124,154 @@ static apr_status_t bail_out_on_error(http_ctx_t *ctx, - return ap_pass_brigade(f->r->output_filters, bb); - } - --static apr_status_t get_remaining_chunk_line(http_ctx_t *ctx, -- apr_bucket_brigade *b, -- int linelimit) -+/** -+ * Parse a chunk line with optional extension, detect overflow. -+ * There are two error cases: -+ * 1) If the conversion would require too many bits, APR_EGENERAL is returned. -+ * 2) If the conversion used the correct number of bits, but an overflow -+ * caused only the sign bit to flip, then APR_ENOSPC is returned. -+ * In general, any negative number can be considered an overflow error. -+ */ -+static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer, -+ apr_size_t len, int linelimit) - { -- apr_status_t rv; -- apr_off_t brigade_length; -- apr_bucket *e; -- const char *lineend; -- apr_size_t len = 0; -+ apr_size_t i = 0; - -- /* -- * As the brigade b should have been requested in mode AP_MODE_GETLINE -- * all buckets in this brigade are already some type of memory -- * buckets (due to the needed scanning for LF in mode AP_MODE_GETLINE) -- * or META buckets. -- */ -- rv = apr_brigade_length(b, 0, &brigade_length); -- if (rv != APR_SUCCESS) { -- return rv; -- } -- /* Sanity check. Should never happen. See above. */ -- if (brigade_length == -1) { -- return APR_EGENERAL; -- } -- if (!brigade_length) { -- return APR_EAGAIN; -- } -- ctx->linesize += brigade_length; -- if (ctx->linesize > linelimit) { -- return APR_ENOSPC; -- } -- /* -- * As all buckets are already some type of memory buckets or META buckets -- * (see above), we only need to check the last byte in the last data bucket. -- */ -- for (e = APR_BRIGADE_LAST(b); -- e != APR_BRIGADE_SENTINEL(b); -- e = APR_BUCKET_PREV(e)) { -+ while (i < len) { -+ char c = buffer[i]; - -- if (APR_BUCKET_IS_METADATA(e)) { -+ ap_xlate_proto_from_ascii(&c, 1); -+ -+ /* handle CRLF after the chunk */ -+ if (ctx->state == BODY_CHUNK_END -+ || ctx->state == BODY_CHUNK_END_LF) { -+ if (c == LF) { -+ ctx->state = BODY_CHUNK; -+ } -+ else if (c == CR && ctx->state == BODY_CHUNK_END) { -+ ctx->state = BODY_CHUNK_END_LF; -+ } -+ else { -+ /* -+ * LF expected. -+ */ -+ return APR_EINVAL; -+ } -+ i++; - continue; - } -- rv = apr_bucket_read(e, &lineend, &len, APR_BLOCK_READ); -- if (rv != APR_SUCCESS) { -- return rv; -+ -+ /* handle start of the chunk */ -+ if (ctx->state == BODY_CHUNK) { -+ if (!apr_isxdigit(c)) { -+ /* -+ * Detect invalid character at beginning. This also works for -+ * empty chunk size lines. -+ */ -+ return APR_EINVAL; -+ } -+ else { -+ ctx->state = BODY_CHUNK_PART; -+ } -+ ctx->remaining = 0; -+ ctx->chunkbits = sizeof(apr_off_t) * 8; -+ ctx->chunk_used = 0; -+ ctx->chunk_bws = 0; - } -- if (len > 0) { -- break; /* we got the data we want */ -+ -+ if (c == LF) { -+ if (ctx->remaining) { -+ ctx->state = BODY_CHUNK_DATA; -+ } -+ else { -+ ctx->state = BODY_CHUNK_TRAILER; -+ } - } -- /* If we got a zero-length data bucket, we try the next one */ -- } -- /* We had no data in this brigade */ -- if (!len || e == APR_BRIGADE_SENTINEL(b)) { -- return APR_EAGAIN; -- } -- if (lineend[len - 1] != APR_ASCII_LF) { -- return APR_EAGAIN; -- } -- /* Line is complete. So reset ctx for next round. */ -- ctx->linesize = 0; -- ctx->pos = ctx->chunk_ln; -- return APR_SUCCESS; --} -+ else if (ctx->state == BODY_CHUNK_LF) { -+ /* -+ * LF expected. -+ */ -+ return APR_EINVAL; -+ } -+ else if (c == CR) { -+ ctx->state = BODY_CHUNK_LF; -+ } -+ else if (c == ';') { -+ ctx->state = BODY_CHUNK_EXT; -+ } -+ else if (ctx->state == BODY_CHUNK_EXT) { -+ /* -+ * Control chars (but tabs) are invalid. -+ */ -+ if (c != '\t' && apr_iscntrl(c)) { -+ return APR_EINVAL; -+ } -+ } -+ else if (c == ' ' || c == '\t') { -+ /* Be lenient up to 10 BWS (term from rfc7230 - 3.2.3). -+ */ -+ ctx->state = BODY_CHUNK_CR; -+ if (++ctx->chunk_bws > 10) { -+ return APR_EINVAL; -+ } -+ } -+ else if (ctx->state == BODY_CHUNK_CR) { -+ /* -+ * ';', CR or LF expected. -+ */ -+ return APR_EINVAL; -+ } -+ else if (ctx->state == BODY_CHUNK_PART) { -+ int xvalue; - --static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b, -- int linelimit) --{ -- apr_size_t len; -- int tmp_len; -- apr_status_t rv; -+ /* ignore leading zeros */ -+ if (!ctx->remaining && c == '0') { -+ i++; -+ continue; -+ } - -- tmp_len = sizeof(ctx->chunk_ln) - (ctx->pos - ctx->chunk_ln) - 1; -- /* Saveguard ourselves against underflows */ -- if (tmp_len < 0) { -- len = 0; -- } -- else { -- len = (apr_size_t) tmp_len; -- } -- /* -- * Check if there is space left in ctx->chunk_ln. If not, then either -- * the chunk size is insane or we have chunk-extensions. Ignore both -- * by discarding the remaining part of the line via -- * get_remaining_chunk_line. Only bail out if the line is too long. -- */ -- if (len > 0) { -- rv = apr_brigade_flatten(b, ctx->pos, &len); -- if (rv != APR_SUCCESS) { -- return rv; -+ ctx->chunkbits -= 4; -+ if (ctx->chunkbits < 0) { -+ /* overflow */ -+ return APR_ENOSPC; -+ } -+ -+ if (c >= '0' && c <= '9') { -+ xvalue = c - '0'; -+ } -+ else if (c >= 'A' && c <= 'F') { -+ xvalue = c - 'A' + 0xa; -+ } -+ else if (c >= 'a' && c <= 'f') { -+ xvalue = c - 'a' + 0xa; -+ } -+ else { -+ /* bogus character */ -+ return APR_EINVAL; -+ } -+ -+ ctx->remaining = (ctx->remaining << 4) | xvalue; -+ if (ctx->remaining < 0) { -+ /* overflow */ -+ return APR_ENOSPC; -+ } - } -- ctx->pos += len; -- ctx->linesize += len; -- *(ctx->pos) = '\0'; -- /* -- * Check if we really got a full line. If yes the -- * last char in the just read buffer must be LF. -- * If not advance the buffer and return APR_EAGAIN. -- * We do not start processing until we have the -- * full line. -- */ -- if (ctx->pos[-1] != APR_ASCII_LF) { -- /* Check if the remaining data in the brigade has the LF */ -- return get_remaining_chunk_line(ctx, b, linelimit); -+ else { -+ /* Should not happen */ -+ return APR_EGENERAL; - } -- /* Line is complete. So reset ctx->pos for next round. */ -- ctx->pos = ctx->chunk_ln; -- return APR_SUCCESS; -+ -+ i++; -+ } -+ -+ /* sanity check */ -+ ctx->chunk_used += len; -+ if (ctx->chunk_used < 0 || ctx->chunk_used > linelimit) { -+ return APR_ENOSPC; - } -- return get_remaining_chunk_line(ctx, b, linelimit); --} - -+ return APR_SUCCESS; -+} - - static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *b, int merge) -@@ -243,7 +285,6 @@ static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, - r->status = HTTP_OK; - r->headers_in = r->trailers_in; - apr_table_clear(r->headers_in); -- ctx->state = BODY_NONE; - ap_get_mime_headers(r); - - if(r->status == HTTP_OK) { -@@ -256,7 +297,7 @@ static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, - else { - const char *error_notes = apr_table_get(r->notes, - "error-notes"); -- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02656) - "Error while reading HTTP trailer: %i%s%s", - r->status, error_notes ? ": " : "", - error_notes ? error_notes : ""); -@@ -287,9 +328,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - apr_bucket *e; - http_ctx_t *ctx = f->ctx; - apr_status_t rv; -- apr_off_t totalread; - int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; - apr_bucket_brigade *bb; -+ int again; - - conf = (core_server_config *) - ap_get_module_config(f->r->server->module_config, &core_module); -@@ -303,7 +344,6 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - const char *tenc, *lenp; - f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); - ctx->state = BODY_NONE; -- ctx->pos = ctx->chunk_ln; - ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); - bb = ctx->bb; - -@@ -335,14 +375,17 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - * reading the connection until it is closed by the server." - */ - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02555) -- "Unknown Transfer-Encoding: %s;" -- " using read-until-close", tenc); -+ "Unknown Transfer-Encoding: %s; " -+ "using read-until-close", tenc); - tenc = NULL; - } - else { -+ /* Something that isn't a HTTP request, unless some future -+ * edition defines new transfer encodings, is unsupported. -+ */ - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01585) - "Unknown Transfer-Encoding: %s", tenc); -- return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED); -+ return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST); - } - lenp = NULL; - } -@@ -361,7 +404,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01587) - "Invalid Content-Length"); - -- return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE); -+ return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST); - } - - /* If we have a limit in effect and we know the C-L ahead of -@@ -403,7 +446,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - if (!ap_is_HTTP_SUCCESS(f->r->status)) { - ctx->state = BODY_NONE; - ctx->eos_sent = 1; -- } else { -+ } -+ else { - char *tmp; - int len; - -@@ -423,288 +467,205 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, - e = apr_bucket_flush_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - -- ap_pass_brigade(f->c->output_filters, bb); -- } -- } -- -- /* We can't read the chunk until after sending 100 if required. */ -- if (ctx->state == BODY_CHUNK) { -- apr_brigade_cleanup(bb); -- -- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, -- block, 0); -- -- /* for timeout */ -- if (block == APR_NONBLOCK_READ && -- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || -- (APR_STATUS_IS_EAGAIN(rv)) )) { -- ctx->state = BODY_CHUNK_PART; -- return APR_EAGAIN; -- } -- -- if (rv == APR_SUCCESS) { -- rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line); -- if (APR_STATUS_IS_EAGAIN(rv)) { -- apr_brigade_cleanup(bb); -- ctx->state = BODY_CHUNK_PART; -- return rv; -- } -- if (rv == APR_SUCCESS) { -- ctx->remaining = get_chunk_size(ctx->chunk_ln); -- if (ctx->remaining == INVALID_CHAR) { -- rv = APR_EGENERAL; -- http_error = HTTP_BAD_REQUEST; -- } -- } -- } -- apr_brigade_cleanup(bb); -- -- /* Detect chunksize error (such as overflow) */ -- if (rv != APR_SUCCESS || ctx->remaining < 0) { -- ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01589) "Error reading first chunk %s ", -- (ctx->remaining < 0) ? "(overflow)" : ""); -- if (APR_STATUS_IS_TIMEUP(rv) || ctx->remaining > 0) { -- http_error = HTTP_REQUEST_TIME_OUT; -+ rv = ap_pass_brigade(f->c->output_filters, bb); -+ if (rv != APR_SUCCESS) { -+ return AP_FILTER_ERROR; - } -- ctx->remaining = 0; /* Reset it in case we have to -- * come back here later */ -- return bail_out_on_error(ctx, f, http_error); -- } -- -- if (!ctx->remaining) { -- return read_chunked_trailers(ctx, f, b, -- conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); - } - } - } -- else { -- bb = ctx->bb; -- } - -+ /* sanity check in case we're read twice */ - if (ctx->eos_sent) { - e = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(b, e); - return APR_SUCCESS; - } - -- if (!ctx->remaining) { -+ do { -+ apr_brigade_cleanup(b); -+ again = 0; /* until further notice */ -+ -+ /* read and handle the brigade */ - switch (ctx->state) { -- case BODY_NONE: -- break; -- case BODY_LENGTH: -- e = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(b, e); -- ctx->eos_sent = 1; -- return APR_SUCCESS; - case BODY_CHUNK: - case BODY_CHUNK_PART: -- { -- apr_brigade_cleanup(bb); -+ case BODY_CHUNK_EXT: -+ case BODY_CHUNK_CR: -+ case BODY_CHUNK_LF: -+ case BODY_CHUNK_END: -+ case BODY_CHUNK_END_LF: { - -- /* We need to read the CRLF after the chunk. */ -- if (ctx->state == BODY_CHUNK) { -- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, -- block, 0); -- if (block == APR_NONBLOCK_READ && -- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || -- (APR_STATUS_IS_EAGAIN(rv)) )) { -- return APR_EAGAIN; -- } -- /* If we get an error, then leave */ -- if (rv == APR_EOF) { -- return APR_INCOMPLETE; -- } -- if (rv != APR_SUCCESS) { -- return rv; -- } -- /* -- * We really don't care whats on this line. If it is RFC -- * compliant it should be only \r\n. If there is more -- * before we just ignore it as long as we do not get over -- * the limit for request lines. -- */ -- rv = get_remaining_chunk_line(ctx, bb, -- f->r->server->limit_req_line); -- apr_brigade_cleanup(bb); -- if (APR_STATUS_IS_EAGAIN(rv)) { -- return rv; -- } -- } else { -- rv = APR_SUCCESS; -- } -+ rv = ap_get_brigade(f->next, b, AP_MODE_GETLINE, block, 0); -+ -+ /* for timeout */ -+ if (block == APR_NONBLOCK_READ -+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) -+ || (APR_STATUS_IS_EAGAIN(rv)))) { -+ return APR_EAGAIN; -+ } -+ -+ if (rv == APR_EOF) { -+ return APR_INCOMPLETE; -+ } -+ -+ if (rv != APR_SUCCESS) { -+ return rv; -+ } -+ -+ e = APR_BRIGADE_FIRST(b); -+ while (e != APR_BRIGADE_SENTINEL(b)) { -+ const char *buffer; -+ apr_size_t len; -+ -+ if (!APR_BUCKET_IS_METADATA(e)) { -+ int parsing = 0; -+ -+ rv = apr_bucket_read(e, &buffer, &len, APR_BLOCK_READ); - -- if (rv == APR_SUCCESS) { -- /* Read the real chunk line. */ -- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, -- block, 0); -- /* Test timeout */ -- if (block == APR_NONBLOCK_READ && -- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || -- (APR_STATUS_IS_EAGAIN(rv)) )) { -- ctx->state = BODY_CHUNK_PART; -- return APR_EAGAIN; -- } -- ctx->state = BODY_CHUNK; - if (rv == APR_SUCCESS) { -- rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line); -- if (APR_STATUS_IS_EAGAIN(rv)) { -- ctx->state = BODY_CHUNK_PART; -- apr_brigade_cleanup(bb); -- return rv; -- } -- if (rv == APR_SUCCESS) { -- ctx->remaining = get_chunk_size(ctx->chunk_ln); -- if (ctx->remaining == INVALID_CHAR) { -- rv = APR_EGENERAL; -+ parsing = 1; -+ rv = parse_chunk_size(ctx, buffer, len, -+ f->r->server->limit_req_fieldsize); -+ } -+ if (rv != APR_SUCCESS) { -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590) -+ "Error reading/parsing chunk %s ", -+ (APR_ENOSPC == rv) ? "(overflow)" : ""); -+ if (parsing) { -+ if (rv != APR_ENOSPC) { - http_error = HTTP_BAD_REQUEST; - } -+ return bail_out_on_error(ctx, f, http_error); - } -+ return rv; - } -- apr_brigade_cleanup(bb); - } - -- /* Detect chunksize error (such as overflow) */ -- if (rv != APR_SUCCESS || ctx->remaining < 0) { -- ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590) "Error reading chunk %s ", -- (ctx->remaining < 0) ? "(overflow)" : ""); -- if (APR_STATUS_IS_TIMEUP(rv) || ctx->remaining > 0) { -- http_error = HTTP_REQUEST_TIME_OUT; -- } -- ctx->remaining = 0; /* Reset it in case we have to -- * come back here later */ -- return bail_out_on_error(ctx, f, http_error); -- } -+ apr_bucket_delete(e); -+ e = APR_BRIGADE_FIRST(b); -+ } -+ again = 1; /* come around again */ - -- if (!ctx->remaining) { -- return read_chunked_trailers(ctx, f, b, -+ if (ctx->state == BODY_CHUNK_TRAILER) { -+ /* Treat UNSET as DISABLE - trailers aren't merged by default */ -+ return read_chunked_trailers(ctx, f, b, - conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); -- } - } -+ - break; - } -- } -+ case BODY_NONE: -+ case BODY_LENGTH: -+ case BODY_CHUNK_DATA: { - -- /* Ensure that the caller can not go over our boundary point. */ -- if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) { -- if (ctx->remaining < readbytes) { -- readbytes = ctx->remaining; -- } -- AP_DEBUG_ASSERT(readbytes > 0); -- } -+ /* Ensure that the caller can not go over our boundary point. */ -+ if (ctx->state != BODY_NONE && ctx->remaining < readbytes) { -+ readbytes = ctx->remaining; -+ } -+ if (readbytes > 0) { -+ apr_off_t totalread; - -- rv = ap_get_brigade(f->next, b, mode, block, readbytes); -+ rv = ap_get_brigade(f->next, b, mode, block, readbytes); - -- if (rv == APR_EOF && ctx->state != BODY_NONE && -- ctx->remaining > 0) { -- return APR_INCOMPLETE; -- } -- if (rv != APR_SUCCESS) { -- return rv; -- } -+ /* for timeout */ -+ if (block == APR_NONBLOCK_READ -+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) -+ || (APR_STATUS_IS_EAGAIN(rv)))) { -+ return APR_EAGAIN; -+ } - -- /* How many bytes did we just read? */ -- apr_brigade_length(b, 0, &totalread); -+ if (rv == APR_EOF && ctx->state != BODY_NONE -+ && ctx->remaining > 0) { -+ return APR_INCOMPLETE; -+ } - -- /* If this happens, we have a bucket of unknown length. Die because -- * it means our assumptions have changed. */ -- AP_DEBUG_ASSERT(totalread >= 0); -+ if (rv != APR_SUCCESS) { -+ return rv; -+ } - -- if (ctx->state != BODY_NONE) { -- ctx->remaining -= totalread; -- if (ctx->remaining > 0) { -- e = APR_BRIGADE_LAST(b); -- if (APR_BUCKET_IS_EOS(e)) { -- apr_bucket_delete(e); -- return APR_INCOMPLETE; -- } -- } -- } -+ /* How many bytes did we just read? */ -+ apr_brigade_length(b, 0, &totalread); - -- /* If we have no more bytes remaining on a C-L request, -- * save the callter a roundtrip to discover EOS. -- */ -- if (ctx->state == BODY_LENGTH && ctx->remaining == 0) { -- e = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(b, e); -- } -+ /* If this happens, we have a bucket of unknown length. Die because -+ * it means our assumptions have changed. */ -+ AP_DEBUG_ASSERT(totalread >= 0); - -- /* We have a limit in effect. */ -- if (ctx->limit) { -- /* FIXME: Note that we might get slightly confused on chunked inputs -- * as we'd need to compensate for the chunk lengths which may not -- * really count. This seems to be up for interpretation. */ -- ctx->limit_used += totalread; -- if (ctx->limit < ctx->limit_used) { -- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01591) -- "Read content-length of %" APR_OFF_T_FMT -- " is larger than the configured limit" -- " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit); -- apr_brigade_cleanup(bb); -- e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, -- f->r->pool, -- f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, e); -- e = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, e); -- ctx->eos_sent = 1; -- return ap_pass_brigade(f->r->output_filters, bb); -- } -- } -+ if (ctx->state != BODY_NONE) { -+ ctx->remaining -= totalread; -+ if (ctx->remaining > 0) { -+ e = APR_BRIGADE_LAST(b); -+ if (APR_BUCKET_IS_EOS(e)) { -+ apr_bucket_delete(e); -+ return APR_INCOMPLETE; -+ } -+ } -+ else if (ctx->state == BODY_CHUNK_DATA) { -+ /* next chunk please */ -+ ctx->state = BODY_CHUNK_END; -+ ctx->chunk_used = 0; -+ } -+ } - -- return APR_SUCCESS; --} -+ /* We have a limit in effect. */ -+ if (ctx->limit) { -+ /* FIXME: Note that we might get slightly confused on -+ * chunked inputs as we'd need to compensate for the chunk -+ * lengths which may not really count. This seems to be up -+ * for interpretation. -+ */ -+ ctx->limit_used += totalread; -+ if (ctx->limit < ctx->limit_used) { -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, -+ APLOGNO(01591) "Read content length of " -+ "%" APR_OFF_T_FMT " is larger than the " -+ "configured limit of %" APR_OFF_T_FMT, -+ ctx->limit_used, ctx->limit); -+ return bail_out_on_error(ctx, f, -+ HTTP_REQUEST_ENTITY_TOO_LARGE); -+ } -+ } -+ } - --/** -- * Parse a chunk extension, detect overflow. -- * There are two error cases: -- * 1) If the conversion would require too many bits, a -1 is returned. -- * 2) If the conversion used the correct number of bits, but an overflow -- * caused only the sign bit to flip, then that negative number is -- * returned. -- * In general, any negative number can be considered an overflow error. -- */ --static long get_chunk_size(char *b) --{ -- long chunksize = 0; -- size_t chunkbits = sizeof(long) * 8; -+ /* If we have no more bytes remaining on a C-L request, -+ * save the caller a round trip to discover EOS. -+ */ -+ if (ctx->state == BODY_LENGTH && ctx->remaining == 0) { -+ e = apr_bucket_eos_create(f->c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(b, e); -+ ctx->eos_sent = 1; -+ } - -- ap_xlate_proto_from_ascii(b, strlen(b)); -+ break; -+ } -+ case BODY_CHUNK_TRAILER: { - -- if (!apr_isxdigit(*b)) { -- /* -- * Detect invalid character at beginning. This also works for empty -- * chunk size lines. -- */ -- return INVALID_CHAR; -- } -- /* Skip leading zeros */ -- while (*b == '0') { -- ++b; -- } -+ rv = ap_get_brigade(f->next, b, mode, block, readbytes); -+ -+ /* for timeout */ -+ if (block == APR_NONBLOCK_READ -+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) -+ || (APR_STATUS_IS_EAGAIN(rv)))) { -+ return APR_EAGAIN; -+ } - -- while (apr_isxdigit(*b) && (chunkbits > 0)) { -- int xvalue = 0; -+ if (rv != APR_SUCCESS) { -+ return rv; -+ } - -- if (*b >= '0' && *b <= '9') { -- xvalue = *b - '0'; -+ break; - } -- else if (*b >= 'A' && *b <= 'F') { -- xvalue = *b - 'A' + 0xa; -+ default: { -+ /* Should not happen */ -+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02901) -+ "Unexpected body state (%i)", (int)ctx->state); -+ return APR_EGENERAL; - } -- else if (*b >= 'a' && *b <= 'f') { -- xvalue = *b - 'a' + 0xa; - } - -- chunksize = (chunksize << 4) | xvalue; -- chunkbits -= 4; -- ++b; -- } -- if (apr_isxdigit(*b)) { -- /* overflow */ -- return -1; -- } -+ } while (again); - -- return chunksize; -+ return APR_SUCCESS; - } - - typedef struct header_struct { -@@ -1416,6 +1377,39 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, - return ap_pass_brigade(f->next, b); - } - -+/* -+ * Map specific APR codes returned by the filter stack to HTTP error -+ * codes, or the default status code provided. Use it as follows: -+ * -+ * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); -+ * -+ * If the filter has already handled the error, AP_FILTER_ERROR will -+ * be returned, which is cleanly passed through. -+ * -+ * These mappings imply that the filter stack is reading from the -+ * downstream client, the proxy will map these codes differently. -+ */ -+AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status) -+{ -+ switch (rv) { -+ case AP_FILTER_ERROR: { -+ return AP_FILTER_ERROR; -+ } -+ case APR_ENOSPC: { -+ return HTTP_REQUEST_ENTITY_TOO_LARGE; -+ } -+ case APR_ENOTIMPL: { -+ return HTTP_NOT_IMPLEMENTED; -+ } -+ case APR_ETIMEDOUT: { -+ return HTTP_REQUEST_TIME_OUT; -+ } -+ default: { -+ return status; -+ } -+ } -+} -+ - /* In HTTP/1.1, any method can have a body. However, most GET handlers - * wouldn't know what to do with a request body if they received one. - * This helper routine tests for and reads any message body in the request, -@@ -1433,7 +1427,8 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, - AP_DECLARE(int) ap_discard_request_body(request_rec *r) - { - apr_bucket_brigade *bb; -- int rv, seen_eos; -+ int seen_eos; -+ apr_status_t rv; - - /* Sometimes we'll get in a state where the input handling has - * detected an error where we want to drop the connection, so if -@@ -1456,21 +1451,8 @@ AP_DECLARE(int) ap_discard_request_body(request_rec *r) - APR_BLOCK_READ, HUGE_STRING_LEN); - - if (rv != APR_SUCCESS) { -- /* FIXME: If we ever have a mapping from filters (apr_status_t) -- * to HTTP error codes, this would be a good place for them. -- * -- * If we received the special case AP_FILTER_ERROR, it means -- * that the filters have already handled this error. -- * Otherwise, we should assume we have a bad request. -- */ -- if (rv == AP_FILTER_ERROR) { -- apr_brigade_destroy(bb); -- return rv; -- } -- else { -- apr_brigade_destroy(bb); -- return HTTP_BAD_REQUEST; -- } -+ apr_brigade_destroy(bb); -+ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); - } - - for (bucket = APR_BRIGADE_FIRST(bb); -@@ -1639,6 +1621,13 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, - /* We lose the failure code here. This is why ap_get_client_block should - * not be used. - */ -+ if (rv == AP_FILTER_ERROR) { -+ /* AP_FILTER_ERROR means a filter has responded already, -+ * we are DONE. -+ */ -+ apr_brigade_destroy(bb); -+ return -1; -+ } - if (rv != APR_SUCCESS) { - /* if we actually fail here, we want to just return and - * stop trying to read data from the client. diff --git a/SOURCES/httpd-2.4.12-CVE-2015-3185.patch b/SOURCES/httpd-2.4.12-CVE-2015-3185.patch deleted file mode 100644 index aa1e95e..0000000 --- a/SOURCES/httpd-2.4.12-CVE-2015-3185.patch +++ /dev/null @@ -1,175 +0,0 @@ -Index: server/request.c -=================================================================== ---- a/server/request.c (revision 1684524) -+++ b/server/request.c (revision 1684525) -@@ -71,6 +71,7 @@ - APR_HOOK_LINK(create_request) - APR_HOOK_LINK(post_perdir_config) - APR_HOOK_LINK(dirwalk_stat) -+ APR_HOOK_LINK(force_authn) - ) - - AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, -@@ -97,6 +98,8 @@ - AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t,dirwalk_stat, - (apr_finfo_t *finfo, request_rec *r, apr_int32_t wanted), - (finfo, r, wanted), AP_DECLINED) -+AP_IMPLEMENT_HOOK_RUN_FIRST(int,force_authn, -+ (request_rec *r), (r), DECLINED) - - static int auth_internal_per_conf = 0; - static int auth_internal_per_conf_hooks = 0; -@@ -118,6 +121,39 @@ - } - } - -+AP_DECLARE(int) ap_some_authn_required(request_rec *r) -+{ -+ int access_status; -+ -+ switch (ap_satisfies(r)) { -+ case SATISFY_ALL: -+ case SATISFY_NOSPEC: -+ if ((access_status = ap_run_access_checker(r)) != OK) { -+ break; -+ } -+ -+ access_status = ap_run_access_checker_ex(r); -+ if (access_status == DECLINED) { -+ return TRUE; -+ } -+ -+ break; -+ case SATISFY_ANY: -+ if ((access_status = ap_run_access_checker(r)) == OK) { -+ break; -+ } -+ -+ access_status = ap_run_access_checker_ex(r); -+ if (access_status == DECLINED) { -+ return TRUE; -+ } -+ -+ break; -+ } -+ -+ return FALSE; -+} -+ - /* This is the master logic for processing requests. Do NOT duplicate - * this logic elsewhere, or the security model will be broken by future - * API changes. Each phase must be individually optimized to pick up -@@ -232,15 +268,8 @@ - } - - access_status = ap_run_access_checker_ex(r); -- if (access_status == OK) { -- ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, -- "request authorized without authentication by " -- "access_checker_ex hook: %s", r->uri); -- } -- else if (access_status != DECLINED) { -- return decl_die(access_status, "check access", r); -- } -- else { -+ if (access_status == DECLINED -+ || (access_status == OK && ap_run_force_authn(r) == OK)) { - if ((access_status = ap_run_check_user_id(r)) != OK) { - return decl_die(access_status, "check user", r); - } -@@ -258,6 +287,14 @@ - return decl_die(access_status, "check authorization", r); - } - } -+ else if (access_status == OK) { -+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, -+ "request authorized without authentication by " -+ "access_checker_ex hook: %s", r->uri); -+ } -+ else { -+ return decl_die(access_status, "check access", r); -+ } - break; - case SATISFY_ANY: - if ((access_status = ap_run_access_checker(r)) == OK) { -@@ -269,15 +306,8 @@ - } - - access_status = ap_run_access_checker_ex(r); -- if (access_status == OK) { -- ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, -- "request authorized without authentication by " -- "access_checker_ex hook: %s", r->uri); -- } -- else if (access_status != DECLINED) { -- return decl_die(access_status, "check access", r); -- } -- else { -+ if (access_status == DECLINED -+ || (access_status == OK && ap_run_force_authn(r) == OK)) { - if ((access_status = ap_run_check_user_id(r)) != OK) { - return decl_die(access_status, "check user", r); - } -@@ -295,6 +325,14 @@ - return decl_die(access_status, "check authorization", r); - } - } -+ else if (access_status == OK) { -+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, -+ "request authorized without authentication by " -+ "access_checker_ex hook: %s", r->uri); -+ } -+ else { -+ return decl_die(access_status, "check access", r); -+ } - break; - } - } -Index: include/http_request.h -=================================================================== ---- a/include/http_request.h 2015/06/09 20:41:28 1684524 -+++ b/include/http_request.h 2015/06/09 20:42:44 1684525 -@@ -185,6 +185,8 @@ - * is required for the current request - * @param r The current request - * @return 1 if authentication is required, 0 otherwise -+ * @bug Behavior changed in 2.4.x refactoring, API no longer usable -+ * @deprecated @see ap_some_authn_required() - */ - AP_DECLARE(int) ap_some_auth_required(request_rec *r); - -@@ -539,6 +541,16 @@ - AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) - - /** -+ * This hook allows a module to force authn to be required when -+ * processing a request. -+ * This hook should be registered with ap_hook_force_authn(). -+ * @param r The current request -+ * @return OK (force authn), DECLINED (let later modules decide) -+ * @ingroup hooks -+ */ -+AP_DECLARE_HOOK(int,force_authn,(request_rec *r)) -+ -+/** - * This hook allows modules to handle/emulate the apr_stat() calls - * needed for directory walk. - * @param finfo where to put the stat data -@@ -584,6 +596,17 @@ - AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list, - request_rec *r); - -+/** -+ * Can be used within any handler to determine if any authentication -+ * is required for the current request. Note that if used with an -+ * access_checker hook, an access_checker_ex hook or an authz provider; the -+ * caller should take steps to avoid a loop since this function is -+ * implemented by calling these hooks. -+ * @param r The current request -+ * @return TRUE if authentication is required, FALSE otherwise -+ */ -+AP_DECLARE(int) ap_some_authn_required(request_rec *r); -+ - #ifdef __cplusplus - } - #endif diff --git a/SOURCES/httpd-2.4.17-autoindex-revert.patch b/SOURCES/httpd-2.4.17-autoindex-revert.patch new file mode 100644 index 0000000..c6147a0 --- /dev/null +++ b/SOURCES/httpd-2.4.17-autoindex-revert.patch @@ -0,0 +1,15 @@ +diff -Naur httpd-2.4.17/modules/generators/mod_autoindex.c httpd-2.4.17.new/modules/generators/mod_autoindex.c +--- httpd-2.4.17/modules/generators/mod_autoindex.c 2015-10-06 14:36:36.000000000 +0200 ++++ httpd-2.4.17.new/modules/generators/mod_autoindex.c 2015-10-16 13:14:16.043883282 +0200 +@@ -2274,10 +2274,7 @@ + autoindex_config_rec *d; + int allow_opts; + +- if (strcmp(r->handler,DIR_MAGIC_TYPE) && !AP_IS_DEFAULT_HANDLER_NAME(r->handler)) { +- return DECLINED; +- } +- if (r->finfo.filetype != APR_DIR) { ++ if(strcmp(r->handler,DIR_MAGIC_TYPE)) { + return DECLINED; + } + diff --git a/SOURCES/httpd-2.4.18-apachectl-httpd-env2.patch b/SOURCES/httpd-2.4.18-apachectl-httpd-env2.patch new file mode 100644 index 0000000..c15fc1a --- /dev/null +++ b/SOURCES/httpd-2.4.18-apachectl-httpd-env2.patch @@ -0,0 +1,13 @@ +diff --git a/support/apachectl.in b/support/apachectl.in +index 47aeb3d..81ce9bf 100644 +--- a/support/apachectl.in ++++ b/support/apachectl.in +@@ -102,7 +102,7 @@ ERROR=$? + + case $ACMD in + start|stop|restart|graceful|graceful-stop) +- $HTTPD $OPTIONS -k $ARGV ++ $sbindir/httpd $OPTIONS -k $ARGV + ERROR=$? + ;; + startssl|sslstart|start-SSL) diff --git a/SOURCES/httpd-2.4.18-apxs.patch b/SOURCES/httpd-2.4.18-apxs.patch new file mode 100644 index 0000000..1566249 --- /dev/null +++ b/SOURCES/httpd-2.4.18-apxs.patch @@ -0,0 +1,47 @@ + +Use libdir from configuration. + +--- httpd-2.4.18/support/apxs.in.apxs ++++ httpd-2.4.18/support/apxs.in +@@ -35,6 +35,7 @@ my $CFG_PREFIX = $prefix; + my $exec_prefix = get_vars("exec_prefix"); + my $datadir = get_vars("datadir"); + my $localstatedir = get_vars("localstatedir"); ++my $libdir = get_vars("libdir"); + my $CFG_TARGET = get_vars("progname"); + my $CFG_SYSCONFDIR = get_vars("sysconfdir"); + my $CFG_CFLAGS = join ' ', map { get_vars($_) } +@@ -275,7 +276,7 @@ if ($opt_g) { + $data =~ s|%NAME%|$name|sg; + $data =~ s|%TARGET%|$CFG_TARGET|sg; + $data =~ s|%PREFIX%|$prefix|sg; +- $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg; ++ $data =~ s|%LIBDIR%|$libdir|sg; + + my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); + +@@ -453,11 +454,11 @@ if ($opt_c) { + my $ldflags = "$CFG_LDFLAGS"; + if ($opt_p == 1) { + +- my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`; ++ my $apr_libs=`$apr_config --cflags --ldflags --link-libtool`; + chomp($apr_libs); + my $apu_libs=""; + if ($apr_major_version < 2) { +- $apu_libs=`$apu_config --ldflags --link-libtool --libs`; ++ $apu_libs=`$apu_config --ldflags --link-libtool`; + chomp($apu_libs); + } + +@@ -672,8 +673,8 @@ __DATA__ + + builddir=. + top_srcdir=%PREFIX% +-top_builddir=%PREFIX% +-include %INSTALLBUILDDIR%/special.mk ++top_builddir=%LIBDIR%/httpd ++include %LIBDIR%/httpd/build/special.mk + + # the used tools + APACHECTL=apachectl diff --git a/SOURCES/httpd-2.4.18-documentroot.patch b/SOURCES/httpd-2.4.18-documentroot.patch new file mode 100644 index 0000000..182bc04 --- /dev/null +++ b/SOURCES/httpd-2.4.18-documentroot.patch @@ -0,0 +1,13 @@ +--- a/server/core.c 2013/07/24 09:49:38 1506473 ++++ b/server/core.c 2013/07/24 09:51:14 1506474 +@@ -1481,7 +1481,9 @@ + conf->ap_document_root = arg; + } + else { +- return "DocumentRoot must be a directory"; ++ return apr_psprintf(cmd->pool, ++ "DocumentRoot '%s' is not a directory, or is not readable", ++ arg); + } + } + return NULL; diff --git a/SOURCES/httpd-2.4.18-r1684636.patch b/SOURCES/httpd-2.4.18-r1684636.patch new file mode 100644 index 0000000..c99bdcc --- /dev/null +++ b/SOURCES/httpd-2.4.18-r1684636.patch @@ -0,0 +1,24 @@ +--- a/modules/aaa/mod_auth_digest.c 2015/06/10 10:32:46 1684635 ++++ b/modules/aaa/mod_auth_digest.c 2015/06/10 10:43:54 1684636 +@@ -249,9 +249,18 @@ + client_shm_filename = ap_runtime_dir_relative(ctx, "authdigest_shm"); + client_shm_filename = ap_append_pid(ctx, client_shm_filename, "."); + +- /* Now create that segment */ +- sts = apr_shm_create(&client_shm, shmem_size, +- client_shm_filename, ctx); ++ /* Use anonymous shm by default, fall back on name-based. */ ++ sts = apr_shm_create(&client_shm, shmem_size, NULL, ctx); ++ if (APR_STATUS_IS_ENOTIMPL(sts)) { ++ /* For a name-based segment, remove it first in case of a ++ * previous unclean shutdown. */ ++ apr_shm_remove(client_shm_filename, ctx); ++ ++ /* Now create that segment */ ++ sts = apr_shm_create(&client_shm, shmem_size, ++ client_shm_filename, ctx); ++ } ++ + if (APR_SUCCESS != sts) { + ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01762) + "Failed to create shared memory segment on file %s", diff --git a/SOURCES/httpd-2.4.18-r1738229.patch b/SOURCES/httpd-2.4.18-r1738229.patch new file mode 100644 index 0000000..1fcc79d --- /dev/null +++ b/SOURCES/httpd-2.4.18-r1738229.patch @@ -0,0 +1,59 @@ +# ./pullrev.sh 1738229 + +https://bugzilla.redhat.com/show_bug.cgi?id=1225116 + +As for mod_auth_digest, fix to use anonymous SHM by default. + +http://svn.apache.org/viewvc?view=revision&revision=1738229 + +--- httpd-2.4.18/modules/lua/mod_lua.c ++++ httpd-2.4.18/modules/lua/mod_lua.c +@@ -83,6 +83,8 @@ + int broken; + } lua_filter_ctx; + ++#define DEFAULT_LUA_SHMFILE "lua_ivm_shm" ++ + apr_global_mutex_t *lua_ivm_mutex; + apr_shm_t *lua_ivm_shm; + char *lua_ivm_shmfile; +@@ -1995,7 +1997,6 @@ + apr_pool_t *ptemp, server_rec *s) + { + apr_pool_t **pool; +- const char *tempdir; + apr_status_t rs; + + lua_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); +@@ -2011,21 +2012,20 @@ + return HTTP_INTERNAL_SERVER_ERROR; + } + +- /* Create shared memory space */ +- rs = apr_temp_dir_get(&tempdir, pconf); +- if (rs != APR_SUCCESS) { +- ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02664) +- "mod_lua IVM: Failed to find temporary directory"); +- return HTTP_INTERNAL_SERVER_ERROR; ++ /* Create shared memory space, anonymous first if possible. */ ++ rs = apr_shm_create(&lua_ivm_shm, sizeof pool, NULL, pconf); ++ if (APR_STATUS_IS_ENOTIMPL(rs)) { ++ /* Fall back to filename-based; nuke any left-over first. */ ++ lua_ivm_shmfile = ap_runtime_dir_relative(pconf, DEFAULT_LUA_SHMFILE); ++ ++ apr_shm_remove(lua_ivm_shmfile, pconf); ++ ++ rs = apr_shm_create(&lua_ivm_shm, sizeof pool, lua_ivm_shmfile, pconf); + } +- lua_ivm_shmfile = apr_psprintf(pconf, "%s/httpd_lua_shm.%ld", tempdir, +- (long int)getpid()); +- rs = apr_shm_create(&lua_ivm_shm, sizeof(apr_pool_t**), +- (const char *) lua_ivm_shmfile, pconf); + if (rs != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02665) + "mod_lua: Failed to create shared memory segment on file %s", +- lua_ivm_shmfile); ++ lua_ivm_shmfile ? lua_ivm_shmfile : "(anonymous)"); + return HTTP_INTERNAL_SERVER_ERROR; + } + pool = (apr_pool_t **)apr_shm_baseaddr_get(lua_ivm_shm); diff --git a/SOURCES/httpd-2.4.3-apctl-systemd.patch b/SOURCES/httpd-2.4.3-apctl-systemd.patch index 30a613d..d8adf87 100644 --- a/SOURCES/httpd-2.4.3-apctl-systemd.patch +++ b/SOURCES/httpd-2.4.3-apctl-systemd.patch @@ -1,11 +1,9 @@ Upstream-Status: vendor specific patch -diff --git a/support/apachectl.in b/support/apachectl.in -index c6ac3ea..2599386 100644 ---- a/support/apachectl.in -+++ b/support/apachectl.in -@@ -100,9 +100,24 @@ fi +--- httpd-2.4.18/support/apachectl.in.apctlsystemd ++++ httpd-2.4.18/support/apachectl.in +@@ -100,9 +100,28 @@ fi ERROR=$? } @@ -24,7 +22,11 @@ index c6ac3ea..2599386 100644 + ERROR=$? + ;; +graceful) -+ /usr/bin/systemctl reload httpd24-httpd.service ++ if /usr/bin/systemctl -q is-active httpd24-httpd.service; then ++ /usr/bin/systemctl reload httpd24-httpd.service ++ else ++ /usr/bin/systemctl start httpd24-httpd.service ++ fi + ERROR=$? + ;; +graceful-stop) @@ -32,7 +34,7 @@ index c6ac3ea..2599386 100644 ERROR=$? ;; startssl|sslstart|start-SSL) -@@ -114,10 +129,6 @@ startssl|sslstart|start-SSL) +@@ -114,10 +133,6 @@ startssl|sslstart|start-SSL) configtest) testconfig ;; diff --git a/SOURCES/httpd-2.4.3-apxs.patch b/SOURCES/httpd-2.4.3-apxs.patch deleted file mode 100644 index 7016dec..0000000 --- a/SOURCES/httpd-2.4.3-apxs.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git a/support/apxs.in b/support/apxs.in -index ad1287f..efcfcf6 100644 ---- a/support/apxs.in -+++ b/support/apxs.in -@@ -25,7 +25,18 @@ package apxs; - - my %config_vars = (); - --my $installbuilddir = "@exp_installbuilddir@"; -+# Awful hack to make apxs libdir-agnostic: -+my $pkg_config = "/usr/bin/pkg-config"; -+if (! -x "$pkg_config") { -+ error("$pkg_config not found!"); -+ exit(1); -+} -+ -+my $libdir = `pkg-config --variable=libdir apr-1`; -+chomp $libdir; -+ -+my $installbuilddir = $libdir . "/httpd/build"; -+ - get_config_vars("$installbuilddir/config_vars.mk",\%config_vars); - - # read the configuration variables once -@@ -275,7 +286,7 @@ if ($opt_g) { - $data =~ s|%NAME%|$name|sg; - $data =~ s|%TARGET%|$CFG_TARGET|sg; - $data =~ s|%PREFIX%|$prefix|sg; -- $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg; -+ $data =~ s|%LIBDIR%|$libdir|sg; - - my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); - -@@ -453,11 +464,11 @@ if ($opt_c) { - my $ldflags = "$CFG_LDFLAGS"; - if ($opt_p == 1) { - -- my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`; -+ my $apr_libs=`$apr_config --cflags --ldflags --link-libtool`; - chomp($apr_libs); - my $apu_libs=""; - if ($apr_major_version < 2) { -- $apu_libs=`$apu_config --ldflags --link-libtool --libs`; -+ $apu_libs=`$apu_config --ldflags --link-libtool`; - chomp($apu_libs); - } - -@@ -672,8 +683,8 @@ __DATA__ - - builddir=. - top_srcdir=%PREFIX% --top_builddir=%PREFIX% --include %INSTALLBUILDDIR%/special.mk -+top_builddir=%LIBDIR%/httpd -+include %LIBDIR%/httpd/build/special.mk - - # the used tools - APACHECTL=apachectl diff --git a/SOURCES/httpd-2.4.3-sslsninotreq.patch b/SOURCES/httpd-2.4.3-sslsninotreq.patch new file mode 100644 index 0000000..bdad486 --- /dev/null +++ b/SOURCES/httpd-2.4.3-sslsninotreq.patch @@ -0,0 +1,83 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 15993f1..53ed6f1 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -55,6 +55,7 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) + mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc)); + mc->pPool = pool; + mc->bFixed = FALSE; ++ mc->sni_required = FALSE; + + /* + * initialize per-module configuration +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index bf1f0e4..a7523de 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -409,7 +409,7 @@ + /* + * Configuration consistency checks + */ +- if ((rv = ssl_init_CheckServers(base_server, ptemp)) != APR_SUCCESS) { ++ if ((rv = ssl_init_CheckServers(mc, base_server, ptemp)) != APR_SUCCESS) { + return rv; + } + +@@ -1475,7 +1475,7 @@ + return APR_SUCCESS; + } + +-apr_status_t ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) ++apr_status_t ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *base_server, apr_pool_t *p) + { + server_rec *s; + SSLSrvConfigRec *sc; +@@ -1557,6 +1557,7 @@ + } + + if (conflict) { ++ mc->sni_required = TRUE; + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917) + "Init: Name-based SSL virtual hosts require " + "an OpenSSL version with support for TLS extensions " +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index bc9e26b..2460f01 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -164,6 +164,7 @@ + server_rec *handshakeserver = sslconn->server; + SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver); + ++ if (myModConfig(r->server)->sni_required) { + if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { + /* + * The SNI extension supplied a hostname. So don't accept requests +@@ -206,6 +207,7 @@ + "which is required to access this server.
\n"); + return HTTP_FORBIDDEN; + } ++ } + } + #endif + modssl_set_app_data2(ssl, r); +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index 75fc0e3..31dbfa9 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -554,6 +554,7 @@ typedef struct { + apr_global_mutex_t *stapling_cache_mutex; + apr_global_mutex_t *stapling_refresh_mutex; + #endif ++ BOOL sni_required; + } SSLModConfigRec; + + /** Structure representing configured filenames for certs and keys for +@@ -786,7 +787,7 @@ + apr_status_t ssl_init_Engine(server_rec *, apr_pool_t *); + apr_status_t ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *, + apr_array_header_t *); +-apr_status_t ssl_init_CheckServers(server_rec *, apr_pool_t *); ++apr_status_t ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *, apr_pool_t *); + STACK_OF(X509_NAME) + *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *); + void ssl_init_Child(apr_pool_t *, server_rec *); diff --git a/SOURCES/httpd-2.4.6-ap-ipv6.patch b/SOURCES/httpd-2.4.6-ap-ipv6.patch new file mode 100644 index 0000000..87e0c1f --- /dev/null +++ b/SOURCES/httpd-2.4.6-ap-ipv6.patch @@ -0,0 +1,139 @@ +diff --git a/support/ab.c b/support/ab.c +index f54c402..93c9066 100644 +--- a/support/ab.c ++++ b/support/ab.c +@@ -344,6 +344,7 @@ apr_time_t start, lasttime, stoptime; + char _request[8192]; + char *request = _request; + apr_size_t reqlen; ++int requests_initialized = 0; + + /* one global throw-away buffer to read stuff into */ + char buffer[8192]; +@@ -1253,12 +1254,18 @@ static void start_connect(struct connection * c) + else { + set_conn_state(c, STATE_UNCONNECTED); + apr_socket_close(c->aprsock); +- err_conn++; +- if (bad++ > 10) { ++ if (good == 0 && destsa->next) { ++ destsa = destsa->next; ++ err_conn = 0; ++ } ++ else if (bad++ > 10) { + fprintf(stderr, + "\nTest aborted after 10 failures\n\n"); + apr_err("apr_socket_connect()", rv); + } ++ else { ++ err_conn++; ++ } + + start_connect(c); + return; +@@ -1339,6 +1346,7 @@ static void read_connection(struct connection * c) + apr_status_t status; + char *part; + char respcode[4]; /* 3 digits and null */ ++ int i; + + r = sizeof(buffer); + #ifdef USE_SSL +@@ -1362,6 +1370,13 @@ static void read_connection(struct connection * c) + good++; + close_connection(c); + } ++ else if (scode == SSL_ERROR_SYSCALL ++ && c->read == 0 ++ && destsa->next ++ && c->state == STATE_CONNECTING ++ && good == 0) { ++ return; ++ } + else if (scode != SSL_ERROR_WANT_WRITE + && scode != SSL_ERROR_WANT_READ) { + /* some fatal error: */ +@@ -1387,8 +1402,8 @@ static void read_connection(struct connection * c) + } + /* catch legitimate fatal apr_socket_recv errors */ + else if (status != APR_SUCCESS) { +- err_recv++; + if (recverrok) { ++ err_recv++; + bad++; + close_connection(c); + if (verbosity >= 1) { +@@ -1396,7 +1411,12 @@ static void read_connection(struct connection * c) + fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status); + } + return; +- } else { ++ } else if (destsa->next && c->state == STATE_CONNECTING ++ && c->read == 0 && good == 0) { ++ return; ++ } ++ else { ++ err_recv++; + apr_err("apr_socket_recv", status); + } + } +@@ -1523,6 +1543,16 @@ static void read_connection(struct connection * c) + } + c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; + totalbread += c->bread; ++ ++ /* We have received the header, so we know this destination socket ++ * address is working, so initialize all remaining requests. */ ++ if (!requests_initialized) { ++ for (i = 1; i < concurrency; i++) { ++ con[i].socknum = i; ++ start_connect(&con[i]); ++ } ++ requests_initialized = 1; ++ } + } + } + else { +@@ -1734,11 +1764,10 @@ static void test(void) + apr_signal(SIGINT, output_results); + #endif + +- /* initialise lots of requests */ +- for (i = 0; i < concurrency; i++) { +- con[i].socknum = i; +- start_connect(&con[i]); +- } ++ /* initialise first connection to determine destination socket address ++ * which should be used for next connections. */ ++ con[0].socknum = 0; ++ start_connect(&con[0]); + + do { + apr_int32_t n; +@@ -1786,14 +1815,20 @@ static void test(void) + if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP)) + read_connection(c); + if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) { +- bad++; +- err_except++; +- /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ +- if (c->state == STATE_CONNECTING) { +- read_connection(c); ++ if (destsa->next && c->state == STATE_CONNECTING && good == 0) { ++ destsa = destsa->next; ++ start_connect(c); + } + else { +- start_connect(c); ++ bad++; ++ err_except++; ++ /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ ++ if (c->state == STATE_CONNECTING) { ++ read_connection(c); ++ } ++ else { ++ start_connect(c); ++ } + } + continue; + } diff --git a/SOURCES/httpd-2.4.6-apachectl-httpd-env.patch b/SOURCES/httpd-2.4.6-apachectl-httpd-env.patch new file mode 100644 index 0000000..d0450c4 --- /dev/null +++ b/SOURCES/httpd-2.4.6-apachectl-httpd-env.patch @@ -0,0 +1,23 @@ +--- a/support/apachectl.in ++++ b/support/apachectl.in +@@ -93,9 +93,9 @@ function testconfig() { + # httpd is denied terminal access in SELinux, so run in the + # current context to get stdout from $HTTPD -t. + if test -x /usr/sbin/selinuxenabled && /usr/sbin/selinuxenabled; then +- runcon -- `id -Z` $HTTPD $OPTIONS -t ++ runcon -- `id -Z` $sbindir/httpd $OPTIONS -t + else +- $HTTPD $OPTIONS -t ++ $sbindir/httpd $OPTIONS -t + fi + ERROR=$? + } +@@ -134,7 +134,7 @@ fullstatus) + $LYNX $STATUSURL + ;; + *) +- $HTTPD $OPTIONS "$@" ++ $sbindir/httpd $OPTIONS "$@" + ERROR=$? + esac + diff --git a/SOURCES/httpd-2.4.6-apachectl-status.patch b/SOURCES/httpd-2.4.6-apachectl-status.patch new file mode 100644 index 0000000..0c23f01 --- /dev/null +++ b/SOURCES/httpd-2.4.6-apachectl-status.patch @@ -0,0 +1,16 @@ +diff --git a/support/apachectl.in b/support/apachectl.in +index 29c2a3e..5d53313 100644 +--- a/support/apachectl.in ++++ b/support/apachectl.in +@@ -116,7 +116,11 @@ configtest) + ;; + status) + checklynx ++ set -o pipefail + $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } ' ++ if [[ $? != 0 ]] ; then ++ ERROR=3 ++ fi + ;; + fullstatus) + checklynx diff --git a/SOURCES/httpd-2.4.6-bomb.patch b/SOURCES/httpd-2.4.6-bomb.patch new file mode 100644 index 0000000..42dbb93 --- /dev/null +++ b/SOURCES/httpd-2.4.6-bomb.patch @@ -0,0 +1,14 @@ +diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in +index 0e8b626..dd6f2c6 100644 +--- a/docs/conf/extra/httpd-autoindex.conf.in ++++ b/docs/conf/extra/httpd-autoindex.conf.in +@@ -53,7 +53,8 @@ AddIcon /icons/dvi.gif .dvi + AddIcon /icons/uuencoded.gif .uu + AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl + AddIcon /icons/tex.gif .tex +-AddIcon /icons/bomb.gif core. ++AddIcon /icons/bomb.gif /core ++AddIcon /icons/bomb.gif */core.* + + AddIcon /icons/back.gif .. + AddIcon /icons/hand.right.gif README diff --git a/SOURCES/httpd-2.4.6-r1332643+.patch b/SOURCES/httpd-2.4.6-r1332643+.patch index 508bc9d..fab9696 100644 --- a/SOURCES/httpd-2.4.6-r1332643+.patch +++ b/SOURCES/httpd-2.4.6-r1332643+.patch @@ -1,14 +1,21 @@ # ./pullrev.sh 1332643 1345599 1487772 - + https://bugzilla.redhat.com//show_bug.cgi?id=809599 +Backport of (deprecated) NPN support from upstream, with +added support for Protocols in the same way as ALPN is +supported. + +Upstream commits: + http://svn.apache.org/viewvc?view=revision&revision=1332643 http://svn.apache.org/viewvc?view=revision&revision=1345599 http://svn.apache.org/viewvc?view=revision&revision=1487772 ---- httpd-2.4.6/modules/ssl/mod_ssl.c.r1332643+ -+++ httpd-2.4.6/modules/ssl/mod_ssl.c -@@ -413,6 +413,37 @@ int ssl_engine_disable(conn_rec *c) +diff -uap httpd-2.4.18/modules/ssl/mod_ssl.c.r1332643+ httpd-2.4.18/modules/ssl/mod_ssl.c +--- httpd-2.4.18/modules/ssl/mod_ssl.c.r1332643+ ++++ httpd-2.4.18/modules/ssl/mod_ssl.c +@@ -439,6 +439,13 @@ int ssl_engine_disable(conn_rec *c) return 1; } @@ -16,37 +23,13 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + ssl_npn_advertise_protos advertisefn, + ssl_npn_proto_negotiated negotiatedfn) +{ -+#ifdef HAVE_TLS_NPN -+ SSLConnRec *sslconn = myConnConfig(c); -+ -+ if (!sslconn) { -+ return DECLINED; -+ } -+ -+ if (!sslconn->npn_advertfns) { -+ sslconn->npn_advertfns = -+ apr_array_make(c->pool, 5, sizeof(ssl_npn_advertise_protos)); -+ sslconn->npn_negofns = -+ apr_array_make(c->pool, 5, sizeof(ssl_npn_proto_negotiated)); -+ } -+ -+ if (advertisefn) -+ APR_ARRAY_PUSH(sslconn->npn_advertfns, ssl_npn_advertise_protos) = -+ advertisefn; -+ if (negotiatedfn) -+ APR_ARRAY_PUSH(sslconn->npn_negofns, ssl_npn_proto_negotiated) = -+ negotiatedfn; -+ -+ return OK; -+#else + return DECLINED; -+#endif +} + int ssl_init_ssl_connection(conn_rec *c, request_rec *r) { SSLSrvConfigRec *sc; -@@ -584,6 +615,7 @@ static void ssl_register_hooks(apr_pool_ +@@ -624,6 +631,7 @@ static void ssl_register_hooks(apr_pool_ APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); @@ -54,8 +37,9 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl", AUTHZ_PROVIDER_VERSION, ---- httpd-2.4.6/modules/ssl/mod_ssl.h.r1332643+ -+++ httpd-2.4.6/modules/ssl/mod_ssl.h +diff -uap httpd-2.4.18/modules/ssl/mod_ssl.h.r1332643+ httpd-2.4.18/modules/ssl/mod_ssl.h +--- httpd-2.4.18/modules/ssl/mod_ssl.h.r1332643+ ++++ httpd-2.4.18/modules/ssl/mod_ssl.h @@ -63,5 +63,40 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_e APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); @@ -97,12 +81,13 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + #endif /* __MOD_SSL_H__ */ /** @} */ ---- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1332643+ -+++ httpd-2.4.6/modules/ssl/ssl_engine_init.c -@@ -725,6 +725,11 @@ static void ssl_init_ctx_callbacks(serve - SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); - - SSL_CTX_set_info_callback(ctx, ssl_callback_Info); +diff -uap httpd-2.4.18/modules/ssl/ssl_engine_init.c.r1332643+ httpd-2.4.18/modules/ssl/ssl_engine_init.c +--- httpd-2.4.18/modules/ssl/ssl_engine_init.c.r1332643+ ++++ httpd-2.4.18/modules/ssl/ssl_engine_init.c +@@ -636,6 +636,11 @@ static void ssl_init_ctx_callbacks(serve + #ifdef HAVE_TLS_ALPN + SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL); + #endif + +#ifdef HAVE_TLS_NPN + SSL_CTX_set_next_protos_advertised_cb( @@ -111,9 +96,10 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 } static apr_status_t ssl_init_ctx_verify(server_rec *s, ---- httpd-2.4.6/modules/ssl/ssl_engine_io.c.r1332643+ -+++ httpd-2.4.6/modules/ssl/ssl_engine_io.c -@@ -297,6 +297,7 @@ typedef struct { +diff -uap httpd-2.4.18/modules/ssl/ssl_engine_io.c.r1332643+ httpd-2.4.18/modules/ssl/ssl_engine_io.c +--- httpd-2.4.18/modules/ssl/ssl_engine_io.c.r1332643+ ++++ httpd-2.4.18/modules/ssl/ssl_engine_io.c +@@ -319,6 +319,7 @@ typedef struct { apr_pool_t *pool; char buffer[AP_IOBUFSIZE]; ssl_filter_ctx_t *filter_ctx; @@ -121,8 +107,8 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 } bio_filter_in_ctx_t; /* -@@ -1400,6 +1401,37 @@ static apr_status_t ssl_io_filter_input( - APR_BRIGADE_INSERT_TAIL(bb, bucket); +@@ -1377,6 +1378,38 @@ static apr_status_t ssl_io_filter_input( + return ssl_io_filter_error(f, bb, status, is_init); } +#ifdef HAVE_TLS_NPN @@ -132,34 +118,35 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + * npn_proto_negotiated_hook. */ + if (!inctx->npn_finished) { + SSLConnRec *sslconn = myConnConfig(f->c); ++ apr_array_header_t *protos = apr_array_make(f->c->pool, 1, sizeof(char *)); + const unsigned char *next_proto = NULL; + unsigned next_proto_len = 0; -+ int n; -+ -+ if (sslconn->npn_negofns) { -+ SSL_get0_next_proto_negotiated( -+ inctx->ssl, &next_proto, &next_proto_len); -+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c, -+ APLOGNO(02306) "SSL NPN negotiated protocol: '%*s'", ++ const unsigned char *out; ++ unsigned char outlen; ++ ++ SSL_get0_next_proto_negotiated(inctx->ssl, &next_proto, &next_proto_len); ++ if (next_proto_len) { ++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c, ++ APLOGNO(02306) "SSL NPN negotiated protocol: '%.*s'", + next_proto_len, (const char*)next_proto); ++ ++ APR_ARRAY_PUSH(protos, char *) = ++ apr_pstrmemdup(f->c->pool, (const char *)next_proto, next_proto_len); + -+ for (n = 0; n < sslconn->npn_negofns->nelts; n++) { -+ ssl_npn_proto_negotiated fn = -+ APR_ARRAY_IDX(sslconn->npn_negofns, n, ssl_npn_proto_negotiated); -+ -+ if (fn(f->c, (const char *)next_proto, next_proto_len) == DONE) -+ break; -+ } ++ if (modssl_select_protocol(inctx->ssl, f->c, sslconn, protos, ++ &out, &outlen) != SSL_TLSEXT_ERR_OK) ++ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, ++ "SSL NPN negotiation failed"); + } + + inctx->npn_finished = 1; + } +#endif + - return APR_SUCCESS; - } - -@@ -1881,6 +1913,7 @@ static void ssl_io_input_add_filter(ssl_ + if (is_init) { + /* protocol module needs to handshake before sending + * data to client (e.g. NNTP or FTP) +@@ -1899,6 +1932,7 @@ static void ssl_io_input_add_filter(ssl_ inctx->block = APR_BLOCK_READ; inctx->pool = c->pool; inctx->filter_ctx = filter_ctx; @@ -167,12 +154,62 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 } /* The request_rec pointer is passed in here only to ensure that the ---- httpd-2.4.6/modules/ssl/ssl_engine_kernel.c.r1332643+ -+++ httpd-2.4.6/modules/ssl/ssl_engine_kernel.c -@@ -2161,6 +2161,97 @@ int ssl_callback_SessionTicket(SSL *ssl, +diff -uap httpd-2.4.18/modules/ssl/ssl_engine_kernel.c.r1332643+ httpd-2.4.18/modules/ssl/ssl_engine_kernel.c +--- httpd-2.4.18/modules/ssl/ssl_engine_kernel.c.r1332643+ ++++ httpd-2.4.18/modules/ssl/ssl_engine_kernel.c +@@ -2297,6 +2297,142 @@ int ssl_callback_SessionTicket(SSL *ssl, } #endif /* HAVE_TLS_SESSION_TICKETS */ ++#if defined(HAVE_TLS_NPN) || defined(HAVE_TLS_ALPN) ++int modssl_select_protocol(SSL *ssl, conn_rec *c, SSLConnRec *sslconn, ++ apr_array_header_t *client_protos, ++ const unsigned char **out, unsigned char *outlen) ++{ ++ const char *proposed; ++ size_t len; ++ ++ /* The order the callbacks are invoked from TLS extensions is, unfortunately ++ * not defined and older openssl versions do call ALPN selection before ++ * they callback the SNI. We need to make sure that we know which vhost ++ * we are dealing with so we respect the correct protocols. ++ */ ++ init_vhost(c, ssl); ++ ++ proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos); ++ if (!proposed) { ++ proposed = ap_get_protocol(c); ++ } ++ ++ len = strlen(proposed); ++ if (len > 255) { ++ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02840) ++ "ALPN negotiated protocol name too long"); ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ } ++ *out = (const unsigned char *)proposed; ++ *outlen = (unsigned char)len; ++ ++ ap_log_cerror(APLOG_MARK, APLOG_TRACE8, 0, c, ++ "protocol switching from '%s' to '%s'", ++ ap_get_protocol(c), proposed); ++ ++ if (strcmp(proposed, ap_get_protocol(c))) { ++ apr_status_t status; ++ ++ status = ap_switch_protocol(c, NULL, sslconn->server, proposed); ++ if (status != APR_SUCCESS) { ++ ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c, ++ APLOGNO(02908) "protocol switch to '%s' failed", ++ proposed); ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ } ++ } ++ ++ return SSL_TLSEXT_ERR_OK; ++} ++#endif /* defined(HAVE_TLS_NPN) || defined(HAVE_TLS_ALPN) */ ++ +#ifdef HAVE_TLS_NPN +/* + * This callback function is executed when SSL needs to decide what protocols @@ -186,7 +223,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 +{ + conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); + SSLConnRec *sslconn = myConnConfig(c); -+ apr_array_header_t *protos; ++ const apr_array_header_t *protos; + int num_protos; + unsigned int size; + int i; @@ -196,23 +233,17 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + *data_out = NULL; + *size_out = 0; + -+ /* If the connection object is not available, or there are no NPN -+ * hooks registered, then there's nothing for us to do. */ -+ if (c == NULL || sslconn->npn_advertfns == NULL) { -+ return SSL_TLSEXT_ERR_OK; ++ /* If the connection object is not available, or there are no ++ upgrades available, do nothing. */ ++ if (!c || ap_get_protocol_upgrades(c, NULL, sslconn->server, 0, &protos)) { ++ return SSL_TLSEXT_ERR_NOACK; + } + -+ /* Invoke our npn_advertise_protos hook, giving other modules a chance to -+ * add alternate protocol names to advertise. */ -+ protos = apr_array_make(c->pool, 0, sizeof(char *)); -+ for (i = 0; i < sslconn->npn_advertfns->nelts; i++) { -+ ssl_npn_advertise_protos fn = -+ APR_ARRAY_IDX(sslconn->npn_advertfns, i, ssl_npn_advertise_protos); -+ -+ if (fn(c, protos) == DONE) -+ break; ++ num_protos = protos ? protos->nelts : 0; ++ ++ if (num_protos == 0) { ++ return SSL_TLSEXT_ERR_NOACK; + } -+ num_protos = protos->nelts; + + /* We now have a list of null-terminated strings; we need to concatenate + * them together into a single string, where each protocol name is prefixed @@ -254,6 +285,8 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + ++start; + memcpy(start, string, length * sizeof(unsigned char)); + start += length; ++ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, ++ "SSL NPN protocol advertising: %s", string); + } + + /* Success. */ @@ -264,11 +297,63 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + +#endif /* HAVE_TLS_NPN */ + - #ifdef HAVE_SRP + #ifdef HAVE_TLS_ALPN - int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg) ---- httpd-2.4.6/modules/ssl/ssl_private.h.r1332643+ -+++ httpd-2.4.6/modules/ssl/ssl_private.h + /* +@@ -2319,8 +2455,6 @@ int ssl_callback_alpn_select(SSL *ssl, + conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); + SSLConnRec *sslconn = myConnConfig(c); + apr_array_header_t *client_protos; +- const char *proposed; +- size_t len; + int i; + + /* If the connection object is not available, +@@ -2350,40 +2484,7 @@ int ssl_callback_alpn_select(SSL *ssl, + i += plen; + } + +- /* The order the callbacks are invoked from TLS extensions is, unfortunately +- * not defined and older openssl versions do call ALPN selection before +- * they callback the SNI. We need to make sure that we know which vhost +- * we are dealing with so we respect the correct protocols. +- */ +- init_vhost(c, ssl); +- +- proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos); +- if (!proposed) { +- proposed = ap_get_protocol(c); +- } +- +- len = strlen(proposed); +- if (len > 255) { +- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02840) +- "ALPN negotiated protocol name too long"); +- return SSL_TLSEXT_ERR_ALERT_FATAL; +- } +- *out = (const unsigned char *)proposed; +- *outlen = (unsigned char)len; +- +- if (strcmp(proposed, ap_get_protocol(c))) { +- apr_status_t status; +- +- status = ap_switch_protocol(c, NULL, sslconn->server, proposed); +- if (status != APR_SUCCESS) { +- ap_log_cerror(APLOG_MARK, APLOG_ERR, status, c, +- APLOGNO(02908) "protocol switch to '%s' failed", +- proposed); +- return SSL_TLSEXT_ERR_ALERT_FATAL; +- } +- } +- +- return SSL_TLSEXT_ERR_OK; ++ return modssl_select_protocol(ssl, c, sslconn, client_protos, out, outlen); + } + #endif /* HAVE_TLS_ALPN */ + +diff -uap httpd-2.4.18/modules/ssl/ssl_private.h.r1332643+ httpd-2.4.18/modules/ssl/ssl_private.h +--- httpd-2.4.18/modules/ssl/ssl_private.h.r1332643+ ++++ httpd-2.4.18/modules/ssl/ssl_private.h @@ -98,6 +98,8 @@ #include #include @@ -278,7 +363,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 /* Avoid tripping over an engine build installed globally and detected * when the user points at an explicit non-engine flavor of OpenSSL */ -@@ -139,6 +141,11 @@ +@@ -127,6 +129,11 @@ #define HAVE_FIPS #endif @@ -290,24 +375,14 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 #if defined(SSL_OP_NO_TLSv1_2) #define HAVE_TLSV1_X #endif -@@ -487,6 +494,12 @@ typedef struct { - * connection */ - } reneg_state; - -+#ifdef HAVE_TLS_NPN -+ /* Poor man's inter-module optional hooks for NPN. */ -+ apr_array_header_t *npn_advertfns; /* list of ssl_npn_advertise_protos callbacks */ -+ apr_array_header_t *npn_negofns; /* list of ssl_npn_proto_negotiated callbacks. */ -+#endif -+ - server_rec *server; - } SSLConnRec; - -@@ -842,6 +855,7 @@ int ssl_callback_ServerNameIndi +@@ -816,6 +823,10 @@ int ssl_callback_ServerNameIndi int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int); #endif +int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); ++int modssl_select_protocol(SSL *ssl, conn_rec *c, SSLConnRec *sslconn, ++ apr_array_header_t *client_protos, ++ const unsigned char **out, unsigned char *outlen); - /** Session Cache Support */ - apr_status_t ssl_scache_init(server_rec *, apr_pool_t *); + #ifdef HAVE_TLS_ALPN + int ssl_callback_alpn_select(SSL *ssl, const unsigned char **out, diff --git a/SOURCES/httpd-2.4.6-sslmultiproxy.patch b/SOURCES/httpd-2.4.6-sslmultiproxy.patch index f8a3b4b..02087ea 100644 --- a/SOURCES/httpd-2.4.6-sslmultiproxy.patch +++ b/SOURCES/httpd-2.4.6-sslmultiproxy.patch @@ -1,9 +1,8 @@ - -Ugly hack to enable mod_ssl and mod_nss to "share" hooks. - ---- httpd-2.4.6/modules/ssl/mod_ssl.c.sslmultiproxy -+++ httpd-2.4.6/modules/ssl/mod_ssl.c -@@ -369,6 +369,9 @@ static SSLConnRec *ssl_init_connection_c +diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c +index 0d7c906..be2ee9f 100644 +--- a/modules/ssl/mod_ssl.c ++++ b/modules/ssl/mod_ssl.c +@@ -395,6 +395,9 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c) return sslconn; } @@ -13,7 +12,7 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. int ssl_proxy_enable(conn_rec *c) { SSLSrvConfigRec *sc; -@@ -377,6 +380,12 @@ int ssl_proxy_enable(conn_rec *c) +@@ -403,6 +406,12 @@ int ssl_proxy_enable(conn_rec *c) sc = mySrvConfig(sslconn->server); if (!sc->proxy_enabled) { @@ -26,7 +25,7 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961) "SSL Proxy requested for %s but not enabled " "[Hint: SSLProxyEngine]", sc->vhost_id); -@@ -396,6 +405,10 @@ int ssl_engine_disable(conn_rec *c) +@@ -422,6 +431,10 @@ int ssl_engine_disable(conn_rec *c) SSLConnRec *sslconn = myConnConfig(c); @@ -37,7 +36,7 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. if (sslconn) { sc = mySrvConfig(sslconn->server); } -@@ -612,6 +625,9 @@ static void ssl_register_hooks(apr_pool_ +@@ -652,6 +665,9 @@ static void ssl_register_hooks(apr_pool_t *p) ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE); ssl_var_register(p); @@ -47,18 +46,25 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); ---- httpd-2.4.6/modules/ssl/ssl_engine_vars.c.sslmultiproxy -+++ httpd-2.4.6/modules/ssl/ssl_engine_vars.c -@@ -53,10 +53,15 @@ static void ssl_var_lookup_ssl_cipher_b +diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c +index a6b0d0d..5a415b9 100644 +--- a/modules/ssl/ssl_engine_vars.c ++++ b/modules/ssl/ssl_engine_vars.c +@@ -55,6 +55,10 @@ static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algk static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); +static APR_OPTIONAL_FN_TYPE(ssl_is_https) *othermod_is_https; +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *othermod_var_lookup; + - static int ssl_is_https(conn_rec *c) ++ + static SSLConnRec *ssl_get_effective_config(conn_rec *c) { SSLConnRec *sslconn = myConnConfig(c); +@@ -68,7 +72,9 @@ static SSLConnRec *ssl_get_effective_config(conn_rec *c) + static int ssl_is_https(conn_rec *c) + { + SSLConnRec *sslconn = ssl_get_effective_config(c); - return sslconn && sslconn->ssl; + + return (sslconn && sslconn->ssl) @@ -66,7 +72,7 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. } static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION; -@@ -106,6 +111,9 @@ void ssl_var_register(apr_pool_t *p) +@@ -137,6 +143,9 @@ void ssl_var_register(apr_pool_t *p) { char *cp, *cp2; @@ -76,10 +82,10 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. APR_REGISTER_OPTIONAL_FN(ssl_is_https); APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); APR_REGISTER_OPTIONAL_FN(ssl_ext_list); -@@ -241,6 +249,15 @@ char *ssl_var_lookup(apr_pool_t *p, serv +@@ -272,6 +281,15 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, */ if (result == NULL && c != NULL) { - SSLConnRec *sslconn = myConnConfig(c); + SSLConnRec *sslconn = ssl_get_effective_config(c); + + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4) + && (!sslconn || !sslconn->ssl) && othermod_var_lookup) { @@ -91,4 +97,4 @@ Ugly hack to enable mod_ssl and mod_nss to "share" hooks. + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4) && sslconn && sslconn->ssl) - result = ssl_var_lookup_ssl(p, c, r, var+4); + result = ssl_var_lookup_ssl(p, sslconn, r, var+4); diff --git a/SOURCES/httpd.init b/SOURCES/httpd.init index a322771..a971ab0 100755 --- a/SOURCES/httpd.init +++ b/SOURCES/httpd.init @@ -11,7 +11,7 @@ # pidfile: $localstatedir/run/httpd/httpd.pid # ### BEGIN INIT INFO -# Provides: httpd +# Provides: httpd24-httpd # Required-Start: $local_fs $remote_fs $network $named # Required-Stop: $local_fs $remote_fs $network # Should-Start: distcache @@ -34,19 +34,25 @@ HTTPD_LANG=${HTTPD_LANG-"C"} # mod_ssl needs a pass-phrase from the user. INITLOG_ARGS="" -# Set HTTPD=$sbindir/httpd.worker in /etc/sysconfig/httpd to use a server -# with the thread-based "worker" MPM; BE WARNED that some modules may not -# work correctly with a thread-based MPM; notably PHP will refuse to start. - # Path to the apachectl script, server binary, and short-form for messages. apachectl=$sbindir/apachectl -httpd=${HTTPD-$sbindir/httpd} +httpd=$sbindir/httpd prog=httpd pidfile=${PIDFILE-$localstatedir/run/httpd/httpd.pid} lockfile=${LOCKFILE-$localstatedir/lock/subsys/httpd} RETVAL=0 STOP_TIMEOUT=${STOP_TIMEOUT-10} +# We have to re-enable SCL environment, because /sbin/service +# clears almost all environment variables. +# Since X_SCLS is cleared as well, we lose information about other +# collections enabled. +. /opt/rh/httpd24/service-environment +for sclname in $HTTPD24_HTTPD_SCLS_ENABLED ; do + . /opt/rh/$sclname/enable + export X_SCLS="$X_SCLS $sclname" +done + # The semantics of these two functions differ from the way apachectl does # things -- attempting to start while running is a failure, and shutdown # when not running is also a failure. So we just do it the way init scripts @@ -97,7 +103,9 @@ case "$1" in stop ;; status) - status -p ${pidfile} $httpd + # `status' checks lockfile only in /var/lock/subsys by default. + # To workaround that, move outside that directory first. + status -p ${pidfile} -l ../../../${lockfile} $httpd RETVAL=$? ;; restart) @@ -105,7 +113,9 @@ case "$1" in start ;; condrestart|try-restart) - if status -p ${pidfile} $httpd >&/dev/null; then + # `status' checks lockfile only in /var/lock/subsys by default. + # To workaround that, move outside that directory first. + if status -p ${pidfile} -l ../../../${lockfile} $httpd >&/dev/null; then stop start fi diff --git a/SOURCES/manual.conf b/SOURCES/manual.conf index 45c9988..89fc690 100644 --- a/SOURCES/manual.conf +++ b/SOURCES/manual.conf @@ -2,10 +2,12 @@ # This configuration file allows the manual to be accessed at # http://localhost/manual/ # -AliasMatch ^/manual(?:/(?:de|en|fr|ja|ko|ru))?(/.*)?$ "/usr/share/httpd/manual$1" +Alias /manual $datadir/httpd/manual Options Indexes AllowOverride None Require all granted + + RedirectMatch 301 ^/manual/(?:da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn)(/.*)$ "/manual$1" diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 6e2f51d..29d4a63 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -1,7 +1,12 @@ %{?scl:%scl_package httpd} +%if 0%{?rhel} >= 7 %define use_systemd 1 %define use_system_apr 1 +%else +%define use_systemd 0 +%define use_system_apr 0 +%endif # If we are using system APR and building as collection, we have to set # apr prefix to _root_prefix @@ -43,8 +48,8 @@ Summary: Apache HTTP Server Name: %{?scl:%scl_prefix}httpd -Version: 2.4.12 -Release: 6%{?dist}.1 +Version: 2.4.18 +Release: 10%{?dist} URL: http://httpd.apache.org/ Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source1: index.html @@ -81,11 +86,12 @@ Source41: htcacheclean.sysconf Source42: htcacheclean.init # build/scripts patches Patch1: httpd-2.4.1-apctl.patch -Patch2: httpd-2.4.3-apxs.patch +Patch2: httpd-2.4.18-apxs.patch Patch3: httpd-2.4.1-deplibs.patch Patch5: httpd-2.4.3-layout.patch Patch6: httpd-2.4.3-apctl-systemd.patch Patch7: httpd-2.4.12-skiplist.patch +Patch8: httpd-2.4.3-mod_systemd.patch # Features/functional changes Patch21: httpd-2.4.6-full-release.patch Patch23: httpd-2.4.4-export.patch @@ -94,20 +100,24 @@ Patch25: httpd-2.4.1-selinux.patch Patch26: httpd-2.4.4-r1337344+.patch Patch27: httpd-2.4.2-icons.patch Patch28: httpd-2.4.6-r1332643+.patch -Patch29: httpd-2.4.3-mod_systemd.patch Patch30: httpd-2.4.4-cachehardmax.patch Patch31: httpd-2.4.6-sslmultiproxy.patch +Patch32: httpd-2.4.3-sslsninotreq.patch # Bug fixes Patch55: httpd-2.4.4-malformed-host.patch Patch56: httpd-2.4.4-mod_unique_id.patch Patch59: httpd-2.4.6-r1556473.patch +Patch62: httpd-2.4.6-apachectl-status.patch Patch63: httpd-2.4.6-ab-overflow.patch Patch64: httpd-2.4.6-sigint.patch -# Security fixed -Patch200: httpd-2.4.12-CVE-2015-0228.patch -Patch201: httpd-2.4.12-CVE-2015-0253.patch -Patch202: httpd-2.4.12-CVE-2015-3183.patch -Patch203: httpd-2.4.12-CVE-2015-3185.patch +Patch65: httpd-2.4.17-autoindex-revert.patch +Patch66: httpd-2.4.18-r1684636.patch +Patch67: httpd-2.4.18-documentroot.patch +Patch68: httpd-2.4.6-ap-ipv6.patch +Patch69: httpd-2.4.6-apachectl-httpd-env.patch +Patch70: httpd-2.4.6-bomb.patch +Patch71: httpd-2.4.18-apachectl-httpd-env2.patch +Patch72: httpd-2.4.18-r1738229.patch License: ASL 2.0 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -118,6 +128,7 @@ BuildRequires: apr-devel >= 1.4.0, apr-util-devel >= 1.2.0 %else BuildRequires: %{?scl:%scl_prefix}apr-devel >= 1.4.0, %{?scl:%scl_prefix}apr-util-devel >= 1.2.0 %endif +BuildRequires: %{?scl:%scl_prefix}libnghttp2-devel BuildRequires: pcre-devel >= 5.0 Requires: /etc/mime.types, system-logos >= 7.92.1-1 Provides: %{?scl:%scl_prefix}mod_dav = %{version}-%{release}, %{?scl:%scl_prefix}httpd-suexec = %{version}-%{release} @@ -132,6 +143,10 @@ Requires(post): systemd-units %else Requires(post): chkconfig %endif +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif %{?scl:Requires:%scl_runtime} %description @@ -148,6 +163,10 @@ Requires: %{?scl:%scl_prefix}apr-devel, %{?scl:%scl_prefix}apr-util-devel %endif Requires: pkgconfig Requires: %{?scl:%scl_prefix}httpd = %{version}-%{release} +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif %description devel The httpd-devel package contains the APXS binary and other files @@ -162,6 +181,10 @@ to install this package. Group: Documentation Summary: Documentation for the Apache HTTP server Requires: %{?scl:%scl_prefix}httpd = %{version}-%{release} +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif BuildArch: noarch %description manual @@ -172,6 +195,8 @@ also be found at http://httpd.apache.org/docs/2.2/. %package tools Group: System Environment/Daemons Summary: Tools for use with the Apache HTTP Server +Requires(post): policycoreutils +Requires(post): policycoreutils-python %description tools The httpd-tools package contains tools which can be used with @@ -185,6 +210,10 @@ BuildRequires: openssl-devel Requires(post): openssl, /bin/cat Requires(pre): %{?scl:%scl_prefix}httpd Requires: %{?scl:%scl_prefix}httpd = 0:%{version}-%{release}, %{?scl:%scl_prefix}httpd-mmn = %{mmnisa} +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif %description -n %{?scl:%scl_prefix}mod_ssl The mod_ssl module provides strong cryptography for the Apache Web @@ -196,6 +225,10 @@ Group: System Environment/Daemons Summary: HTML and XML content filters for the Apache HTTP Server Requires: %{?scl:%scl_prefix}httpd = 0:%{version}-%{release}, %{?scl:%scl_prefix}httpd-mmn = %{mmnisa} BuildRequires: libxml2-devel +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif Epoch: 1 %description -n %{?scl:%scl_prefix}mod_proxy_html @@ -211,6 +244,10 @@ Requires: apr-util-ldap %else Requires: %{?scl:%scl_prefix}apr-util-ldap %endif +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif %description -n %{?scl:%scl_prefix}mod_ldap The mod_ldap and mod_authnz_ldap modules add support for LDAP @@ -220,6 +257,10 @@ authentication to the Apache HTTP Server. Group: System Environment/Daemons Summary: Session interface for the Apache HTTP Server Requires: %{?scl:%scl_prefix}httpd = 0:%{version}-%{release}, %{?scl:%scl_prefix}httpd-mmn = %{mmnisa} +%if 0%{?rhel} < 7 +Requires(post): policycoreutils +Requires(post): policycoreutils-python +%endif %description -n %{?scl:%scl_prefix}mod_session The mod_session module and associated backends provide an abstract @@ -231,13 +272,17 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %endif %setup -q %{?scl:-n %{pkg_name}-%{version}} %patch1 -p1 -b .apctl -%if 0%{?scl:0} %patch2 -p1 -b .apxs -%endif %patch3 -p1 -b .deplibs %patch5 -p1 -b .layout +%if %{use_systemd} %patch6 -p1 -b .apctlsystemd %patch7 -p1 -b .skiplist +%patch8 -p1 -b .systemd +%else +%patch62 -p1 -b .apachectlstatus +%patch71 -p1 -b .envhttpd2 +%endif %patch21 -p1 -b .fullrelease %patch23 -p1 -b .export @@ -246,20 +291,22 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %patch26 -p1 -b .r1337344+ %patch27 -p1 -b .icons %patch28 -p1 -b .r1332643+ -%patch29 -p1 -b .systemd %patch30 -p1 -b .cachehardmax %patch31 -p1 -b .sslmultiproxy +%patch32 -p1 -b .sslsninotreq %patch55 -p1 -b .malformedhost %patch56 -p1 -b .uniqueid %patch59 -p1 -b .r1556473 %patch63 -p1 -b .aboverflow %patch64 -p1 -b .sigint - -%patch200 -p1 -b .cve0228 -%patch201 -p1 -b .cve0253 -%patch202 -p1 -b .cve3183 -%patch203 -p1 -b .cve3185 +%patch65 -p1 -b .autoindexrevert +%patch66 -p1 -b .r1684636 +%patch67 -p1 -b .documentroot +%patch68 -p1 -b .ipv6 +%patch69 -p1 -b .envhttpd +%patch70 -p1 -b .bomb +%patch72 -p1 -b .r1738229 # Patch in the vendor string and the release string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -312,11 +359,17 @@ export LYNX_PATH=/usr/bin/links --enable-mpms-shared=all \ --with-apr=%{apr_prefix} --with-apr-util=%{apr_prefix} \ --enable-suexec --with-suexec \ +%if 0%{?rhel} >= 7 --enable-suexec-capabilities \ +%endif --with-suexec-caller=%{suexec_caller} \ --with-suexec-docroot=%{docroot} \ +%if 0%{?rhel} >= 7 --without-suexec-logfile \ --with-suexec-syslog \ +%else + --with-suexec-logfile=%{_root_localstatedir}/log/httpd/suexec.log \ +%endif --with-suexec-bin=%{_sbindir}/suexec \ --with-suexec-uidmin=500 --with-suexec-gidmin=100 \ --enable-pie \ @@ -404,7 +457,10 @@ install -m 644 $RPM_SOURCE_DIR/README.confd \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/README for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \ 00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \ - 01-ldap.conf 01-session.conf 00-systemd.conf 00-optional.conf; do +%if %{use_systemd} + 00-systemd.conf \ +%endif + 01-ldap.conf 01-session.conf 00-optional.conf; do install -m 644 -p $RPM_SOURCE_DIR/$f \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f done @@ -418,6 +474,8 @@ for f in welcome.conf ssl.conf manual.conf userdir.conf; do $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/$f sed -i 's|\$datadir|%{_datadir}|' \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/$f + touch -r $RPM_SOURCE_DIR/$f \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/$f done # Split-out extra config shipped as default in conf.d: @@ -446,6 +504,11 @@ for s in httpd htcacheclean; do $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/${s} done +%if 0%{?rhel} < 7 +sed -i 's|LANG|HTTPD_LANG|' \ + $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/httpd +%endif + # tmpfiles.d configuration %if 0%{?rhel} >= 7 && ! %{?scl:1}0 mkdir $RPM_BUILD_ROOT/etc/tmpfiles.d @@ -467,7 +530,7 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd \ # Make the MMN accessible to module packages echo %{mmnisa} > $RPM_BUILD_ROOT%{_includedir}/httpd/.mmn -# When building as SCL, use different pref%{?scl:Requires:%scl_runtime}ix for macros +# When building as SCL, use different prefix for macros %if %{?scl}0 mkdir -p $RPM_BUILD_ROOT%{_root_sysconfdir}/rpm/ cat > $RPM_BUILD_ROOT%{_root_sysconfdir}/rpm/macros.httpd24 < /dev/null || : %post +%if 0%{?rhel} < 7 +restorecon -R %{_scl_root} >/dev/null 2>&1 || : +%endif + %if %{use_systemd} %systemd_post %{httpd_service} %{htcacheclean_service} + +semanage fcontext -a -t httpd_exec_t "%{_root_sbindir}/httpd-scl-wrapper" +restorecon -R %{_scl_root} >/dev/null 2>&1 || : %else # Register the httpd service /sbin/chkconfig --add %{?scl:%scl_prefix}httpd /sbin/chkconfig --add %{?scl:%scl_prefix}htcacheclean + +semanage fcontext -a -e /etc/rc.d/init.d/httpd /etc/rc.d/init.d/httpd24-httpd >/dev/null 2>&1 || : +restorecon -R /etc/rc.d/init.d/httpd24-httpd >/dev/null 2>&1 || : + +semanage fcontext -a -e /etc/rc.d/init.d/htcacheclean /etc/rc.d/init.d/httpd24-htcacheclean >/dev/null 2>&1 || : +restorecon -R /etc/rc.d/init.d/httpd24-htcacheclean >/dev/null 2>&1 || : %endif + semanage fcontext -a -e /var/log/httpd %{httpd_logdir} >/dev/null 2>&1 || : restorecon -R %{httpd_logdir} >/dev/null 2>&1 || : -semanage fcontext -a -t httpd_exec_t "%{_root_sbindir}/httpd-scl-wrapper" -restorecon -R %{_scl_root} >/dev/null 2>&1 || : - %preun %if %{use_systemd} %systemd_preun %{httpd_service} %{htcacheclean_service} @@ -630,12 +710,20 @@ fi %if %{use_systemd} test -f %{_sysconfdir}/sysconfig/httpd-disable-posttrans || \ /bin/systemctl try-restart %{httpd_service} %{htcacheclean_service} >/dev/null 2>&1 || : +%else +test -f %{_sysconfdir}/sysconfig/httpd-disable-posttrans || \ + /sbin/service %{?scl:%scl_prefix}httpd condrestart >/dev/null 2>&1 || : +test -f %{_sysconfdir}/sysconfig/httpd-disable-posttrans || \ + /sbin/service %{?scl:%scl_prefix}htcacheclean condrestart >/dev/null 2>&1 || : %endif %define sslcert %{_root_sysconfdir}/pki/tls/certs/localhost.crt %define sslkey %{_root_sysconfdir}/pki/tls/private/localhost.key %post -n %{?scl:%scl_prefix}mod_ssl +%if 0%{?rhel} < 7 +restorecon -R %{_scl_root} >/dev/null 2>&1 || : +%endif umask 077 if [ -f %{sslkey} -o -f %{sslcert} ]; then @@ -661,12 +749,40 @@ ${FQDN} root@${FQDN} EOF +%if 0%{?rhel} < 7 +%post tools +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + +%post manual +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + +%post -n %{?scl:%scl_prefix}mod_proxy_html +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + +%post -n %{?scl:%scl_prefix}mod_ldap +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + +%post -n %{?scl:%scl_prefix}mod_session +restorecon -R %{_scl_root} >/dev/null 2>&1 || : + +%post devel +restorecon -R %{_scl_root} >/dev/null 2>&1 || : +%endif + %check # Check the built modules are all PIC if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then : modules contain non-relocatable code exit 1 fi +# Ensure every mod_* that's built is loaded. +for f in $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so; do + m=${f##*/} + if ! grep -q $m $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.conf; then + echo ERROR: Module $m not configured. Disable it, or load it. + exit 1 + fi +done %clean rm -rf $RPM_BUILD_ROOT @@ -711,12 +827,21 @@ rm -rf $RPM_BUILD_ROOT %{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/* %endif +%if %{use_systemd} +%dir %{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd +%{_root_libexecdir}/initscripts/legacy-actions/%{?scl:%scl_prefix}httpd/* +%endif + %{_sbindir}/ht* %{_sbindir}/fcgistarter %{_sbindir}/apachectl %{_sbindir}/rotatelogs +%if 0%{?rhel} >= 7 %{_sbindir}/httpd-scl-wrapper %caps(cap_setuid,cap_setgid+pe) %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec +%else +%attr(4510,root,%{suexec_caller}) %{_sbindir}/suexec +%endif %dir %{_libdir}/httpd %dir %{_libdir}/httpd/modules @@ -812,7 +937,55 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog -* Tue Aug 11 2015 Jan Kaluza - 2.4.12-6.1 +* Fri Apr 15 2016 Joe Orton - 2.4.18-10 +- load more built modules (including mod_http2) by default (#1302653) +- lower log-level for mod_ssl NPN debugging (#1302653) + +* Thu Apr 14 2016 Joe Orton - 2.4.18-9 +- mod_ssl: restore NPN behaviour with no Protocol configured (#1302653) + +* Tue Apr 12 2016 Joe Orton - 2.4.18-8 +- mod_ssl: allow protocol upgrades via NPN (#1302653) + +* Fri Apr 8 2016 Joe Orton - 2.4.18-7 +- mod_lua: use anonymous shm segment (#1225116) +- revert 'apachectl graceful' to start httpd if stopped (#1221702) + +* Wed Apr 6 2016 Joe Orton - 2.4.18-6 +- fix apxs generated Makefile path to build directory (#1319837) +- use redirects for lang-specific /manual/ URLs (#1324406) + +* Wed Mar 30 2016 Jan Kaluza - 2.4.18-5 +- apachectl: use httpd from the SCL in apachectl (#1319780) +- apachectl: ignore HTTPD variable also on RHEL6 (#1221681) + +* Tue Feb 23 2016 Jan Kaluza - 2.4.18-4 +- apxs: fix querying installbuilddir + +* Thu Feb 11 2016 Jan Kaluza - 2.4.18-3 +- correct the AliasMatch in manual.conf (#1282481) + +* Wed Feb 10 2016 Jan Kaluza - 2.4.18-2 +- use HTTPD_LANG in sysconfig file on RHEL6 (#1222055) +- ignore HTTPD sysconfig variable on RHEL6 (#1204075) +- call restorecon on /etc/rc.d/init.d/htcacheclean after install (#1222494) + +* Wed Feb 03 2016 Jan Kaluza - 2.4.18-1 +- update to version 2.4.18 +- add support for http/2 +- mod_auth_digest: use anonymous shared memory (#1225116) +- core: improve error message for inaccessible DocumentRoot (#1207093) +- ab: try all addresses instead of failing on first one when not available (#1209552) +- apachectl: ignore HTTPD variable from sysconfig (#1221681) +- apachectl: fix "graceful" documentation (#1221702) +- apachectl: fix "graceful" behaviour when httpd is not running (#1221650) +- do not display "bomb" icon for files ending with "core" (#1196553) +- mod_proxy_wstunnel: load this module by default (#1253396) + +* Tue Dec 15 2015 Jan Kaluza - 2.4.12-8 +- Add httpd-2.4.3-sslsninotreq.patch as we did in rhscl-2.0 (#1249800) + +* Tue Aug 11 2015 Jan Kaluza - 2.4.12-7 - core: fix chunk header parsing defect (CVE-2015-3183) - core: replace of ap_some_auth_required with ap_some_authn_required and ap_force_authn hook (CVE-2015-3185)