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/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 6685b0a..26d2893 100644 --- a/SOURCES/action-configtest.sh +++ b/SOURCES/action-configtest.sh @@ -1,2 +1,2 @@ #!/bin/sh -exec /sbin/apachectl configtest "$@" +exec /sbin/apachectl configtest diff --git a/SOURCES/action-graceful.sh b/SOURCES/action-graceful.sh index 3d28f0e..4976087 100644 --- a/SOURCES/action-graceful.sh +++ b/SOURCES/action-graceful.sh @@ -1,2 +1,2 @@ #!/bin/sh -exec /sbin/apachectl -k graceful "$@" +exec /sbin/apachectl graceful diff --git a/SOURCES/htcacheclean.service b/SOURCES/htcacheclean.service index 166067b..2a0aa8e 100644 --- a/SOURCES/htcacheclean.service +++ b/SOURCES/htcacheclean.service @@ -1,6 +1,7 @@ [Unit] Description=Disk Cache Cleaning Daemon for Apache HTTP Server After=httpd.service +Documentation=man:htcacheclean(8) [Service] Type=forking diff --git a/SOURCES/httpd-2.4.3-layout.patch b/SOURCES/httpd-2.4.3-layout.patch index 163c66b..f3ee9ec 100644 --- a/SOURCES/httpd-2.4.3-layout.patch +++ b/SOURCES/httpd-2.4.3-layout.patch @@ -3,7 +3,7 @@ Add layout for Fedora. --- httpd-2.4.3/config.layout.layout +++ httpd-2.4.3/config.layout -@@ -370,3 +370,27 @@ +@@ -370,3 +370,28 @@ logfiledir: ${localstatedir}/log/httpd proxycachedir: ${localstatedir}/cache/httpd @@ -30,4 +30,5 @@ Add layout for Fedora. + runtimedir: /run/httpd + logfiledir: ${localstatedir}/log/httpd + proxycachedir: ${localstatedir}/cache/httpd/proxy ++ davlockdb: ${localstatedir}/lib/dav/lockdb + 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..e1eba14 --- /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[2048]; + 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..3e884b9 --- /dev/null +++ b/SOURCES/httpd-2.4.6-apachectl-httpd-env.patch @@ -0,0 +1,38 @@ +diff --git a/docs/man/apachectl.8 b/docs/man/apachectl.8 +index 054550f..4bfc7cb 100644 +--- a/docs/man/apachectl.8 ++++ b/docs/man/apachectl.8 +@@ -77,7 +77,7 @@ status + Displays a brief status report\&. Similar to the fullstatus option, except that the list of requests currently being served is omitted\&. + .TP + graceful +-Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is started\&. This differs from a normal restart in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This means that if used in a log rotation script, a substantial delay may be necessary to ensure that the old log files are closed before processing them\&. This command automatically checks the configuration files as in configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. ++Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is not started\&. This differs from a normal restart in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This means that if used in a log rotation script, a substantial delay may be necessary to ensure that the old log files are closed before processing them\&. This command automatically checks the configuration files as in configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. + .TP + graceful-stop + Gracefully stops the Apache httpd daemon\&. This differs from a normal stop in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This is equivalent to apachectl -k graceful-stop\&. +diff --git a/support/apachectl.in b/support/apachectl.in +index 2d59623..10fc280 100644 +--- 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` /usr/sbin/httpd $OPTIONS -t + else +- $HTTPD $OPTIONS -t ++ /usr/sbin/httpd $OPTIONS -t + fi + ERROR=$? + } +@@ -134,7 +134,7 @@ fullstatus) + $LYNX $STATUSURL + ;; + *) +- $HTTPD $OPTIONS "$@" ++ /usr/sbin/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..779a9ab --- /dev/null +++ b/SOURCES/httpd-2.4.6-apachectl-status.patch @@ -0,0 +1,13 @@ +diff --git a/docs/man/apachectl.8 b/docs/man/apachectl.8 +index 4bfc7cb..372c08e 100644 +--- a/docs/man/apachectl.8 ++++ b/docs/man/apachectl.8 +@@ -74,7 +74,7 @@ fullstatus + Displays a full status report from mod_status\&. For this to work, you need to have mod_status enabled on your server and a text-based browser such as lynx available on your system\&. The URL used to access the status report can be set by editing the STATUSURL variable in the script\&. + .TP + status +-Displays a brief status report\&. Similar to the fullstatus option, except that the list of requests currently being served is omitted\&. ++Displays a brief status report using systemd\&. + .TP + graceful + Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is not started\&. This differs from a normal restart in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This means that if used in a log rotation script, a substantial delay may be necessary to ensure that the old log files are closed before processing them\&. This command automatically checks the configuration files as in configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. 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 d2e5565..cfe6d7b 100644 --- a/SOURCES/httpd-2.4.6-r1332643+.patch +++ b/SOURCES/httpd-2.4.6-r1332643+.patch @@ -199,7 +199,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + /* 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; ++ return SSL_TLSEXT_ERR_NOACK; + } + + /* Invoke our npn_advertise_protos hook, giving other modules a chance to @@ -238,7 +238,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1487772 + * anything to the protos array, or because all strings added to the array + * were skipped), then we're done. */ + if (size == 0) { -+ return SSL_TLSEXT_ERR_OK; ++ return SSL_TLSEXT_ERR_NOACK; + } + + /* Now we can build the string. Copy each protocol name string into the diff --git a/SOURCES/httpd-2.4.6-r1420184.patch b/SOURCES/httpd-2.4.6-r1420184.patch new file mode 100644 index 0000000..7de3031 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1420184.patch @@ -0,0 +1,154 @@ +Index: modules/aaa/mod_authz_owner.c +=================================================================== +--- a/modules/aaa/mod_authz_owner.c (revision 1420183) ++++ b/modules/aaa/mod_authz_owner.c (revision 1420184) +@@ -28,9 +28,8 @@ + #include "http_request.h" + + #include "mod_auth.h" ++#include "mod_authz_owner.h" + +-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); +- + static const command_rec authz_owner_cmds[] = + { + {NULL} +Index: modules/aaa/mod_authz_owner.h +=================================================================== +--- a/modules/aaa/mod_authz_owner.h (revision 0) ++++ b/modules/aaa/mod_authz_owner.h (revision 1420184) +@@ -0,0 +1,27 @@ ++/* Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef MOD_AUTHZ_OWNER_H ++#define MOD_AUTHZ_OWNER_H ++ ++#include "http_request.h" ++ ++/* mod_authz_owner exports an optional function which retrieves the ++ * group name of the file identified by r->filename, if available, or ++ * else returns NULL. */ ++APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); ++ ++#endif /* MOD_AUTHZ_OWNER_H */ +Index: modules/aaa/mod_authz_groupfile.c +=================================================================== +--- a/modules/aaa/mod_authz_groupfile.c (revision 1420183) ++++ b/modules/aaa/mod_authz_groupfile.c (revision 1420184) +@@ -55,13 +55,12 @@ + #include "util_varbuf.h" + + #include "mod_auth.h" ++#include "mod_authz_owner.h" + + typedef struct { + char *groupfile; + } authz_groupfile_config_rec; + +-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); +- + static void *create_authz_groupfile_dir_config(apr_pool_t *p, char *d) + { + authz_groupfile_config_rec *conf = apr_palloc(p, sizeof(*conf)); +@@ -200,7 +199,7 @@ + return AUTHZ_DENIED; + } + +-APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; ++static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; + + static authz_status filegroup_check_authorization(request_rec *r, + const char *require_args, +@@ -279,10 +278,14 @@ + NULL, + }; + +-static void register_hooks(apr_pool_t *p) ++ ++static void authz_groupfile_getfns(void) + { + authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); ++} + ++static void register_hooks(apr_pool_t *p) ++{ + ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "group", + AUTHZ_PROVIDER_VERSION, + &authz_group_provider, +@@ -291,6 +294,7 @@ + AUTHZ_PROVIDER_VERSION, + &authz_filegroup_provider, + AP_AUTH_INTERNAL_PER_CONF); ++ ap_hook_optional_fn_retrieve(authz_groupfile_getfns, NULL, NULL, APR_HOOK_MIDDLE); + } + + AP_DECLARE_MODULE(authz_groupfile) = +Index: modules/aaa/mod_authz_dbm.c +=================================================================== +--- a/modules/aaa/mod_authz_dbm.c (revision 1420183) ++++ b/modules/aaa/mod_authz_dbm.c (revision 1420184) +@@ -29,6 +29,7 @@ + #include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/ + + #include "mod_auth.h" ++#include "mod_authz_owner.h" + + typedef struct { + const char *grpfile; +@@ -35,9 +36,7 @@ + const char *dbmtype; + } authz_dbm_config_rec; + +-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); + +- + /* This should go into APR; perhaps with some nice + * caching/locking/flocking of the open dbm file. + */ +@@ -199,7 +198,7 @@ + return AUTHZ_DENIED; + } + +-APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; ++static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; + + static authz_status dbmfilegroup_check_authorization(request_rec *r, + const char *require_args, +@@ -279,11 +278,13 @@ + NULL, + }; + ++static void authz_dbm_getfns(void) ++{ ++ authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); ++} + + static void register_hooks(apr_pool_t *p) + { +- authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); +- + ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-group", + AUTHZ_PROVIDER_VERSION, + &authz_dbmgroup_provider, +@@ -292,6 +293,7 @@ + AUTHZ_PROVIDER_VERSION, + &authz_dbmfilegroup_provider, + AP_AUTH_INTERNAL_PER_CONF); ++ ap_hook_optional_fn_retrieve(authz_dbm_getfns, NULL, NULL, APR_HOOK_MIDDLE); + } + + AP_DECLARE_MODULE(authz_dbm) = diff --git a/SOURCES/httpd-2.4.6-r1506474.patch b/SOURCES/httpd-2.4.6-r1506474.patch new file mode 100644 index 0000000..182bc04 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1506474.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.6-r1524368.patch b/SOURCES/httpd-2.4.6-r1524368.patch new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1524368.patch @@ -0,0 +1,20 @@ +--- a/modules/proxy/mod_proxy_fcgi.c 2013/09/18 11:17:28 1524367 ++++ b/modules/proxy/mod_proxy_fcgi.c 2013/09/18 11:18:02 1524368 +@@ -429,15 +429,13 @@ + ob = apr_brigade_create(r->pool, c->bucket_alloc); + + while (! done) { +- apr_interval_time_t timeout = conn->worker->s->timeout; ++ apr_interval_time_t timeout; + apr_size_t len; + int n; + + /* We need SOME kind of timeout here, or virtually anything will + * cause timeout errors. */ +- if (! conn->worker->s->timeout_set) { +- timeout = apr_time_from_sec(30); +- } ++ apr_socket_timeout_get(conn->sock, &timeout); + + rv = apr_poll(&pfd, 1, &n, timeout); + if (rv != APR_SUCCESS) { diff --git a/SOURCES/httpd-2.4.6-r1527509.patch b/SOURCES/httpd-2.4.6-r1527509.patch new file mode 100644 index 0000000..103a460 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1527509.patch @@ -0,0 +1,21 @@ +diff -Npru httpd-2.4.6.orig/modules/dav/main/mod_dav.c httpd-2.4.6/modules/dav/main/mod_dav.c +--- httpd-2.4.6.orig/modules/dav/main/mod_dav.c 2015-06-24 12:24:47.920000000 -0400 ++++ httpd-2.4.6/modules/dav/main/mod_dav.c 2015-06-24 12:27:19.706000000 -0400 +@@ -316,6 +316,8 @@ static int dav_error_response(request_re + { + r->status = status; + ++ r->status_line = ap_get_status_line(status); ++ + ap_set_content_type(r, "text/html; charset=ISO-8859-1"); + + /* begin the response now... */ +@@ -347,6 +349,8 @@ static int dav_error_response_tag(reques + { + r->status = err->status; + ++ r->status_line = ap_get_status_line(err->status); ++ + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + ap_rputs(DAV_XML_HEADER DEBUG_CR diff --git a/SOURCES/httpd-2.4.6-r1528556.patch b/SOURCES/httpd-2.4.6-r1528556.patch new file mode 100644 index 0000000..bab51aa --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1528556.patch @@ -0,0 +1,23 @@ +Index: modules/mappers/mod_rewrite.c +=================================================================== +--- a/modules/mappers/mod_rewrite.c (revision 1499025) ++++ b/modules/mappers/mod_rewrite.c (revision 1528556) +@@ -589,6 +589,18 @@ + return 7; + } + break; ++ ++ case 'w': ++ case 'W': ++ if (!strncasecmp(uri, "s://", 4)) { /* ws:// */ ++ *sqs = 1; ++ return 5; ++ } ++ else if (!strncasecmp(uri, "ss://", 5)) { /* wss:// */ ++ *sqs = 1; ++ return 6; ++ } ++ break; + } + + return 0; diff --git a/SOURCES/httpd-2.4.6-r1528958.patch b/SOURCES/httpd-2.4.6-r1528958.patch new file mode 100644 index 0000000..82bfd6e --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1528958.patch @@ -0,0 +1,46 @@ +--- a/server/vhost.c 2013/07/15 11:50:50 1503188 ++++ b/server/vhost.c 2013/10/03 18:31:22 1528958 +@@ -577,14 +577,22 @@ + */ + + for (s = main_s->next; s; s = s->next) { ++ server_addr_rec *sar_prev = NULL; + has_default_vhost_addr = 0; + for (sar = s->addrs; sar; sar = sar->next) { + ipaddr_chain *ic; + char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ +- ++ /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */ + if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) { + ic = find_default_server(sar->host_port); +- if (!ic || sar->host_port != ic->sar->host_port) { ++ ++ if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server" */ ++ if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len) ++ || sar_prev->host_port != sar->host_port) { ++ add_name_vhost_config(p, main_s, s, sar, ic); ++ } ++ } ++ else { + /* No default server, or we found a default server but + ** exactly one of us is a wildcard port, which means we want + ** two ip-based vhosts not an NVH with two names +@@ -592,6 +600,7 @@ + ic = new_ipaddr_chain(p, s, sar); + ic->next = default_list; + default_list = ic; ++ add_name_vhost_config(p, main_s, s, sar, ic); + } + has_default_vhost_addr = 1; + } +@@ -609,8 +618,9 @@ + ic->next = *iphash_table_tail[bucket]; + *iphash_table_tail[bucket] = ic; + } ++ add_name_vhost_config(p, main_s, s, sar, ic); + } +- add_name_vhost_config(p, main_s, s, sar, ic); ++ sar_prev = sar; + } + + /* Ok now we want to set up a server_hostname if the user was diff --git a/SOURCES/httpd-2.4.6-r1530280.patch b/SOURCES/httpd-2.4.6-r1530280.patch new file mode 100644 index 0000000..ea748e1 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1530280.patch @@ -0,0 +1,59 @@ +--- a/modules/http/http_filters.c 2013/10/08 14:17:33 1530279 ++++ b/modules/http/http_filters.c 2013/10/08 14:18:44 1530280 +@@ -825,7 +825,7 @@ + * handler. + * Zap r->status_line if bad. + */ +-static void validate_status_line(request_rec *r) ++static apr_status_t validate_status_line(request_rec *r) + { + char *end; + +@@ -836,15 +836,19 @@ + || (end - 3) != r->status_line + || (len >= 4 && ! apr_isspace(r->status_line[3]))) { + r->status_line = NULL; ++ return APR_EGENERAL; + } + /* Since we passed the above check, we know that length three + * is equivalent to only a 3 digit numeric http status. + * RFC2616 mandates a trailing space, let's add it. + */ +- else if (len == 3) { ++ if (len == 3) { + r->status_line = apr_pstrcat(r->pool, r->status_line, " ", NULL); ++ return APR_EGENERAL; + } ++ return APR_SUCCESS; + } ++ return APR_EGENERAL; + } + + /* +@@ -856,15 +860,25 @@ + static void basic_http_header_check(request_rec *r, + const char **protocol) + { ++ apr_status_t rv; ++ + if (r->assbackwards) { + /* no such thing as a response protocol */ + return; + } + +- validate_status_line(r); ++ rv = validate_status_line(r); + + if (!r->status_line) { + r->status_line = ap_get_status_line(r->status); ++ } else if (rv != APR_SUCCESS) { ++ /* Status line is OK but our own reason phrase ++ * would be preferred if defined ++ */ ++ const char *tmp = ap_get_status_line(r->status); ++ if (!strncmp(tmp, r->status_line, 3)) { ++ r->status_line = tmp; ++ } + } + + /* Note that we must downgrade before checking for force responses. */ diff --git a/SOURCES/httpd-2.4.6-r1533448.patch b/SOURCES/httpd-2.4.6-r1533448.patch new file mode 100644 index 0000000..3b90cb1 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1533448.patch @@ -0,0 +1,155 @@ +Index: modules/dav/fs/repos.c +=================================================================== +--- a/modules/dav/fs/repos.c (revision 1533447) ++++ b/modules/dav/fs/repos.c (revision 1533448) +@@ -717,13 +717,13 @@ + resource->pool = r->pool; + + /* make sure the URI does not have a trailing "/" */ +- len = strlen(r->uri); +- if (len > 1 && r->uri[len - 1] == '/') { +- s = apr_pstrmemdup(r->pool, r->uri, len-1); ++ len = strlen(r->unparsed_uri); ++ if (len > 1 && r->unparsed_uri[len - 1] == '/') { ++ s = apr_pstrmemdup(r->pool, r->unparsed_uri, len-1); + resource->uri = s; + } + else { +- resource->uri = r->uri; ++ resource->uri = r->unparsed_uri; + } + + if (r->finfo.filetype != APR_NOFILE) { +@@ -1482,6 +1482,18 @@ + return dav_fs_deleteset(info->pool, resource); + } + ++/* Take an unescaped path component and escape it and append it onto a ++ * dav_buffer for a URI */ ++static apr_size_t dav_fs_append_uri(apr_pool_t *p, dav_buffer *pbuf, ++ const char *path, apr_size_t pad) ++{ ++ const char *epath = ap_escape_uri(p, path); ++ apr_size_t epath_len = strlen(epath); ++ ++ dav_buffer_place_mem(p, pbuf, epath, epath_len + 1, pad); ++ return epath_len; ++} ++ + /* ### move this to dav_util? */ + /* Walk recursively down through directories, * + * including lock-null resources as we go. */ +@@ -1537,6 +1549,7 @@ + } + while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) { + apr_size_t len; ++ apr_size_t escaped_len; + + len = strlen(dirent.name); + +@@ -1579,7 +1592,7 @@ + + /* copy the file to the URI, too. NOTE: we will pad an extra byte + for the trailing slash later. */ +- dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1); ++ escaped_len = dav_fs_append_uri(pool, &fsctx->uri_buf, dirent.name, 1); + + /* if there is a secondary path, then do that, too */ + if (fsctx->path2.buf != NULL) { +@@ -1612,7 +1625,7 @@ + fsctx->path2.cur_len += len; + + /* adjust URI length to incorporate subdir and a slash */ +- fsctx->uri_buf.cur_len += len + 1; ++ fsctx->uri_buf.cur_len += escaped_len + 1; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/'; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0'; + +@@ -1678,8 +1691,8 @@ + */ + dav_buffer_place_mem(pool, &fsctx->path1, + fsctx->locknull_buf.buf + offset, len + 1, 0); +- dav_buffer_place_mem(pool, &fsctx->uri_buf, +- fsctx->locknull_buf.buf + offset, len + 1, 0); ++ dav_fs_append_uri(pool, &fsctx->uri_buf, ++ fsctx->locknull_buf.buf + offset, 0); + if (fsctx->path2.buf != NULL) { + dav_buffer_place_mem(pool, &fsctx->path2, + fsctx->locknull_buf.buf + offset, +Index: modules/dav/main/mod_dav.c +=================================================================== +--- a/modules/dav/main/mod_dav.c (revision 1533447) ++++ b/modules/dav/main/mod_dav.c (revision 1533448) +@@ -396,11 +396,9 @@ + */ + static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri) + { +- const char *e_uri = ap_escape_uri(p, uri); +- + /* check the easy case... */ +- if (ap_strchr_c(e_uri, '&') == NULL) +- return e_uri; ++ if (ap_strchr_c(uri, '&') == NULL) ++ return uri; + + /* there was a '&', so more work is needed... sigh. */ + +@@ -408,7 +406,7 @@ + * Note: this is a teeny bit of overkill since we know there are no + * '<' or '>' characters, but who cares. + */ +- return apr_xml_quote_string(p, e_uri, 0); ++ return apr_xml_quote_string(p, uri, 0); + } + + +@@ -604,7 +602,8 @@ + return DONE; + } + +-/* handy function for return values of methods that (may) create things */ ++/* handy function for return values of methods that (may) create things. ++ * locn if provided is assumed to be escaped. */ + static int dav_created(request_rec *r, const char *locn, const char *what, + int replaced) + { +@@ -612,8 +611,6 @@ + + if (locn == NULL) { + locn = r->unparsed_uri; +- } else { +- locn = ap_escape_uri(r->pool, locn); + } + + /* did the target resource already exist? */ +@@ -3004,7 +3001,7 @@ + } + + /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ +- return dav_created(r, lookup.rnew->uri, "Destination", ++ return dav_created(r, lookup.rnew->unparsed_uri, "Destination", + resnew_state == DAV_RESOURCE_EXISTS); + } + +@@ -4610,7 +4607,7 @@ + + /* return an appropriate response (HTTP_CREATED) */ + /* ### spec doesn't say what happens when destination was replaced */ +- return dav_created(r, lookup.rnew->uri, "Binding", 0); ++ return dav_created(r, lookup.rnew->unparsed_uri, "Binding", 0); + } + + +Index: modules/dav/main/mod_dav.h +=================================================================== +--- a/modules/dav/main/mod_dav.h (revision 1533447) ++++ b/modules/dav/main/mod_dav.h (revision 1533448) +@@ -386,7 +386,7 @@ + * REGULAR and WORKSPACE resources, + * and is always 1 for WORKING */ + +- const char *uri; /* the URI for this resource */ ++ const char *uri; /* the escaped URI for this resource */ + + dav_resource_private *info; /* the provider's private info */ + diff --git a/SOURCES/httpd-2.4.6-r1569006.patch b/SOURCES/httpd-2.4.6-r1569006.patch new file mode 100644 index 0000000..32dd900 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1569006.patch @@ -0,0 +1,19 @@ +--- a/modules/metadata/mod_remoteip.c 2014/02/17 14:11:38 1569005 ++++ b/modules/metadata/mod_remoteip.c 2014/02/17 14:12:30 1569006 +@@ -246,14 +246,14 @@ + + while (remote) { + +- /* verify c->client_addr is trusted if there is a trusted proxy list ++ /* verify user agent IP against the trusted proxy list + */ + if (config->proxymatch_ip) { + int i; + remoteip_proxymatch_t *match; + match = (remoteip_proxymatch_t *)config->proxymatch_ip->elts; + for (i = 0; i < config->proxymatch_ip->nelts; ++i) { +- if (apr_ipsubnet_test(match[i].ip, c->client_addr)) { ++ if (apr_ipsubnet_test(match[i].ip, temp_sa)) { + internal = match[i].internal; + break; + } diff --git a/SOURCES/httpd-2.4.6-r1594625.patch b/SOURCES/httpd-2.4.6-r1594625.patch new file mode 100644 index 0000000..487b2ad --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1594625.patch @@ -0,0 +1,25 @@ +Index: modules/proxy/mod_proxy_wstunnel.c +=================================================================== +--- a/modules/proxy/mod_proxy_wstunnel.c (revision 1593857) ++++ b/modules/proxy/mod_proxy_wstunnel.c (revision 1594625) +@@ -477,9 +477,11 @@ + conn_rec *c = r->connection; + apr_pool_t *p = r->pool; + apr_uri_t *uri; ++ int is_ssl = 0; + + if (strncasecmp(url, "wss:", 4) == 0) { + scheme = "WSS"; ++ is_ssl = 1; + } + else if (strncasecmp(url, "ws:", 3) == 0) { + scheme = "WS"; +@@ -503,7 +505,7 @@ + return status; + } + +- backend->is_ssl = 0; ++ backend->is_ssl = is_ssl; + backend->close = 0; + + retry = 0; diff --git a/SOURCES/httpd-2.4.6-r1604460.patch b/SOURCES/httpd-2.4.6-r1604460.patch new file mode 100644 index 0000000..465005d --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1604460.patch @@ -0,0 +1,22 @@ +--- a/modules/filters/mod_deflate.c 2014/02/26 15:24:07 1572091 ++++ b/modules/filters/mod_deflate.c 2014/02/26 15:30:25 1572092 +@@ -1125,7 +1125,8 @@ + } + ctx->stream.next_in += 4; + compLen = getLong(ctx->stream.next_in); +- if (ctx->stream.total_out != compLen) { ++ /* gzip stores original size only as 4 byte value */ ++ if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) { + inflateEnd(&ctx->stream); + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01395) + "Zlib: Length %ld of inflated data does " +@@ -1322,7 +1323,8 @@ + } + ctx->validation_buffer += VALIDATION_SIZE / 2; + compLen = getLong(ctx->validation_buffer); +- if (ctx->stream.total_out != compLen) { ++ /* gzip stores original size only as 4 byte value */ ++ if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01400) + "Zlib: Length of inflated stream invalid"); + return APR_EGENERAL; diff --git a/SOURCES/httpd-2.4.6-r1610013.patch b/SOURCES/httpd-2.4.6-r1610013.patch new file mode 100644 index 0000000..b53ae60 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1610013.patch @@ -0,0 +1,141 @@ +Index: modules/dav/main/mod_dav.c +=================================================================== +--- a/modules/dav/main/mod_dav.c (revision 1610012) ++++ b/modules/dav/main/mod_dav.c (revision 1610013) +@@ -396,9 +396,11 @@ + */ + static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri) + { ++ const char *e_uri = ap_escape_uri(p, uri); ++ + /* check the easy case... */ +- if (ap_strchr_c(uri, '&') == NULL) +- return uri; ++ if (ap_strchr_c(e_uri, '&') == NULL) ++ return e_uri; + + /* there was a '&', so more work is needed... sigh. */ + +@@ -406,7 +408,7 @@ + * Note: this is a teeny bit of overkill since we know there are no + * '<' or '>' characters, but who cares. + */ +- return apr_xml_quote_string(p, uri, 0); ++ return apr_xml_quote_string(p, e_uri, 0); + } + + +Index: modules/dav/main/mod_dav.h +=================================================================== +--- a/modules/dav/main/mod_dav.h (revision 1610012) ++++ b/modules/dav/main/mod_dav.h (revision 1610013) +@@ -386,7 +386,9 @@ + * REGULAR and WORKSPACE resources, + * and is always 1 for WORKING */ + +- const char *uri; /* the escaped URI for this resource */ ++ const char *uri; /* the URI for this resource; ++ * currently has an ABI flaw where sometimes it is ++ * assumed to be encoded and sometimes not */ + + dav_resource_private *info; /* the provider's private info */ + +Index: modules/dav/main/props.c +=================================================================== +--- a/modules/dav/main/props.c (revision 1610012) ++++ b/modules/dav/main/props.c (revision 1610013) +@@ -321,10 +321,14 @@ + /* do a sub-request to fetch properties for the target resource's URI. */ + static void dav_do_prop_subreq(dav_propdb *propdb) + { ++ /* need to escape the uri that's in the resource struct because during ++ * the property walker it's not encoded. */ ++ const char *e_uri = ap_escape_uri(propdb->resource->pool, ++ propdb->resource->uri); ++ + /* perform a "GET" on the resource's URI (note that the resource + may not correspond to the current request!). */ +- propdb->subreq = ap_sub_req_lookup_uri(propdb->resource->uri, propdb->r, +- NULL); ++ propdb->subreq = ap_sub_req_lookup_uri(e_uri, propdb->r, NULL); + } + + static dav_error * dav_insert_coreprop(dav_propdb *propdb, +Index: modules/dav/fs/repos.c +=================================================================== +--- a/modules/dav/fs/repos.c (revision 1610012) ++++ b/modules/dav/fs/repos.c (revision 1610013) +@@ -717,13 +717,13 @@ + resource->pool = r->pool; + + /* make sure the URI does not have a trailing "/" */ +- len = strlen(r->unparsed_uri); +- if (len > 1 && r->unparsed_uri[len - 1] == '/') { +- s = apr_pstrmemdup(r->pool, r->unparsed_uri, len-1); ++ len = strlen(r->uri); ++ if (len > 1 && r->uri[len - 1] == '/') { ++ s = apr_pstrmemdup(r->pool, r->uri, len-1); + resource->uri = s; + } + else { +- resource->uri = r->unparsed_uri; ++ resource->uri = r->uri; + } + + if (r->finfo.filetype != APR_NOFILE) { +@@ -1482,18 +1482,6 @@ + return dav_fs_deleteset(info->pool, resource); + } + +-/* Take an unescaped path component and escape it and append it onto a +- * dav_buffer for a URI */ +-static apr_size_t dav_fs_append_uri(apr_pool_t *p, dav_buffer *pbuf, +- const char *path, apr_size_t pad) +-{ +- const char *epath = ap_escape_uri(p, path); +- apr_size_t epath_len = strlen(epath); +- +- dav_buffer_place_mem(p, pbuf, epath, epath_len + 1, pad); +- return epath_len; +-} +- + /* ### move this to dav_util? */ + /* Walk recursively down through directories, * + * including lock-null resources as we go. */ +@@ -1549,7 +1537,6 @@ + } + while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) { + apr_size_t len; +- apr_size_t escaped_len; + + len = strlen(dirent.name); + +@@ -1592,7 +1579,7 @@ + + /* copy the file to the URI, too. NOTE: we will pad an extra byte + for the trailing slash later. */ +- escaped_len = dav_fs_append_uri(pool, &fsctx->uri_buf, dirent.name, 1); ++ dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1); + + /* if there is a secondary path, then do that, too */ + if (fsctx->path2.buf != NULL) { +@@ -1625,7 +1612,7 @@ + fsctx->path2.cur_len += len; + + /* adjust URI length to incorporate subdir and a slash */ +- fsctx->uri_buf.cur_len += escaped_len + 1; ++ fsctx->uri_buf.cur_len += len + 1; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/'; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0'; + +@@ -1691,8 +1678,8 @@ + */ + dav_buffer_place_mem(pool, &fsctx->path1, + fsctx->locknull_buf.buf + offset, len + 1, 0); +- dav_fs_append_uri(pool, &fsctx->uri_buf, +- fsctx->locknull_buf.buf + offset, 0); ++ dav_buffer_place_mem(pool, &fsctx->uri_buf, ++ fsctx->locknull_buf.buf + offset, len + 1, 0); + if (fsctx->path2.buf != NULL) { + dav_buffer_place_mem(pool, &fsctx->path2, + fsctx->locknull_buf.buf + offset, diff --git a/SOURCES/httpd-2.4.6-r1624349.patch b/SOURCES/httpd-2.4.6-r1624349.patch new file mode 100644 index 0000000..c2e93f8 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1624349.patch @@ -0,0 +1,21 @@ +diff --git a/server/scoreboard.c b/server/scoreboard.c +index bef2b90..c8ef6a3 100644 +--- a/server/scoreboard.c ++++ b/server/scoreboard.c +@@ -484,8 +484,14 @@ static int update_child_status_internal(int child_num, + ws->conn_bytes = 0; + } + if (r) { +- apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, +- REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); ++ const char *client = ap_get_remote_host(c, r->per_dir_config, ++ REMOTE_NOLOOKUP, NULL); ++ if (!client || !strcmp(client, c->client_ip)) { ++ apr_cpystrn(ws->client, r->useragent_ip, sizeof(ws->client)); ++ } ++ else { ++ apr_cpystrn(ws->client, client, sizeof(ws->client)); ++ } + copy_request(ws->request, sizeof(ws->request), r); + if (r->server) { + apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d", diff --git a/SOURCES/httpd-2.4.6-r1633085.patch b/SOURCES/httpd-2.4.6-r1633085.patch new file mode 100644 index 0000000..ec10a6a --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1633085.patch @@ -0,0 +1,14 @@ +--- a/modules/ssl/ssl_engine_io.c 2014/10/20 09:11:19 1633084 ++++ b/modules/ssl/ssl_engine_io.c 2014/10/20 09:18:22 1633085 +@@ -1322,6 +1322,11 @@ + "\"SSLVerifyClient optional_no_ca\" " + "configuration"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server); ++ ++ /* on session resumption ssl_callback_SSLVerify() ++ * will not be called, therefore we have to set it here ++ */ ++ sslconn->verify_info = "GENEROUS"; + } + else { + const char *error = sslconn->verify_error ? diff --git a/SOURCES/httpd-2.4.6-r1650655.patch b/SOURCES/httpd-2.4.6-r1650655.patch new file mode 100644 index 0000000..1791419 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1650655.patch @@ -0,0 +1,41 @@ +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index c37a09b..2121892 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -1733,6 +1733,9 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p, + + memset(wshared, 0, sizeof(proxy_worker_shared)); + ++ if (uri.port && uri.port == ap_proxy_port_of_scheme(uri.scheme)) { ++ uri.port = 0; ++ } + ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD); + if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) { + return apr_psprintf(p, "worker name (%s) too long", ptr); +@@ -2688,6 +2691,13 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + worker->s->hostname); + break; + } ++ ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02823) ++ "%s: connection established with Unix domain socket " ++ "%s (%s)", ++ proxy_function, ++ conn->uds_path, ++ worker->s->hostname); + } + else + #endif +@@ -2780,6 +2790,12 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + backend_addr = backend_addr->next; + continue; + } ++ ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02824) ++ "%s: connection established with %pI (%s)", ++ proxy_function, ++ backend_addr, ++ worker->s->hostname); + } + + /* Set a timeout on the socket */ diff --git a/SOURCES/httpd-2.4.6-r1651083.patch b/SOURCES/httpd-2.4.6-r1651083.patch new file mode 100644 index 0000000..57505ad --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1651083.patch @@ -0,0 +1,10 @@ +--- a/server/core.c 2015/01/12 13:37:20 1651082 ++++ b/server/core.c 2015/01/12 13:38:02 1651083 +@@ -1271,6 +1271,7 @@ + static int reset_config_defines(void *dummy) + { + ap_server_config_defines = saved_server_config_defines; ++ saved_server_config_defines = NULL; + server_config_defined_vars = NULL; + return OK; + } diff --git a/SOURCES/httpd-2.4.6-r1663647.patch b/SOURCES/httpd-2.4.6-r1663647.patch new file mode 100644 index 0000000..4d082cf --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1663647.patch @@ -0,0 +1,22 @@ +--- a/modules/aaa/mod_authn_dbd.c 2015/03/03 11:11:33 1663646 ++++ b/modules/aaa/mod_authn_dbd.c 2015/03/03 11:12:18 1663647 +@@ -174,7 +174,8 @@ + i++; + } + #endif +- dbd_password = apr_dbd_get_entry(dbd->driver, row, 0); ++ dbd_password = apr_pstrdup(r->pool, ++ apr_dbd_get_entry(dbd->driver, row, 0)); + } + /* we can't break out here or row won't get cleaned up */ + } +@@ -269,7 +270,8 @@ + i++; + } + #endif +- dbd_hash = apr_dbd_get_entry(dbd->driver, row, 0); ++ dbd_hash = apr_pstrdup(r->pool, ++ apr_dbd_get_entry(dbd->driver, row, 0)); + } + /* we can't break out here or row won't get cleaned up */ + } diff --git a/SOURCES/httpd-2.4.6-r1674222.patch b/SOURCES/httpd-2.4.6-r1674222.patch new file mode 100644 index 0000000..60356b0 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1674222.patch @@ -0,0 +1,81 @@ +Index: acinclude.m4 +=================================================================== +--- a/acinclude.m4 (revision 1667671) ++++ b/acinclude.m4 (working copy) +@@ -43,6 +43,7 @@ + APACHE_SUBST(installbuilddir) + APACHE_SUBST(runtimedir) + APACHE_SUBST(proxycachedir) ++ APACHE_SUBST(davlockdb) + APACHE_SUBST(other_targets) + APACHE_SUBST(progname) + APACHE_SUBST(prefix) +@@ -710,6 +711,7 @@ + APACHE_SUBST_EXPANDED_ARG(runtimedir) + APACHE_SUBST_EXPANDED_ARG(logfiledir) + APACHE_SUBST_EXPANDED_ARG(proxycachedir) ++ APACHE_SUBST_EXPANDED_ARG(davlockdb) + ]) + + dnl +Index: build/mkconfNW.awk +=================================================================== +--- a/build/mkconfNW.awk (revision 1667671) ++++ b/build/mkconfNW.awk (working copy) +@@ -26,6 +26,7 @@ + A["runtimedir"] = "logs" + A["errordir"] = "error" + A["proxycachedir"] = "proxy" ++ A["davlockdb"] = "davlockdb" + + B["htdocsdir"] = A["ServerRoot"]"/"A["htdocsdir"] + B["iconsdir"] = A["ServerRoot"]"/"A["iconsdir"] +@@ -32,6 +33,7 @@ + B["manualdir"] = A["ServerRoot"]"/"A["manualdir"] + B["errordir"] = A["ServerRoot"]"/"A["errordir"] + B["proxycachedir"] = A["ServerRoot"]"/"A["proxycachedir"] ++ B["davlockdb"] = A["ServerRoot"]"/"A["davlockdb"] + B["cgidir"] = A["ServerRoot"]"/"A["cgidir"] + B["logfiledir"] = A["logfiledir"] + B["sysconfdir"] = A["sysconfdir"] +Index: include/ap_config_layout.h.in +=================================================================== +--- a/include/ap_config_layout.h.in (revision 1667671) ++++ b/include/ap_config_layout.h.in (working copy) +@@ -60,5 +60,7 @@ + #define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@" + #define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@" + #define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@" ++#define DEFAULT_EXP_DAVLOCKDB "@exp_davlockdb@" ++#define DEFAULT_REL_DAVLOCKDB "@rel_davlockdb@" + + #endif /* AP_CONFIG_LAYOUT_H */ +Index: modules/dav/fs/mod_dav_fs.c +=================================================================== +--- a/modules/dav/fs/mod_dav_fs.c (revision 1667671) ++++ b/modules/dav/fs/mod_dav_fs.c (working copy) +@@ -17,6 +17,7 @@ + #include "httpd.h" + #include "http_config.h" + #include "apr_strings.h" ++#include "ap_config_auto.h" + + #include "mod_dav.h" + #include "repos.h" +@@ -39,7 +40,15 @@ + + static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s) + { +- return apr_pcalloc(p, sizeof(dav_fs_server_conf)); ++ dav_fs_server_conf *conf = apr_pcalloc(p, sizeof(dav_fs_server_conf)); ++#ifdef DEFAULT_EXP_DAVLOCKDB ++ conf->lockdb_path = DEFAULT_EXP_DAVLOCKDB; ++ if (*conf->lockdb_path == '\0') { ++ conf->lockdb_path = NULL; ++ } ++#endif ++ ++ return conf; + } + + static void *dav_fs_merge_server_config(apr_pool_t *p, diff --git a/SOURCES/httpd-2.4.6-r1688399.patch b/SOURCES/httpd-2.4.6-r1688399.patch new file mode 100644 index 0000000..91f94ee --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1688399.patch @@ -0,0 +1,11 @@ +--- a/modules/metadata/mod_remoteip.c 2015/06/30 08:36:49 1688398 ++++ b/modules/metadata/mod_remoteip.c 2015/06/30 08:40:17 1688399 +@@ -255,7 +255,7 @@ + } + remote = apr_pstrdup(r->pool, remote); + +- temp_sa = c->client_addr; ++ temp_sa = r->useragent_addr ? r->useragent_addr : c->client_addr; + + while (remote) { + diff --git a/SOURCES/httpd-2.4.6-rewrite-dir.patch b/SOURCES/httpd-2.4.6-rewrite-dir.patch new file mode 100644 index 0000000..c29f0a6 --- /dev/null +++ b/SOURCES/httpd-2.4.6-rewrite-dir.patch @@ -0,0 +1,59 @@ +Index: modules/mappers/mod_rewrite.h +=================================================================== +--- a/modules/mappers/mod_rewrite.h (revision 1560696) ++++ b/modules/mappers/mod_rewrite.h (revision 1560697) +@@ -29,6 +29,8 @@ + #include "apr_optional.h" + #include "httpd.h" + ++#define REWRITE_REDIRECT_HANDLER_NAME "redirect-handler" ++ + /* rewrite map function prototype */ + typedef char *(rewrite_mapfunc_t)(request_rec *r, char *key); + +Index: modules/mappers/mod_dir.c +=================================================================== +--- a/modules/mappers/mod_dir.c (revision 1560696) ++++ b/modules/mappers/mod_dir.c (revision 1560697) +@@ -29,6 +29,7 @@ + #include "http_log.h" + #include "http_main.h" + #include "util_script.h" ++#include "mod_rewrite.h" + + module AP_MODULE_DECLARE_DATA dir_module; + +@@ -260,6 +261,11 @@ + return HTTP_MOVED_PERMANENTLY; + } + ++ /* we're running between mod_rewrites fixup and its internal redirect handler, step aside */ ++ if (!strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) { ++ return DECLINED; ++ } ++ + if (d->index_names) { + names_ptr = (char **)d->index_names->elts; + num_names = d->index_names->nelts; +Index: modules/mappers/mod_rewrite.c +=================================================================== +--- a/modules/mappers/mod_rewrite.c (revision 1560696) ++++ b/modules/mappers/mod_rewrite.c (revision 1560697) +@@ -5004,7 +5004,7 @@ + rewritelog((r, 1, dconf->directory, "internal redirect with %s " + "[INTERNAL REDIRECT]", r->filename)); + r->filename = apr_pstrcat(r->pool, "redirect:", r->filename, NULL); +- r->handler = "redirect-handler"; ++ r->handler = REWRITE_REDIRECT_HANDLER_NAME; + return OK; + } + } +@@ -5050,7 +5050,7 @@ + */ + static int handler_redirect(request_rec *r) + { +- if (strcmp(r->handler, "redirect-handler")) { ++ if (strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) { + return DECLINED; + } + diff --git a/SOURCES/httpd-2.4.6-ssl-error-free.patch b/SOURCES/httpd-2.4.6-ssl-error-free.patch new file mode 100644 index 0000000..6f268d2 --- /dev/null +++ b/SOURCES/httpd-2.4.6-ssl-error-free.patch @@ -0,0 +1,46 @@ +diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c +index 19d3ec7..926e05e 100644 +--- a/modules/ssl/mod_ssl.c ++++ b/modules/ssl/mod_ssl.c +@@ -295,9 +295,12 @@ static apr_status_t ssl_cleanup_pre_config(void *data) + #endif + ERR_remove_state(0); + +- /* Don't call ERR_free_strings here; ERR_load_*_strings only +- * actually load the error strings once per process due to static ++ /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only ++ * actually loaded the error strings once per process due to static + * variable abuse in OpenSSL. */ ++#if (OPENSSL_VERSION_NUMBER >= 0x00090805f) ++ ERR_free_strings(); ++#endif + + /* Also don't call CRYPTO_cleanup_all_ex_data here; any registered + * ex_data indices may have been cached in static variables in +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 8425acb..508991e 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -1065,7 +1065,7 @@ static void ssl_init_server_certs(server_rec *s, + const char *ecc_id; + EC_GROUP *ecparams; + int nid; +- EC_KEY *eckey; ++ EC_KEY *eckey = NULL; + #endif + const char *vhost_id = mctx->sc->vhost_id; + int i; +@@ -1151,10 +1151,11 @@ static void ssl_init_server_certs(server_rec *s, + #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)); ++ eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); + #endif + } ++ EC_KEY_free(eckey); + #endif + } + diff --git a/SOURCES/httpd-2.4.6-upn.patch b/SOURCES/httpd-2.4.6-upn.patch new file mode 100644 index 0000000..ce7f19c --- /dev/null +++ b/SOURCES/httpd-2.4.6-upn.patch @@ -0,0 +1,381 @@ +diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c +index 926e05e..bbe1d20 100644 +--- a/modules/ssl/mod_ssl.c ++++ b/modules/ssl/mod_ssl.c +@@ -333,6 +333,11 @@ static int ssl_hook_pre_config(apr_pool_t *pconf, + OpenSSL_add_all_algorithms(); + OPENSSL_load_builtin_modules(); + ++ if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) { ++ (void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV", ++ "SRVName otherName form"); ++ } ++ + /* + * Let us cleanup the ssl library when the module is unloaded + */ +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index eb11a38..27eaa5a 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -1156,6 +1156,7 @@ int ssl_hook_Fixup(request_rec *r) + /* standard SSL environment variables */ + if (dc->nOptions & SSL_OPT_STDENVVARS) { + modssl_var_extract_dns(env, sslconn->ssl, r->pool); ++ modssl_var_extract_san_entries(env, sslconn->ssl, r->pool); + + for (i = 0; ssl_hook_Fixup_vars[i]; i++) { + var = (char *)ssl_hook_Fixup_vars[i]; +diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c +index c508fff..2b7c9ba 100644 +--- a/modules/ssl/ssl_engine_vars.c ++++ b/modules/ssl/ssl_engine_vars.c +@@ -42,6 +42,7 @@ + static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, request_rec *r, char *var); + static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs, char *var); + static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var); ++static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var); + static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm); + static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *tm); + static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs); +@@ -509,6 +510,10 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs, + result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5); + resdup = FALSE; + } ++ else if (strlen(var) > 4 && strcEQn(var, "SAN_", 4)) { ++ result = ssl_var_lookup_ssl_cert_san(p, xs, var+4); ++ resdup = FALSE; ++ } + else if (strcEQ(var, "A_SIG")) { + nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm)); + result = apr_pstrdup(p, +@@ -597,6 +602,49 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char * + return result; + } + ++static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var) ++{ ++ int type, numlen; ++ const char *onf = NULL; ++ apr_array_header_t *entries; ++ ++ if (strcEQn(var, "Email_", 6)) { ++ type = GEN_EMAIL; ++ var += 6; ++ } ++ else if (strcEQn(var, "DNS_", 4)) { ++ type = GEN_DNS; ++ var += 4; ++ } ++ else if (strcEQn(var, "OTHER_", 6)) { ++ type = GEN_OTHERNAME; ++ var += 6; ++ if (strEQn(var, "msUPN_", 6)) { ++ var += 6; ++ onf = "msUPN"; ++ } ++ else if (strEQn(var, "dnsSRV_", 7)) { ++ var += 7; ++ onf = "id-on-dnsSRV"; ++ } ++ else ++ return NULL; ++ } ++ else ++ return NULL; ++ ++ /* sanity check: number must be between 1 and 4 digits */ ++ numlen = strspn(var, "0123456789"); ++ if ((numlen < 1) || (numlen > 4) || (numlen != strlen(var))) ++ return NULL; ++ ++ if (SSL_X509_getSAN(p, xs, type, onf, atoi(var), &entries)) ++ /* return the first entry from this 1-element array */ ++ return APR_ARRAY_IDX(entries, 0, char *); ++ else ++ return NULL; ++} ++ + static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm) + { + char *result; +@@ -890,6 +938,54 @@ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p) + } + } + ++static void extract_san_array(apr_table_t *t, const char *pfx, ++ apr_array_header_t *entries, apr_pool_t *p) ++{ ++ int i; ++ ++ for (i = 0; i < entries->nelts; i++) { ++ const char *key = apr_psprintf(p, "%s_%d", pfx, i); ++ apr_table_setn(t, key, APR_ARRAY_IDX(entries, i, const char *)); ++ } ++} ++ ++void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p) ++{ ++ X509 *xs; ++ apr_array_header_t *entries; ++ ++ /* subjectAltName entries of the server certificate */ ++ xs = SSL_get_certificate(ssl); ++ if (xs) { ++ if (SSL_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) { ++ extract_san_array(t, "SSL_SERVER_SAN_Email", entries, p); ++ } ++ if (SSL_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) { ++ extract_san_array(t, "SSL_SERVER_SAN_DNS", entries, p); ++ } ++ if (SSL_X509_getSAN(p, xs, GEN_OTHERNAME, "id-on-dnsSRV", -1, ++ &entries)) { ++ extract_san_array(t, "SSL_SERVER_SAN_OTHER_dnsSRV", entries, p); ++ } ++ /* no need to free xs (refcount does not increase) */ ++ } ++ ++ /* subjectAltName entries of the client certificate */ ++ xs = SSL_get_peer_certificate(ssl); ++ if (xs) { ++ if (SSL_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) { ++ extract_san_array(t, "SSL_CLIENT_SAN_Email", entries, p); ++ } ++ if (SSL_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) { ++ extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p); ++ } ++ if (SSL_X509_getSAN(p, xs, GEN_OTHERNAME, "msUPN", -1, &entries)) { ++ extract_san_array(t, "SSL_CLIENT_SAN_OTHER_msUPN", entries, p); ++ } ++ X509_free(xs); ++ } ++} ++ + /* For an extension type which OpenSSL does not recognize, attempt to + * parse the extension type as a primitive string. This will fail for + * any structured extension type per the docs. Returns non-zero on +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index a5ede6e..80e1e8e 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -974,6 +974,10 @@ void ssl_var_log_config_register(apr_pool_t *p); + * allocating from 'p': */ + void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p); + ++/* Extract SSL_*_SAN_* variables (subjectAltName entries) into table 't' ++ * from SSL object 'ssl', allocating from 'p'. */ ++void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p); ++ + #ifndef OPENSSL_NO_OCSP + /* Perform OCSP validation of the current cert in the given context. + * Returns non-zero on success or zero on failure. On failure, the +diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c +index 588ceba..09a9877 100644 +--- a/modules/ssl/ssl_util_ssl.c ++++ b/modules/ssl/ssl_util_ssl.c +@@ -236,22 +236,32 @@ BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen) + return TRUE; + } + +-/* convert a NAME_ENTRY to UTF8 string */ +-char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne) ++/* convert an ASN.1 string to a UTF-8 string (escaping control characters) */ ++char *SSL_ASN1_STRING_to_utf8(apr_pool_t *p, ASN1_STRING *asn1str) + { + char *result = NULL; +- BIO* bio; ++ BIO *bio; + int len; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return NULL; +- ASN1_STRING_print_ex(bio, X509_NAME_ENTRY_get_data(xsne), +- ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_UTF8_CONVERT); ++ ++ ASN1_STRING_print_ex(bio, asn1str, ASN1_STRFLGS_ESC_CTRL| ++ ASN1_STRFLGS_UTF8_CONVERT); + len = BIO_pending(bio); +- result = apr_palloc(p, len+1); +- len = BIO_read(bio, result, len); +- result[len] = NUL; ++ if (len > 0) { ++ result = apr_palloc(p, len+1); ++ len = BIO_read(bio, result, len); ++ result[len] = NUL; ++ } + BIO_free(bio); ++ return result; ++} ++ ++/* convert a NAME_ENTRY to UTF8 string */ ++char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne) ++{ ++ char *result = SSL_ASN1_STRING_to_utf8(p, X509_NAME_ENTRY_get_data(xsne)); + ap_xlate_proto_from_ascii(result, len); + return result; + } +@@ -288,51 +298,123 @@ char *SSL_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, int maxlen) + return result; + } + +-/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */ +-BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids) ++static void parse_otherName_value(apr_pool_t *p, ASN1_TYPE *value, ++ const char *onf, apr_array_header_t **entries) ++{ ++ const char *str; ++ int nid = onf ? OBJ_txt2nid(onf) : NID_undef; ++ ++ if (!value || (nid == NID_undef) || !*entries) ++ return; ++ ++ /* ++ * Currently supported otherName forms (values for "onf"): ++ * "msUPN" (1.3.6.1.4.1.311.20.2.3): Microsoft User Principal Name ++ * "id-on-dnsSRV" (1.3.6.1.5.5.7.8.7): SRVName, as specified in RFC 4985 ++ */ ++ if ((nid == NID_ms_upn) && (value->type == V_ASN1_UTF8STRING) && ++ (str = SSL_ASN1_STRING_to_utf8(p, value->value.utf8string))) { ++ APR_ARRAY_PUSH(*entries, const char *) = str; ++ } else if (strEQ(onf, "id-on-dnsSRV") && ++ (value->type == V_ASN1_IA5STRING) && ++ (str = SSL_ASN1_STRING_to_utf8(p, value->value.ia5string))) { ++ APR_ARRAY_PUSH(*entries, const char *) = str; ++ } ++} ++ ++/* ++ * Return an array of subjectAltName entries of type "type". If idx is -1, ++ * return all entries of the given type, otherwise return an array consisting ++ * of the n-th occurrence of that type only. Currently supported types: ++ * GEN_EMAIL (rfc822Name) ++ * GEN_DNS (dNSName) ++ * GEN_OTHERNAME (requires the otherName form ["onf"] argument to be supplied, ++ * see parse_otherName_value for the currently supported forms) ++ */ ++BOOL SSL_X509_getSAN(apr_pool_t *p, X509 *x509, int type, const char *onf, ++ int idx, apr_array_header_t **entries) + { + STACK_OF(GENERAL_NAME) *names; +- BIO *bio; +- X509_NAME *subj; +- char **cpp; +- int i, n; ++ int nid = onf ? OBJ_txt2nid(onf) : NID_undef; + +- if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) { +- *ids = NULL; ++ if (!x509 || (type < GEN_OTHERNAME) || ++ ((type == GEN_OTHERNAME) && (nid == NID_undef)) || ++ (type > GEN_RID) || (idx < -1) || ++ !(*entries = apr_array_make(p, 0, sizeof(char *)))) { ++ *entries = NULL; + return FALSE; + } + +- /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */ +- if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) && +- (bio = BIO_new(BIO_s_mem()))) { ++ if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL))) { ++ int i, n = 0; + GENERAL_NAME *name; ++ const char *utf8str; + + for (i = 0; i < sk_GENERAL_NAME_num(names); i++) { + name = sk_GENERAL_NAME_value(names, i); +- if (name->type == GEN_DNS) { +- ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL| +- ASN1_STRFLGS_UTF8_CONVERT); +- n = BIO_pending(bio); +- if (n > 0) { +- cpp = (char **)apr_array_push(*ids); +- *cpp = apr_palloc(p, n+1); +- n = BIO_read(bio, *cpp, n); +- (*cpp)[n] = NUL; ++ ++ if (name->type != type) ++ continue; ++ ++ switch (type) { ++ case GEN_EMAIL: ++ case GEN_DNS: ++ if (((idx == -1) || (n == idx)) && ++ (utf8str = SSL_ASN1_STRING_to_utf8(p, name->d.ia5))) { ++ APR_ARRAY_PUSH(*entries, const char *) = utf8str; ++ } ++ n++; ++ break; ++ case GEN_OTHERNAME: ++ if (OBJ_obj2nid(name->d.otherName->type_id) == nid) { ++ if (((idx == -1) || (n == idx))) { ++ parse_otherName_value(p, name->d.otherName->value, ++ onf, entries); ++ } ++ n++; + } ++ break; ++ default: ++ /* ++ * Not implemented right now: ++ * GEN_X400 (x400Address) ++ * GEN_DIRNAME (directoryName) ++ * GEN_EDIPARTY (ediPartyName) ++ * GEN_URI (uniformResourceIdentifier) ++ * GEN_IPADD (iPAddress) ++ * GEN_RID (registeredID) ++ */ ++ break; + } ++ ++ if ((idx != -1) && (n > idx)) ++ break; + } +- BIO_free(bio); +- } + +- if (names) + sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); ++ } ++ ++ return apr_is_empty_array(*entries) ? FALSE : TRUE; ++} ++ ++/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */ ++BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids) ++{ ++ X509_NAME *subj; ++ int i = -1; ++ ++ /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */ ++ if (!x509 || ++ (SSL_X509_getSAN(p, x509, GEN_DNS, NULL, -1, ids) == FALSE && !*ids)) { ++ *ids = NULL; ++ return FALSE; ++ } + + /* Second, the CN-IDs (commonName attributes in the subject DN) */ + subj = X509_get_subject_name(x509); +- i = -1; + while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) { +- cpp = (char **)apr_array_push(*ids); +- *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i)); ++ APR_ARRAY_PUSH(*ids, const char *) = ++ SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i)); + } + + return apr_is_empty_array(*ids) ? FALSE : TRUE; +diff --git a/modules/ssl/ssl_util_ssl.h b/modules/ssl/ssl_util_ssl.h +index 4b882db..be07ab7 100644 +--- a/modules/ssl/ssl_util_ssl.h ++++ b/modules/ssl/ssl_util_ssl.h +@@ -65,8 +65,10 @@ EVP_PKEY *SSL_read_PrivateKey(char *, EVP_PKEY **, pem_password_cb *, void *); + int SSL_smart_shutdown(SSL *ssl); + BOOL SSL_X509_isSGC(X509 *); + BOOL SSL_X509_getBC(X509 *, int *, int *); ++char *SSL_ASN1_STRING_to_utf8(apr_pool_t *, ASN1_STRING *); + char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne); + char *SSL_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int); ++BOOL SSL_X509_getSAN(apr_pool_t *, X509 *, int, const char *, int, apr_array_header_t **); + BOOL SSL_X509_getIDs(apr_pool_t *, X509 *, apr_array_header_t **); + BOOL SSL_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *); + BOOL SSL_X509_INFO_load_file(apr_pool_t *, STACK_OF(X509_INFO) *, const char *); diff --git a/SOURCES/httpd.service b/SOURCES/httpd.service index 8014874..e5538ee 100644 --- a/SOURCES/httpd.service +++ b/SOURCES/httpd.service @@ -1,6 +1,8 @@ [Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target +Documentation=man:httpd(8) +Documentation=man:apachectl(8) [Service] Type=notify diff --git a/SOURCES/ssl.conf b/SOURCES/ssl.conf index ff60307..58eaf3b 100644 --- a/SOURCES/ssl.conf +++ b/SOURCES/ssl.conf @@ -77,7 +77,7 @@ SSLProtocol all -SSLv2 # SSL Cipher Suite: # List the ciphers that the client is permitted to negotiate. # See the mod_ssl documentation for a complete list. -SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 +SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA # Speed-optimized SSL Cipher configuration: # If speed is your main concern (on busy HTTPS servers e.g.), 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 c3d480c..ce4961b 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: 31%{?dist}.1 +Release: 40%{?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 @@ -69,6 +69,7 @@ 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 +Patch38: httpd-2.4.6-upn.patch # Bug fixes Patch51: httpd-2.4.3-sslsninotreq.patch Patch55: httpd-2.4.4-malformed-host.patch @@ -84,6 +85,31 @@ 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 +Patch68: httpd-2.4.6-r1663647.patch +Patch69: httpd-2.4.6-r1569006.patch +Patch70: httpd-2.4.6-r1506474.patch +Patch71: httpd-2.4.6-bomb.patch +Patch72: httpd-2.4.6-r1604460.patch +Patch73: httpd-2.4.6-r1624349.patch +Patch74: httpd-2.4.6-ap-ipv6.patch +Patch75: httpd-2.4.6-r1530280.patch +Patch76: httpd-2.4.6-r1633085.patch +Patch78: httpd-2.4.6-ssl-error-free.patch +Patch79: httpd-2.4.6-r1528556.patch +Patch80: httpd-2.4.6-r1594625.patch +Patch81: httpd-2.4.6-r1674222.patch +Patch82: httpd-2.4.6-apachectl-httpd-env.patch +Patch83: httpd-2.4.6-rewrite-dir.patch +Patch84: httpd-2.4.6-r1420184.patch +Patch85: httpd-2.4.6-r1524368.patch +Patch86: httpd-2.4.6-r1528958.patch +Patch87: httpd-2.4.6-r1651083.patch +Patch88: httpd-2.4.6-r1688399.patch +Patch89: httpd-2.4.6-r1527509.patch +Patch90: httpd-2.4.6-apachectl-status.patch +Patch91: httpd-2.4.6-r1650655.patch +Patch92: httpd-2.4.6-r1533448.patch +Patch93: httpd-2.4.6-r1610013.patch # Security fixes Patch200: httpd-2.4.6-CVE-2013-6438.patch Patch201: httpd-2.4.6-CVE-2014-0098.patch @@ -158,7 +184,7 @@ the Apache HTTP Server. Group: System Environment/Daemons Summary: SSL/TLS module for the Apache HTTP Server Epoch: 1 -BuildRequires: openssl-devel +BuildRequires: openssl-devel >= 1:1.0.1e-37 Requires: openssl-libs >= 1:1.0.1e-37 Requires(post): openssl, /bin/cat Requires(pre): httpd @@ -226,6 +252,7 @@ rm modules/ssl/ssl_engine_dh.c %patch35 -p1 -b .prehtaccess %patch36 -p1 -b .r1573626 %patch37 -p1 -b .uds +%patch38 -p1 -b .upn %patch51 -p1 -b .sninotreq %patch55 -p1 -b .malformedhost @@ -241,6 +268,31 @@ rm modules/ssl/ssl_engine_dh.c %patch65 -p1 -b .r1556818 %patch66 -p1 -b .r1618851 %patch67 -p1 -b .r1526189 +%patch68 -p1 -b .r1663647 +%patch69 -p1 -b .1569006 +%patch70 -p1 -b .r1506474 +%patch71 -p1 -b .bomb +%patch72 -p1 -b .r1604460 +%patch73 -p1 -b .r1624349 +%patch74 -p1 -b .abipv6 +%patch75 -p1 -b .r1530280 +%patch76 -p1 -b .r1633085 +%patch78 -p1 -b .sslerrorfree +%patch79 -p1 -b .r1528556 +%patch80 -p1 -b .r1594625 +%patch81 -p1 -b .r1674222 +%patch82 -p1 -b .envhttpd +%patch83 -p1 -b .rewritedir +%patch84 -p1 -b .r1420184 +%patch85 -p1 -b .r1524368 +%patch86 -p1 -b .r1528958 +%patch87 -p1 -b .r1651083 +%patch88 -p1 -b .r1688399 +%patch89 -p1 -b .r1527509 +%patch90 -p1 -b .apachectlstatus +%patch91 -p1 -b .r1650655 +%patch92 -p1 -b .r1533448 +%patch93 -p1 -b .r1610013 %patch200 -p1 -b .cve6438 %patch201 -p1 -b .cve0098 @@ -406,10 +458,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 @@ -432,7 +482,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 @@ -617,7 +667,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 @@ -683,17 +733,63 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/rpm/macros.httpd %changelog -* Mon Aug 24 2015 CentOS Sources - 2.4.6-31.el7.centos.1 -- Remove index.html, add centos-noindex.tar.gz -- change vstring -- change symlink for poweredby.png -- update welcome.conf with proper aliases +* Thu Sep 17 2015 Jan Kaluza - 2.4.6-40 +- mod_dav: follow up fix for previous commit (#1263975) + +* Wed Aug 26 2015 Jan Kaluza - 2.4.6-39 +- mod_dav: treat dav_resource uri as escaped (#1255480) -* Mon Aug 10 2015 Jan Kaluza - 2.4.6-31.1 +* Wed Aug 19 2015 Jan Kaluza - 2.4.6-38 +- mod_ssl: add support for User Principal Name in SSLUserName (#1242503) + +* Mon Aug 10 2015 Jan Kaluza - 2.4.6-37 - 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) +* Tue Jul 14 2015 Jan Kaluza - 2.4.6-36 +- Revert fix for #1162152, it is not needed in RHEL7 +- mod_proxy_ajp: fix settings ProxyPass parameters for AJP backends (#1242416) + +* Wed Jul 01 2015 Jan Kaluza - 2.4.6-35 +- mod_remoteip: correct the trusted proxy match test (#1179306) +- mod_dav: send complete response when resource is created (#1235383) +- apachectl: correct the apachectl status man page (#1231924) + +* Wed Jun 03 2015 Jan Kaluza - 2.4.6-34 +- mod_proxy_fcgi: honor Timeout / ProxyTimeout (#1222328) +- do not show all vhosts twice in httpd -D DUMP_VHOSTS output (#1225820) +- fix -D[efined] or [d] variables lifetime accross restarts (#1227219) +- mod_ssl: do not send NPN extension with not configured (#1226015) + +* Mon May 18 2015 Jan Kaluza - 2.4.6-33 +- mod_authz_dbm: fix crash when using "Require dbm-file-group" (#1221575) + +* Wed Apr 15 2015 Jan Kaluza - 2.4.6-32 +- mod_authn_dbd: fix use-after-free bug with postgresql (#1188779) +- mod_remoteip: correct the trusted proxy match test (#1179306) +- mod_status: honor remote_ip as documented (#1169081) +- mod_deflate: fix decompression of files larger than 4GB (#1170214) +- core: improve error message for inaccessible DocumentRoot (#1170220) +- ab: try all addresses instead of failing on first one when not available (#1125276) +- mod_proxy_wstunnel: add support for SSL (#1180745) +- mod_proxy_wstunnel: load this module by default (#1180745) +- mod_rewrite: add support for WebSockets (#1180745) +- mod_rewrite: do not search for directory if a URL will be rewritten (#1210091) +- mod_ssl: Fix SSL_CLIENT_VERIFY value when optional_no_ca and SSLSessionCache + are used and SSL session is resumed (#1170206) +- mod_ssl: fix memory leak on httpd reloads (#1181690) +- mod_ssl: use SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA (#1118476) +- mod_cgi: return error code 408 on timeout (#1162152) +- mod_dav_fs: set default value of DAVLockDB (#1176449) +- add Documentation= to the httpd.service and htcacheclean.service (#1184118) +- do not display "bomb" icon for files ending with "core" (#1170215) +- add missing Reason-Phrase in HTTP response headers (#1162159) +- fix BuildRequires to require openssl-devel >= 1:1.0.1e-37 (#1160625) +- apachectl: ignore HTTPD variable from sysconfig (#1214401) +- apachectl: fix "graceful" documentation (#1214398) +- apachectl: fix "graceful" behaviour when httpd is not running (#1214430) + * 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 (#1168050)