diff --git a/.gitignore b/.gitignore index 260a2d6..9969f1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ SOURCES/httpd-2.4.6.tar.bz2 -SOURCES/centos-noindex.tar.gz diff --git a/.httpd.metadata b/.httpd.metadata index 17ede1b..d335a99 100644 --- a/.httpd.metadata +++ b/.httpd.metadata @@ -1,2 +1 @@ 16d8ec72535ded65d035122b0d944b0e64eaa2a2 SOURCES/httpd-2.4.6.tar.bz2 -6ce5ab3c765b9efeceb2e636e32373bc6e6ed489 SOURCES/centos-noindex.tar.gz diff --git a/SOURCES/httpd-2.4.6-CVE-2013-5704.patch b/SOURCES/httpd-2.4.6-CVE-2013-5704.patch new file mode 100644 index 0000000..ee42b25 --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2013-5704.patch @@ -0,0 +1,381 @@ +diff --git a/include/http_core.h b/include/http_core.h +index 3c47989..f6f4aa2 100644 +--- a/include/http_core.h ++++ b/include/http_core.h +@@ -663,6 +663,10 @@ typedef struct { + #define AP_TRACE_ENABLE 1 + #define AP_TRACE_EXTENDED 2 + int trace_enable; ++#define AP_MERGE_TRAILERS_UNSET 0 ++#define AP_MERGE_TRAILERS_ENABLE 1 ++#define AP_MERGE_TRAILERS_DISABLE 2 ++ int merge_trailers; + + } core_server_config; + +diff --git a/include/httpd.h b/include/httpd.h +index 36cd58d..2e415f9 100644 +--- a/include/httpd.h ++++ b/include/httpd.h +@@ -1032,6 +1032,11 @@ struct request_rec { + */ + apr_sockaddr_t *useragent_addr; + char *useragent_ip; ++ ++ /** MIME trailer environment from the request */ ++ apr_table_t *trailers_in; ++ /** MIME trailer environment from the response */ ++ apr_table_t *trailers_out; + }; + + /** +diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c +index 24a939a..2ae8f46 100644 +--- a/modules/http/http_filters.c ++++ b/modules/http/http_filters.c +@@ -214,6 +214,49 @@ static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b, + } + + ++static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, ++ apr_bucket_brigade *b, int merge) ++{ ++ int rv; ++ apr_bucket *e; ++ request_rec *r = f->r; ++ apr_table_t *saved_headers_in = r->headers_in; ++ int saved_status = r->status; ++ ++ 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) { ++ r->status = saved_status; ++ e = apr_bucket_eos_create(f->c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(b, e); ++ ctx->eos_sent = 1; ++ rv = APR_SUCCESS; ++ } ++ else { ++ const char *error_notes = apr_table_get(r->notes, ++ "error-notes"); ++ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, ++ "Error while reading HTTP trailer: %i%s%s", ++ r->status, error_notes ? ": " : "", ++ error_notes ? error_notes : ""); ++ rv = APR_EINVAL; ++ } ++ ++ if(!merge) { ++ r->headers_in = saved_headers_in; ++ } ++ else { ++ r->headers_in = apr_table_overlay(r->pool, saved_headers_in, ++ r->trailers_in); ++ } ++ ++ return rv; ++} ++ + /* This is the HTTP_INPUT filter for HTTP requests and responses from + * proxied servers (mod_proxy). It handles chunked and content-length + * bodies. This can only be inserted/used after the headers +@@ -223,6 +266,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) + { ++ core_server_config *conf; + apr_bucket *e; + http_ctx_t *ctx = f->ctx; + apr_status_t rv; +@@ -230,6 +274,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; + apr_bucket_brigade *bb; + ++ conf = (core_server_config *) ++ ap_get_module_config(f->r->server->module_config, &core_module); ++ + /* just get out of the way of things we don't want. */ + if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) { + return ap_get_brigade(f->next, b, mode, block, readbytes); +@@ -403,13 +450,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + } + + if (!ctx->remaining) { +- /* Handle trailers by calling ap_get_mime_headers again! */ +- ctx->state = BODY_NONE; +- ap_get_mime_headers(f->r); +- e = apr_bucket_eos_create(f->c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(b, e); +- ctx->eos_sent = 1; +- return APR_SUCCESS; ++ return read_chunked_trailers(ctx, f, b, ++ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); + } + } + } +@@ -509,13 +551,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + } + + if (!ctx->remaining) { +- /* Handle trailers by calling ap_get_mime_headers again! */ +- ctx->state = BODY_NONE; +- ap_get_mime_headers(f->r); +- e = apr_bucket_eos_create(f->c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(b, e); +- ctx->eos_sent = 1; +- return APR_SUCCESS; ++ return read_chunked_trailers(ctx, f, b, ++ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); + } + } + break; +diff --git a/modules/http/http_request.c b/modules/http/http_request.c +index 796d506..cdfec8b 100644 +--- a/modules/http/http_request.c ++++ b/modules/http/http_request.c +@@ -463,6 +463,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, + new->main = r->main; + + new->headers_in = r->headers_in; ++ new->trailers_in = r->trailers_in; + new->headers_out = apr_table_make(r->pool, 12); + if (ap_is_HTTP_REDIRECT(new->status)) { + const char *location = apr_table_get(r->headers_out, "Location"); +@@ -470,6 +471,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, + apr_table_setn(new->headers_out, "Location", location); + } + new->err_headers_out = r->err_headers_out; ++ new->trailers_out = apr_table_make(r->pool, 5); + new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); + new->notes = apr_table_make(r->pool, 5); + +@@ -583,6 +585,8 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r) + r->headers_out); + r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, + r->err_headers_out); ++ r->trailers_out = apr_table_overlay(r->pool, rr->trailers_out, ++ r->trailers_out); + r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, + r->subprocess_env); + +diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c +index 25f5030..b021dd3 100644 +--- a/modules/loggers/mod_log_config.c ++++ b/modules/loggers/mod_log_config.c +@@ -431,6 +431,12 @@ static const char *log_header_in(request_rec *r, char *a) + return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a)); + } + ++static const char *log_trailer_in(request_rec *r, char *a) ++{ ++ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_in, a)); ++} ++ ++ + static APR_INLINE char *find_multiple_headers(apr_pool_t *pool, + const apr_table_t *table, + const char *key) +@@ -514,6 +520,11 @@ static const char *log_header_out(request_rec *r, char *a) + return ap_escape_logitem(r->pool, cp); + } + ++static const char *log_trailer_out(request_rec *r, char *a) ++{ ++ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a)); ++} ++ + static const char *log_note(request_rec *r, char *a) + { + return ap_escape_logitem(r->pool, apr_table_get(r->notes, a)); +@@ -916,7 +927,7 @@ static char *parse_log_misc_string(apr_pool_t *p, log_format_item *it, + static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) + { + const char *s = *sa; +- ap_log_handler *handler; ++ ap_log_handler *handler = NULL; + + if (*s != '%') { + return parse_log_misc_string(p, it, sa); +@@ -986,7 +997,16 @@ static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) + break; + + default: +- handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); ++ /* check for '^' + two character format first */ ++ if (*s == '^' && *(s+1) && *(s+2)) { ++ handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3); ++ if (handler) { ++ s += 3; ++ } ++ } ++ if (!handler) { ++ handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); ++ } + if (!handler) { + char dummy[2]; + +@@ -1516,7 +1536,7 @@ static void ap_register_log_handler(apr_pool_t *p, char *tag, + log_struct->func = handler; + log_struct->want_orig_default = def; + +- apr_hash_set(log_hash, tag, 1, (const void *)log_struct); ++ apr_hash_set(log_hash, tag, strlen(tag), (const void *)log_struct); + } + static ap_log_writer_init* ap_log_set_writer_init(ap_log_writer_init *handle) + { +@@ -1686,6 +1706,9 @@ static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) + log_pfn_register(p, "U", log_request_uri, 1); + log_pfn_register(p, "s", log_status, 1); + log_pfn_register(p, "R", log_handler, 1); ++ ++ log_pfn_register(p, "^ti", log_trailer_in, 0); ++ log_pfn_register(p, "^to", log_trailer_out, 0); + } + + /* reset to default conditions */ +diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c +index 7ae0fa4..05f33b4 100644 +--- a/modules/proxy/mod_proxy_http.c ++++ b/modules/proxy/mod_proxy_http.c +@@ -994,8 +994,11 @@ static request_rec *make_fake_req(conn_rec *c, request_rec *r) + rp->status = HTTP_OK; + + rp->headers_in = apr_table_make(pool, 50); ++ rp->trailers_in = apr_table_make(pool, 5); ++ + rp->subprocess_env = apr_table_make(pool, 50); + rp->headers_out = apr_table_make(pool, 12); ++ rp->trailers_out = apr_table_make(pool, 5); + rp->err_headers_out = apr_table_make(pool, 5); + rp->notes = apr_table_make(pool, 5); + +@@ -1076,6 +1079,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, + psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + + r->headers_out = apr_table_make(r->pool, 20); ++ r->trailers_out = apr_table_make(r->pool, 5); + *pread_len = 0; + + /* +@@ -1206,6 +1210,14 @@ apr_status_t ap_proxygetline(apr_bucket_brigade *bb, char *s, int n, request_rec + #define AP_MAX_INTERIM_RESPONSES 10 + #endif + ++static int add_trailers(void *data, const char *key, const char *val) ++{ ++ if (val) { ++ apr_table_add((apr_table_t*)data, key, val); ++ } ++ return 1; ++} ++ + static + apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, + proxy_conn_rec **backend_ptr, +@@ -1717,6 +1729,12 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, + /* next time try a non-blocking read */ + mode = APR_NONBLOCK_READ; + ++ if (!apr_is_empty_table(backend->r->trailers_in)) { ++ apr_table_do(add_trailers, r->trailers_out, ++ backend->r->trailers_in, NULL); ++ apr_table_clear(backend->r->trailers_in); ++ } ++ + apr_brigade_length(bb, 0, &readbytes); + backend->worker->s->read += readbytes; + #if DEBUGGING +diff --git a/server/core.c b/server/core.c +index 024bab6..7cfde63 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -523,6 +523,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) + if (virt->error_log_req) + conf->error_log_req = virt->error_log_req; + ++ conf->merge_trailers = (virt->merge_trailers != AP_MERGE_TRAILERS_UNSET) ++ ? virt->merge_trailers ++ : base->merge_trailers; ++ + return conf; + } + +@@ -3877,6 +3881,16 @@ AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag, + } + + ++static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg) ++{ ++ core_server_config *conf = ap_get_module_config(cmd->server->module_config, ++ &core_module); ++ conf->merge_trailers = (arg ? AP_MERGE_TRAILERS_ENABLE : ++ AP_MERGE_TRAILERS_DISABLE); ++ ++ return NULL; ++} ++ + /* Note --- ErrorDocument will now work from .htaccess files. + * The AllowOverride of Fileinfo allows webmasters to turn it off + */ +@@ -4124,6 +4138,8 @@ AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, + #endif + AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, + "'on' (default), 'off' or 'extended' to trace request body content"), ++AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF, ++ "merge request trailers into request headers or not"), + { NULL } + }; + +@@ -4206,7 +4222,6 @@ static int core_map_to_storage(request_rec *r) + + static int do_nothing(request_rec *r) { return OK; } + +- + static int core_override_type(request_rec *r) + { + core_dir_config *conf = +diff --git a/server/protocol.c b/server/protocol.c +index 14329eb..46fc034 100644 +--- a/server/protocol.c ++++ b/server/protocol.c +@@ -718,6 +718,8 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb + r->status = HTTP_REQUEST_TIME_OUT; + } + else { ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, ++ "Failed to read request header line %s", field); + r->status = HTTP_BAD_REQUEST; + } + +@@ -917,9 +919,11 @@ request_rec *ap_read_request(conn_rec *conn) + r->allowed_methods = ap_make_method_list(p, 2); + + r->headers_in = apr_table_make(r->pool, 25); ++ r->trailers_in = apr_table_make(r->pool, 5); + r->subprocess_env = apr_table_make(r->pool, 25); + r->headers_out = apr_table_make(r->pool, 12); + r->err_headers_out = apr_table_make(r->pool, 5); ++ r->trailers_out = apr_table_make(r->pool, 5); + r->notes = apr_table_make(r->pool, 5); + + r->request_config = ap_create_request_config(r->pool); +@@ -1162,6 +1166,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, + rnew->status = HTTP_OK; + + rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); ++ rnew->trailers_in = apr_table_copy(rnew->pool, r->trailers_in); + + /* did the original request have a body? (e.g. POST w/SSI tags) + * if so, make sure the subrequest doesn't inherit body headers +@@ -1173,6 +1178,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, + rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); + rnew->headers_out = apr_table_make(rnew->pool, 5); + rnew->err_headers_out = apr_table_make(rnew->pool, 5); ++ rnew->trailers_out = apr_table_make(rnew->pool, 5); + rnew->notes = apr_table_make(rnew->pool, 5); + + rnew->expecting_100 = r->expecting_100; diff --git a/SOURCES/httpd-2.4.6-CVE-2014-3581.patch b/SOURCES/httpd-2.4.6-CVE-2014-3581.patch new file mode 100644 index 0000000..2f2217d --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2014-3581.patch @@ -0,0 +1,17 @@ +diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c +index 7b7fb45..fbebb1e 100644 +--- a/modules/cache/cache_util.c ++++ b/modules/cache/cache_util.c +@@ -1251,8 +1251,10 @@ CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r) + + if (!apr_table_get(headers_out, "Content-Type") + && r->content_type) { +- apr_table_setn(headers_out, "Content-Type", +- ap_make_content_type(r, r->content_type)); ++ const char *ctype = ap_make_content_type(r, r->content_type); ++ if (ctype) { ++ apr_table_setn(headers_out, "Content-Type", ctype); ++ } + } + + if (!apr_table_get(headers_out, "Content-Encoding") diff --git a/SOURCES/httpd-2.4.6-ab-overflow.patch b/SOURCES/httpd-2.4.6-ab-overflow.patch new file mode 100644 index 0000000..91a76b2 --- /dev/null +++ b/SOURCES/httpd-2.4.6-ab-overflow.patch @@ -0,0 +1,20 @@ +--- a/support/ab.c 2014/08/14 12:12:38 1617912 ++++ b/support/ab.c 2014/08/14 12:15:31 1617913 +@@ -1029,7 +1029,7 @@ + ap_round_ms(stats[done - 1].time)); + else + printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], +- ap_round_ms(stats[(int) (done * percs[i] / 100)].time)); ++ ap_round_ms(stats[(unsigned long)done * percs[i] / 100].time)); + } + } + if (csvperc) { +@@ -1046,7 +1046,7 @@ + else if (i == 100) + t = ap_double_ms(stats[done - 1].time); + else +- t = ap_double_ms(stats[(int) (0.5 + done * i / 100.0)].time); ++ t = ap_double_ms(stats[(unsigned long) (0.5 + (double)done * i / 100.0)].time); + fprintf(out, "%d,%.3f\n", i, t); + } + fclose(out); diff --git a/SOURCES/httpd-2.4.6-pre_htaccess.patch b/SOURCES/httpd-2.4.6-pre_htaccess.patch new file mode 100644 index 0000000..ff7bd5a --- /dev/null +++ b/SOURCES/httpd-2.4.6-pre_htaccess.patch @@ -0,0 +1,140 @@ +diff --git a/include/ap_mmn.h b/include/ap_mmn.h +index 89c4140..82a0acb 100644 +--- a/include/ap_mmn.h ++++ b/include/ap_mmn.h +@@ -418,6 +418,7 @@ + * ap_proxy_pass_brigade() + * 20120211.22 (2.4.5-dev) No longer prevent usage of strtoul() + * 20120211.23 (2.4.5-dev) Add ap_proxy_clear_connection() ++ * 20120211.24 (2.4.7-dev) add open_htaccess hook. + */ + + #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ +@@ -425,7 +426,7 @@ + #ifndef MODULE_MAGIC_NUMBER_MAJOR + #define MODULE_MAGIC_NUMBER_MAJOR 20120211 + #endif +-#define MODULE_MAGIC_NUMBER_MINOR 23 /* 0...n */ ++#define MODULE_MAGIC_NUMBER_MINOR 24 /* 0...n */ + + /** + * Determine if the server's current MODULE_MAGIC_NUMBER is at least a +diff --git a/include/http_config.h b/include/http_config.h +index 7ee3760..c93c3b2 100644 +--- a/include/http_config.h ++++ b/include/http_config.h +@@ -1322,6 +1322,31 @@ AP_DECLARE_HOOK(int,quick_handler,(request_rec *r, int lookup_uri)) + AP_DECLARE_HOOK(void,optional_fn_retrieve,(void)) + + /** ++ * Allow modules to open htaccess files or perform operations before doing so ++ * @param r The current request ++ * @param dir_name The directory for which the htaccess file should be opened ++ * @param access_name The filename for which the htaccess file should be opened ++ * @param conffile Where the pointer to the opened ap_configfile_t must be ++ * stored ++ * @param full_name Where the full file name of the htaccess file must be ++ * stored. ++ * @return APR_SUCCESS on success, ++ * APR_ENOENT or APR_ENOTDIR if no htaccess file exists, ++ * AP_DECLINED to let later modules do the opening, ++ * any other error code on error. ++ */ ++AP_DECLARE_HOOK(apr_status_t,open_htaccess, ++ (request_rec *r, const char *dir_name, const char *access_name, ++ ap_configfile_t **conffile, const char **full_name)) ++ ++/** ++ * Core internal function, use ap_run_open_htaccess() instead. ++ */ ++apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name, ++ const char *access_name, ap_configfile_t **conffile, ++ const char **full_name); ++ ++/** + * A generic pool cleanup that will reset a pointer to NULL. For use with + * apr_pool_cleanup_register. + * @param data The address of the pointer +diff --git a/server/config.c b/server/config.c +index c1aae17..265744e 100644 +--- a/server/config.c ++++ b/server/config.c +@@ -80,6 +80,7 @@ APR_HOOK_STRUCT( + APR_HOOK_LINK(quick_handler) + APR_HOOK_LINK(optional_fn_retrieve) + APR_HOOK_LINK(test_config) ++ APR_HOOK_LINK(open_htaccess) + ) + + AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser, +@@ -171,6 +172,12 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r), + AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup), + (r, lookup), DECLINED) + ++AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, open_htaccess, ++ (request_rec *r, const char *dir_name, const char *access_name, ++ ap_configfile_t **conffile, const char **full_name), ++ (r, dir_name, access_name, conffile, full_name), ++ AP_DECLINED) ++ + /* hooks with no args are implemented last, after disabling APR hook probes */ + #if defined(APR_HOOK_PROBES_ENABLED) + #undef APR_HOOK_PROBES_ENABLED +@@ -2073,14 +2080,23 @@ AP_DECLARE(int) ap_process_config_tree(server_rec *s, + return OK; + } + ++apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name, ++ const char *access_name, ++ ap_configfile_t **conffile, ++ const char **full_name) ++{ ++ *full_name = ap_make_full_path(r->pool, dir_name, access_name); ++ return ap_pcfg_openfile(conffile, r->pool, *full_name); ++} ++ + AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, + request_rec *r, int override, + int override_opts, apr_table_t *override_list, +- const char *d, const char *access_name) ++ const char *d, const char *access_names) + { + ap_configfile_t *f = NULL; + cmd_parms parms; +- char *filename = NULL; ++ const char *filename; + const struct htaccess_result *cache; + struct htaccess_result *new; + ap_conf_vector_t *dc = NULL; +@@ -2104,15 +2120,11 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, + parms.path = apr_pstrdup(r->pool, d); + + /* loop through the access names and find the first one */ +- while (access_name[0]) { +- /* AFAICT; there is no use of the actual 'filename' against +- * any canonicalization, so we will simply take the given +- * name, ignoring case sensitivity and aliases +- */ +- filename = ap_make_full_path(r->pool, d, +- ap_getword_conf(r->pool, &access_name)); +- status = ap_pcfg_openfile(&f, r->pool, filename); ++ while (access_names[0]) { ++ const char *access_name = ap_getword_conf(r->pool, &access_names); + ++ filename = NULL; ++ status = ap_run_open_htaccess(r, d, access_name, &f, &filename); + if (status == APR_SUCCESS) { + const char *errmsg; + ap_directive_t *temptree = NULL; +diff --git a/server/core.c b/server/core.c +index f3965ca..85f876b 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -4930,6 +4930,7 @@ static void register_hooks(apr_pool_t *p) + ap_hook_insert_network_bucket(core_insert_network_bucket, NULL, NULL, + APR_HOOK_REALLY_LAST); + ap_hook_dirwalk_stat(core_dirwalk_stat, NULL, NULL, APR_HOOK_REALLY_LAST); ++ ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST); + + /* register the core's insert_filter hook and register core-provided + * filters diff --git a/SOURCES/httpd-2.4.6-r1556818.patch b/SOURCES/httpd-2.4.6-r1556818.patch new file mode 100644 index 0000000..93195e1 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1556818.patch @@ -0,0 +1,26 @@ +# ./pullrev.sh r1556818 +http://svn.apache.org/viewvc?view=revision&revision=r1556818 +--- httpd-2.4.6/modules/aaa/mod_authn_core.c 2014/01/09 14:30:23 1556817 ++++ httpd-2.4.6/modules/aaa/mod_authn_core.c 2014/01/09 14:32:47 1556818 +@@ -179,6 +179,12 @@ + return (void *) authcfg; + } + ++/* Only per-server directive we have is GLOBAL_ONLY */ ++static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv) ++{ ++ return basev; ++} ++ + static const authn_provider authn_alias_provider = + { + &authn_alias_check_password, +@@ -373,7 +379,7 @@ + create_authn_core_dir_config, /* dir config creater */ + merge_authn_core_dir_config, /* dir merger --- default is to override */ + create_authn_alias_svr_config, /* server config */ +- NULL, /* merge server config */ ++ merge_authn_alias_svr_config, /* merge server config */ + authn_cmds, + register_hooks /* register hooks */ + }; diff --git a/SOURCES/httpd-2.4.6-r1618851.patch b/SOURCES/httpd-2.4.6-r1618851.patch new file mode 100644 index 0000000..fa84b0c --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1618851.patch @@ -0,0 +1,28 @@ +# ./pullrev.sh r1618851 +http://svn.apache.org/viewvc?view=revision&revision=r1618851 + +--- httpd-2.4.6/modules/aaa/mod_authz_core.c ++++ httpd-2.4.6/modules/aaa/mod_authz_core.c +@@ -168,6 +168,13 @@ + return (void*)conf; + } + ++/* Only per-server directive we have is GLOBAL_ONLY */ ++static void *merge_authz_core_svr_config(apr_pool_t *p, ++ void *basev, void *newv) ++{ ++ return basev; ++} ++ + static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s) + { + authz_core_srv_conf *authcfg; +@@ -1140,7 +1148,7 @@ AP_DECLARE_MODULE(authz_core) = + create_authz_core_dir_config, /* dir config creater */ + merge_authz_core_dir_config, /* dir merger */ + create_authz_core_svr_config, /* server config */ +- NULL, /* merge server config */ ++ merge_authz_core_svr_config , /* merge server config */ + authz_cmds, + register_hooks /* register hooks */ + }; diff --git a/SOURCES/httpd-2.4.6-rewrite-clientaddr.patch b/SOURCES/httpd-2.4.6-rewrite-clientaddr.patch new file mode 100644 index 0000000..e2bd079 --- /dev/null +++ b/SOURCES/httpd-2.4.6-rewrite-clientaddr.patch @@ -0,0 +1,14 @@ +--- a/modules/mappers/mod_rewrite.c 2014/01/28 19:40:17 1562174 ++++ b/modules/mappers/mod_rewrite.c 2014/02/10 18:54:23 1566702 +@@ -2139,7 +2139,10 @@ + break; + + case 16: +- if (!strcmp(var, "REQUEST_FILENAME")) { ++ if (*var == 'C' && !strcmp(var, "CONN_REMOTE_ADDR")) { ++ result = r->connection->client_ip; ++ } ++ else if (!strcmp(var, "REQUEST_FILENAME")) { + result = r->filename; /* same as script_filename (15) */ + } + break; diff --git a/SOURCES/httpd-2.4.6-sigint.patch b/SOURCES/httpd-2.4.6-sigint.patch new file mode 100644 index 0000000..7574a9c --- /dev/null +++ b/SOURCES/httpd-2.4.6-sigint.patch @@ -0,0 +1,45 @@ +From 20656c3b77cc548b59fea3bde5e2b7705d71c427 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Kalu=C5=BEa?= +Date: Mon, 18 Aug 2014 07:43:43 +0000 +Subject: [PATCH] prefork: Ignore SIGINT in child. This fixes race-condition in + signals handling when httpd is runnning on foreground and user hits ctrl+c. + In this case, SIGINT is sent to all children followed by SIGTERM from the + main process, which interrupts the SIGINT handler and leads to inconsistency + (process freezes or crashes). + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1618555 13f79535-47bb-0310-9956-ffa450edef68 +--- + server/mpm/prefork/prefork.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c +index 8790ec0..d6c038b 100644 +--- a/server/mpm/prefork/prefork.c ++++ b/server/mpm/prefork/prefork.c +@@ -222,6 +222,9 @@ static void clean_child_exit(int code) + { + mpm_state = AP_MPMQ_STOPPING; + ++ apr_signal(SIGHUP, SIG_IGN); ++ apr_signal(SIGTERM, SIG_IGN); ++ + if (pchild) { + apr_pool_destroy(pchild); + } +@@ -817,6 +820,13 @@ static int make_child(server_rec *s, int slot) + */ + apr_signal(SIGHUP, just_die); + apr_signal(SIGTERM, just_die); ++ /* Ignore SIGINT in child. This fixes race-condition in signals ++ * handling when httpd is runnning on foreground and user hits ctrl+c. ++ * In this case, SIGINT is sent to all children followed by SIGTERM ++ * from the main process, which interrupts the SIGINT handler and ++ * leads to inconsistency. ++ */ ++ apr_signal(SIGINT, SIG_IGN); + /* The child process just closes listeners on AP_SIG_GRACEFUL. + * The pod is used for signalling the graceful restart. + */ +-- +2.0.4 + diff --git a/SOURCES/httpd-2.4.6-ssl-ecdh-auto.patch b/SOURCES/httpd-2.4.6-ssl-ecdh-auto.patch new file mode 100644 index 0000000..7cbb1ec --- /dev/null +++ b/SOURCES/httpd-2.4.6-ssl-ecdh-auto.patch @@ -0,0 +1,22 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 0275452..8efdcd7 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -1144,11 +1144,16 @@ static void ssl_init_server_certs(server_rec *s, + OBJ_nid2sn(nid), vhost_id, mctx->pks->cert_files[0]); + } + /* +- * ...otherwise, configure NIST P-256 (required to enable ECDHE) ++ * ...otherwise, enable auto curve selection (OpenSSL 1.0.2 and later) ++ * or configure NIST P-256 (required to enable ECDHE for earlier versions) + */ + else { ++#if defined(SSL_CTX_set_ecdh_auto) ++ SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1); ++#else + SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, + EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); ++#endif + } + #endif + } diff --git a/SOURCES/httpd-2.4.6-ssl-large-keys.patch b/SOURCES/httpd-2.4.6-ssl-large-keys.patch new file mode 100644 index 0000000..46078ba --- /dev/null +++ b/SOURCES/httpd-2.4.6-ssl-large-keys.patch @@ -0,0 +1,173 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 46769e9..0275452 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -41,6 +41,79 @@ + #define KEYTYPES "RSA or DSA" + #endif + ++/* ++ * Grab well-defined DH parameters from OpenSSL, see the get_rfc* ++ * functions in for all available primes. ++ */ ++static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen) ++{ ++ DH *dh = DH_new(); ++ ++ if (!dh) { ++ return NULL; ++ } ++ dh->p = prime(NULL); ++ BN_dec2bn(&dh->g, gen); ++ if (!dh->p || !dh->g) { ++ DH_free(dh); ++ return NULL; ++ } ++ return dh; ++} ++ ++/* Storage and initialization for DH parameters. */ ++static struct dhparam { ++ BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */ ++ DH *dh; /* ...this, used for keys.... */ ++ const unsigned int min; /* ...of length >= this. */ ++} dhparams[] = { ++ { get_rfc3526_prime_8192, NULL, 6145 }, ++ { get_rfc3526_prime_6144, NULL, 4097 }, ++ { get_rfc3526_prime_4096, NULL, 3073 }, ++ { get_rfc3526_prime_3072, NULL, 2049 }, ++ { get_rfc3526_prime_2048, NULL, 1025 }, ++ { get_rfc2409_prime_1024, NULL, 0 } ++}; ++ ++static void init_dh_params(void) ++{ ++ unsigned n; ++ ++ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) ++ dhparams[n].dh = make_dh_params(dhparams[n].prime, "2"); ++} ++ ++static void free_dh_params(void) ++{ ++ unsigned n; ++ ++ /* DH_free() is a noop for a NULL parameter, so these are harmless ++ * in the (unexpected) case where these variables are already ++ * NULL. */ ++ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) { ++ DH_free(dhparams[n].dh); ++ dhparams[n].dh = NULL; ++ } ++} ++ ++/* Hand out the same DH structure though once generated as we leak ++ * memory otherwise and freeing the structure up after use would be ++ * hard to track and in fact is not needed at all as it is safe to ++ * use the same parameters over and over again security wise (in ++ * contrast to the keys itself) and code safe as the returned structure ++ * is duplicated by OpenSSL anyway. Hence no modification happens ++ * to our copy. */ ++DH *modssl_get_dh_params(unsigned keylen) ++{ ++ unsigned n; ++ ++ for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) ++ if (keylen >= dhparams[n].min) ++ return dhparams[n].dh; ++ ++ return NULL; /* impossible to reach. */ ++} ++ + static void ssl_add_version_components(apr_pool_t *p, + server_rec *s) + { +@@ -244,6 +317,8 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, + + SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ + ++ init_dh_params(); ++ + return OK; + } + +@@ -1623,6 +1698,8 @@ apr_status_t ssl_init_ModuleKill(void *data) + ssl_init_ctx_cleanup_server(sc->server); + } + ++ free_dh_params(); ++ + return APR_SUCCESS; + } + +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index 2d6d59e..1ecbccd 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -1287,34 +1287,6 @@ const authz_provider ssl_authz_provider_verify_client = + */ + + /* +- * Grab well-defined DH parameters from OpenSSL, see +- * (get_rfc*) for all available primes. +- */ +-#define make_get_dh(rfc,size,gen) \ +-static DH *get_dh##size(void) \ +-{ \ +- DH *dh; \ +- if (!(dh = DH_new())) { \ +- return NULL; \ +- } \ +- dh->p = get_##rfc##_prime_##size(NULL); \ +- BN_dec2bn(&dh->g, #gen); \ +- if (!dh->p || !dh->g) { \ +- DH_free(dh); \ +- return NULL; \ +- } \ +- return dh; \ +-} +- +-/* +- * Prepare DH parameters from 1024 to 4096 bits, in 1024-bit increments +- */ +-make_get_dh(rfc2409, 1024, 2) +-make_get_dh(rfc3526, 2048, 2) +-make_get_dh(rfc3526, 3072, 2) +-make_get_dh(rfc3526, 4096, 2) +- +-/* + * Hand out standard DH parameters, based on the authentication strength + */ + DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) +@@ -1342,14 +1314,7 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) + ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, + "handing out built-in DH parameters for %d-bit authenticated connection", keylen); + +- if (keylen >= 4096) +- return get_dh4096(); +- else if (keylen >= 3072) +- return get_dh3072(); +- else if (keylen >= 2048) +- return get_dh2048(); +- else +- return get_dh1024(); ++ return modssl_get_dh_params(keylen); + } + + /* +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index 744af9e..f47ed47 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -990,6 +990,11 @@ OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri, + conn_rec *c, apr_pool_t *p); + #endif + ++/* Retrieve DH parameters for given key length. Return value should ++ * be treated as unmutable, since it is stored in process-global ++ * memory. */ ++DH *modssl_get_dh_params(unsigned keylen); ++ + #endif /* SSL_PRIVATE_H */ + /** @} */ + diff --git a/SOURCES/welcome.conf b/SOURCES/welcome.conf index c1b6c11..5d1e452 100644 --- a/SOURCES/welcome.conf +++ b/SOURCES/welcome.conf @@ -16,7 +16,3 @@ Alias /.noindex.html /usr/share/httpd/noindex/index.html -Alias /noindex/css/bootstrap.min.css /usr/share/httpd/noindex/css/bootstrap.min.css -Alias /noindex/css/open-sans.css /usr/share/httpd/noindex/css/open-sans.css -Alias /images/apache_pb.gif /usr/share/httpd/noindex/images/apache_pb.gif -Alias /images/poweredby.png /usr/share/httpd/noindex/images/poweredby.png diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 9096fc2..b71659c 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -4,7 +4,7 @@ %define mmn 20120211 %define oldmmnisa %{mmn}-%{__isa_name}-%{__isa_bits} %define mmnisa %{mmn}%{__isa_name}%{__isa_bits} -%define vstring CentOS +%define vstring %(source /etc/os-release; echo ${REDHAT_SUPPORT_PRODUCT}) # Drop automatic provides for module DSOs %{?filter_setup: @@ -15,10 +15,10 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.6 -Release: 19%{?dist} +Release: 31%{?dist} URL: http://httpd.apache.org/ Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 -Source1: centos-noindex.tar.gz +Source1: index.html Source2: httpd.logrotate Source3: httpd.sysconf Source4: httpd-ssl-pass-dialog @@ -65,8 +65,10 @@ Patch30: httpd-2.4.4-cachehardmax.patch Patch31: httpd-2.4.6-sslmultiproxy.patch Patch32: httpd-2.4.6-r1537535.patch Patch33: httpd-2.4.6-r1542327.patch -Patch34: httpd-2.4.6-r1573626.patch -Patch35: httpd-2.4.6-uds.patch +Patch34: httpd-2.4.6-ssl-large-keys.patch +Patch35: httpd-2.4.6-pre_htaccess.patch +Patch36: httpd-2.4.6-r1573626.patch +Patch37: httpd-2.4.6-uds.patch # Bug fixes Patch51: httpd-2.4.3-sslsninotreq.patch Patch55: httpd-2.4.4-malformed-host.patch @@ -75,7 +77,13 @@ Patch57: httpd-2.4.6-ldaprefer.patch Patch58: httpd-2.4.6-r1507681+.patch Patch59: httpd-2.4.6-r1556473.patch Patch60: httpd-2.4.6-r1553540.patch -Patch61: httpd-2.4.6-r1526189.patch +Patch61: httpd-2.4.6-rewrite-clientaddr.patch +Patch62: httpd-2.4.6-ab-overflow.patch +Patch63: httpd-2.4.6-sigint.patch +Patch64: httpd-2.4.6-ssl-ecdh-auto.patch +Patch65: httpd-2.4.6-r1556818.patch +Patch66: httpd-2.4.6-r1618851.patch +Patch67: httpd-2.4.6-r1526189.patch # Security fixes Patch200: httpd-2.4.6-CVE-2013-6438.patch Patch201: httpd-2.4.6-CVE-2014-0098.patch @@ -84,6 +92,8 @@ Patch203: httpd-2.4.6-CVE-2014-0117.patch Patch204: httpd-2.4.6-CVE-2014-0118.patch Patch205: httpd-2.4.6-CVE-2014-0226.patch Patch206: httpd-2.4.6-CVE-2013-4352.patch +Patch207: httpd-2.4.6-CVE-2013-5704.patch +Patch208: httpd-2.4.6-CVE-2014-3581.patch License: ASL 2.0 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -147,6 +157,7 @@ Group: System Environment/Daemons Summary: SSL/TLS module for the Apache HTTP Server Epoch: 1 BuildRequires: openssl-devel +Requires: openssl-libs >= 1:1.0.1e-37 Requires(post): openssl, /bin/cat Requires(pre): httpd Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} @@ -209,8 +220,10 @@ interface for storing and accessing per-user session data. %patch32 -p1 -b .r1537535 %patch33 -p1 -b .r1542327 rm modules/ssl/ssl_engine_dh.c -%patch34 -p1 -b .r1573626 -%patch35 -p1 -b .uds +%patch34 -p1 -b .ssllargekeys +%patch35 -p1 -b .prehtaccess +%patch36 -p1 -b .r1573626 +%patch37 -p1 -b .uds %patch51 -p1 -b .sninotreq %patch55 -p1 -b .malformedhost @@ -219,7 +232,13 @@ rm modules/ssl/ssl_engine_dh.c %patch58 -p1 -b .r1507681+ %patch59 -p1 -b .r1556473 %patch60 -p1 -b .r1553540 -%patch61 -p1 -b .r1526189 +%patch61 -p1 -b .clientaddr +%patch62 -p1 -b .aboverflow +%patch63 -p1 -b .sigint +%patch64 -p1 -b .sslecdhauto +%patch65 -p1 -b .r1556818 +%patch66 -p1 -b .r1618851 +%patch67 -p1 -b .r1526189 %patch200 -p1 -b .cve6438 %patch201 -p1 -b .cve0098 @@ -228,6 +247,8 @@ rm modules/ssl/ssl_engine_dh.c %patch204 -p1 -b .cve0118 %patch205 -p1 -b .cve0226 %patch206 -p1 -b .cve4352 +%patch207 -p1 -b .cve5704 +%patch208 -p1 -b .cve3581 # Patch in the vendor string and the release string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -260,15 +281,15 @@ autoheader && autoconf || exit 1 export CFLAGS=$RPM_OPT_FLAGS export LDFLAGS="-Wl,-z,relro,-z,now" -%ifarch ppc64 -CFLAGS="$CFLAGS -O3" +%ifarch ppc64 ppc64le +%global _performance_build 1 %endif # Hard-code path to links to avoid unnecessary builddep export LYNX_PATH=/usr/bin/links # Build the daemon -./configure \ +%configure \ --prefix=%{_sysconfdir}/httpd \ --exec-prefix=%{_prefix} \ --bindir=%{_bindir} \ @@ -381,10 +402,8 @@ EOF # Handle contentdir mkdir $RPM_BUILD_ROOT%{contentdir}/noindex -tar xzf $RPM_SOURCE_DIR/centos-noindex.tar.gz \ - -C $RPM_BUILD_ROOT%{contentdir}/noindex/ \ - --strip-components=1 - +install -m 644 -p $RPM_SOURCE_DIR/index.html \ + $RPM_BUILD_ROOT%{contentdir}/noindex/index.html rm -rf %{contentdir}/htdocs # remove manual sources @@ -407,7 +426,7 @@ rm -v $RPM_BUILD_ROOT%{docroot}/html/*.html \ $RPM_BUILD_ROOT%{docroot}/cgi-bin/* # Symlink for the powered-by-$DISTRO image: -ln -s ../noindex/images/poweredby.png \ +ln -s ../../pixmaps/poweredby.png \ $RPM_BUILD_ROOT%{contentdir}/icons/poweredby.png # symlinks for /etc/httpd @@ -592,7 +611,7 @@ rm -rf $RPM_BUILD_ROOT %{contentdir}/error/README %{contentdir}/error/*.var %{contentdir}/error/include/*.html -%{contentdir}/noindex/* +%{contentdir}/noindex/index.html %dir %{docroot} %dir %{docroot}/cgi-bin @@ -658,23 +677,56 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/rpm/macros.httpd %changelog -* Mon Jan 12 2015 CentOS Sources - 2.4.6-19.el7.centos -- Remove index.html, add centos-noindex.tar.gz -- change vstring -- change symlink for poweredby.png -- update welcome.conf with proper aliases - -* Thu Dec 04 2014 Jan Kaluza - 2.4.6-19 +* Tue Dec 02 2014 Jan Kaluza - 2.4.6-31 - mod_proxy_fcgi: determine if FCGI_CONN_CLOSE should be enabled - instead of hardcoding it (#1170217) -- mod_proxy: support Unix Domain Sockets (#1170286) + instead of hardcoding it (#1168050) +- mod_proxy: support Unix Domain Sockets (#1168081) + +* Tue Nov 25 2014 Jan Kaluza - 2.4.6-30 +- core: fix bypassing of mod_headers rules via chunked requests (CVE-2013-5704) +- mod_cache: fix NULL pointer dereference on empty Content-Type (CVE-2014-3581) + +* Tue Nov 04 2014 Jan Kaluza - 2.4.6-29 +- rebuild against proper version of OpenSSL (#1080125) + +* Wed Oct 22 2014 Jan Kaluza - 2.4.6-28 +- set vstring based on /etc/os-release (#1114123) + +* Mon Oct 06 2014 Jan Kaluza - 2.4.6-27 +- fix the dependency on openssl-libs to match the fix for #1080125 + +* Mon Sep 22 2014 Jan Kaluza - 2.4.6-26 +- allow 'es to be seen under virtual hosts (#1131847) + +* Fri Sep 19 2014 Jan Kaluza - 2.4.6-25 +- do not use hardcoded curve for ECDHE suites (#1080125) + +* Wed Sep 03 2014 Jan Kaluza - 2.4.6-24 +- allow reverse-proxy to be set via SetHandler (#1136290) + +* Thu Aug 21 2014 Jan Kaluza - 2.4.6-23 +- fix possible crash in SIGINT handling (#1131006) + +* Mon Aug 18 2014 Jan Kaluza - 2.4.6-22 +- ab: fix integer overflow when printing stats with lot of requests (#1092420) + +* Mon Aug 11 2014 Jan Kaluza - 2.4.6-21 +- add pre_htaccess so mpm-itk can be build as separate module (#1059143) + +* Tue Aug 05 2014 Jan Kaluza - 2.4.6-20 +- mod_ssl: prefer larger keys and support up to 8192-bit keys (#1073078) + +* Mon Aug 04 2014 Jan Kaluza - 2.4.6-19 +- fix build on ppc64le by using configure macro (#1125545) +- compile httpd with -O3 on ppc64le (#1123490) +- mod_rewrite: expose CONN_REMOTE_ADDR (#1060536) * Thu Jul 17 2014 Jan Kaluza - 2.4.6-18 -- mod_cgid: add security fix for CVE-2014-0231 (#1120607) -- mod_proxy: add security fix for CVE-2014-0117 (#1120607) -- mod_deflate: add security fix for CVE-2014-0118 (#1120607) -- mod_status: add security fix for CVE-2014-0226 (#1120607) -- mod_cache: add secutiry fix for CVE-2013-4352 (#1120607) +- mod_cgid: add security fix for CVE-2014-0231 (#1120608) +- mod_proxy: add security fix for CVE-2014-0117 (#1120608) +- mod_deflate: add security fix for CVE-2014-0118 (#1120608) +- mod_status: add security fix for CVE-2014-0226 (#1120608) +- mod_cache: add secutiry fix for CVE-2013-4352 (#1120608) * Thu Mar 20 2014 Jan Kaluza - 2.4.6-17 - mod_dav: add security fix for CVE-2013-6438 (#1077907)