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-2019-0217.patch b/SOURCES/httpd-2.4.6-CVE-2019-0217.patch new file mode 100644 index 0000000..69702a1 --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2019-0217.patch @@ -0,0 +1,113 @@ +diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c +index b50bcf9..5bfec82 100644 +--- a/modules/aaa/mod_auth_digest.c ++++ b/modules/aaa/mod_auth_digest.c +@@ -92,7 +92,6 @@ typedef struct digest_config_struct { + int check_nc; + const char *algorithm; + char *uri_list; +- const char *ha1; + } digest_config_rec; + + +@@ -153,6 +152,7 @@ typedef struct digest_header_struct { + apr_time_t nonce_time; + enum hdr_sts auth_hdr_sts; + int needed_auth; ++ const char *ha1; + client_entry *client; + } digest_header_rec; + +@@ -1295,7 +1295,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type) + */ + + static authn_status get_hash(request_rec *r, const char *user, +- digest_config_rec *conf) ++ digest_config_rec *conf, const char **rethash) + { + authn_status auth_result; + char *password; +@@ -1347,7 +1347,7 @@ static authn_status get_hash(request_rec *r, const char *user, + } while (current_provider); + + if (auth_result == AUTH_USER_FOUND) { +- conf->ha1 = password; ++ *rethash = password; + } + + return auth_result; +@@ -1474,25 +1474,24 @@ static int check_nonce(request_rec *r, digest_header_rec *resp, + + /* RFC-2069 */ + static const char *old_digest(const request_rec *r, +- const digest_header_rec *resp, const char *ha1) ++ const digest_header_rec *resp) + { + const char *ha2; + + ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":", + resp->uri, NULL)); + return ap_md5(r->pool, +- (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, +- ":", ha2, NULL)); ++ (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":", ++ resp->nonce, ":", ha2, NULL)); + } + + /* RFC-2617 */ + static const char *new_digest(const request_rec *r, +- digest_header_rec *resp, +- const digest_config_rec *conf) ++ digest_header_rec *resp) + { + const char *ha1, *ha2, *a2; + +- ha1 = conf->ha1; ++ ha1 = resp->ha1; + + a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); + ha2 = ap_md5(r->pool, (const unsigned char *)a2); +@@ -1505,7 +1504,6 @@ static const char *new_digest(const request_rec *r, + NULL)); + } + +- + static void copy_uri_components(apr_uri_t *dst, + apr_uri_t *src, request_rec *r) { + if (src->scheme && src->scheme[0] != '\0') { +@@ -1742,7 +1740,7 @@ static int authenticate_digest_user(request_rec *r) + return HTTP_UNAUTHORIZED; + } + +- return_code = get_hash(r, r->user, conf); ++ return_code = get_hash(r, r->user, conf, &resp->ha1); + + if (return_code == AUTH_USER_NOT_FOUND) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790) +@@ -1772,7 +1770,7 @@ static int authenticate_digest_user(request_rec *r) + + if (resp->message_qop == NULL) { + /* old (rfc-2069) style digest */ +- if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) { ++ if (strcmp(resp->digest, old_digest(r, resp))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792) + "user %s: password mismatch: %s", r->user, + r->uri); +@@ -1802,7 +1800,7 @@ static int authenticate_digest_user(request_rec *r) + return HTTP_UNAUTHORIZED; + } + +- exp_digest = new_digest(r, resp, conf); ++ exp_digest = new_digest(r, resp); + if (!exp_digest) { + /* we failed to allocate a client struct */ + return HTTP_INTERNAL_SERVER_ERROR; +@@ -1886,7 +1884,7 @@ static int add_auth_info(request_rec *r) + + /* calculate rspauth attribute + */ +- ha1 = conf->ha1; ++ ha1 = resp->ha1; + + a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); + ha2 = ap_md5(r->pool, (const unsigned char *)a2); diff --git a/SOURCES/httpd-2.4.6-CVE-2019-0220.patch b/SOURCES/httpd-2.4.6-CVE-2019-0220.patch new file mode 100644 index 0000000..94a76ee --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2019-0220.patch @@ -0,0 +1,244 @@ +diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en +index 86d9bee..e08034b 100644 +--- a/docs/manual/mod/core.html.en ++++ b/docs/manual/mod/core.html.en +@@ -90,6 +90,7 @@ available +
Description: | Controls whether the server merges consecutive slashes in URLs. |
---|---|
Syntax: | MergeSlashes ON | OFF |
Default: | MergeSlashes ON |
Context: | server config, virtual host |
Status: | Core |
Module: | core |
Compatibility: | Available in Apache HTTP Server 2.4.6 in Red Hat Enterprise Linux 7 |
By default, the server merges (or collapses) multiple consecutive slash ++ ('/') characters in the path component of the request URL.
++ ++When mapping URL's to the filesystem, these multiple slashes are not
++ significant. However, URL's handled other ways, such as by CGI or proxy,
++ might prefer to retain the significance of multiple consecutive slashes.
++ In these cases MergeSlashes
can be set to
++ OFF to retain the multiple consecutive slashes. In these
++ configurations, regular expressions used in the configuration file that match
++ the path component of the URL (LocationMatch
,
++ RewriteRule
, ...) need to take into account multiple
++ consecutive slashes.
Description: | Configures mutex mechanism and lock file directory for all
+diff --git a/include/http_core.h b/include/http_core.h
+index c05d06e..76bf5a4 100644
+--- a/include/http_core.h
++++ b/include/http_core.h
+@@ -465,6 +465,17 @@ typedef unsigned long etag_components_t;
+ /* This is the default value used */
+ #define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE)
+
++/* Generic ON/OFF/UNSET for unsigned int foo :2 */
++#define AP_CORE_CONFIG_OFF (0)
++#define AP_CORE_CONFIG_ON (1)
++#define AP_CORE_CONFIG_UNSET (2)
++
++/* Generic merge of flag */
++#define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \
++ over->field != AP_CORE_CONFIG_UNSET \
++ ? over->field \
++ : base->field
++
+ /**
+ * @brief Server Signature Enumeration
+ */
+@@ -682,7 +693,7 @@ typedef struct {
+ #define AP_HTTP_METHODS_LENIENT 1
+ #define AP_HTTP_METHODS_REGISTERED 2
+ char http_methods;
+-
++ unsigned int merge_slashes;
+ } core_server_config;
+
+ /* for AddOutputFiltersByType in core.c */
+diff --git a/include/httpd.h b/include/httpd.h
+index 176ef5e..a552358 100644
+--- a/include/httpd.h
++++ b/include/httpd.h
+@@ -1622,11 +1622,21 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes);
+ AP_DECLARE(int) ap_unescape_urlencoded(char *query);
+
+ /**
+- * Convert all double slashes to single slashes
+- * @param name The string to convert
++ * Convert all double slashes to single slashes, except where significant
++ * to the filesystem on the current platform.
++ * @param name The string to convert, assumed to be a filesystem path
+ */
+ AP_DECLARE(void) ap_no2slash(char *name);
+
++/**
++ * Convert all double slashes to single slashes, except where significant
++ * to the filesystem on the current platform.
++ * @param name The string to convert
++ * @param is_fs_path if set to 0, the significance of any double-slashes is
++ * ignored.
++ */
++AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path);
++
+ /**
+ * Remove all ./ and xx/../ substrings from a file name. Also remove
+ * any leading ../ or /../ substrings.
+diff --git a/server/core.c b/server/core.c
+index 0e69f8c..67efd7e 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -476,6 +476,7 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s)
+ */
+
+ conf->trace_enable = AP_TRACE_UNSET;
++ conf->merge_slashes = AP_CORE_CONFIG_UNSET;
+
+ return (void *)conf;
+ }
+@@ -536,6 +537,8 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
+ ? virt->merge_trailers
+ : base->merge_trailers;
+
++ AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt);
++
+ return conf;
+ }
+
+@@ -1673,6 +1676,13 @@ static const char *set_override(cmd_parms *cmd, void *d_, const char *l)
+ return NULL;
+ }
+
++static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag)
++{
++ core_server_config *conf =
++ ap_get_core_module_config(cmd->server->module_config);
++ return ap_set_flag_slot(cmd, conf, flag);
++}
++
+ static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
+ {
+ core_dir_config *d = d_;
+@@ -4216,6 +4226,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CON
+ ,
+ AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
+ "Registers non-standard HTTP methods"),
++AP_INIT_FLAG("MergeSlashes", set_core_server_flag,
++ (void *)APR_OFFSETOF(core_server_config, merge_slashes),
++ RSRC_CONF,
++ "Controls whether consecutive slashes in the URI path are merged"),
+ { NULL }
+ };
+
+diff --git a/server/request.c b/server/request.c
+index 4eef097..cba3891 100644
+--- a/server/request.c
++++ b/server/request.c
+@@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
+ int file_req = (r->main && r->filename);
+ int access_status;
+ core_dir_config *d;
++ core_server_config *sconf =
++ ap_get_core_module_config(r->server->module_config);
+
+ /* Ignore embedded %2F's in path for proxy requests */
+ if (!r->proxyreq && r->parsed_uri.path) {
+@@ -191,6 +193,12 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
+ }
+
+ ap_getparents(r->uri); /* OK --- shrinking transformations... */
++ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
++ ap_no2slash(r->uri);
++ if (r->parsed_uri.path) {
++ ap_no2slash(r->parsed_uri.path);
++ }
++ }
+
+ /* All file subrequests are a huge pain... they cannot bubble through the
+ * next several steps. Only file subrequests are allowed an empty uri,
+@@ -1383,20 +1391,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
+
+ cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
+ cached = (cache->cached != NULL);
+-
+- /* Location and LocationMatch differ on their behaviour w.r.t. multiple
+- * slashes. Location matches multiple slashes with a single slash,
+- * LocationMatch doesn't. An exception, for backwards brokenness is
+- * absoluteURIs... in which case neither match multiple slashes.
+- */
+- if (r->uri[0] != '/') {
+- entry_uri = r->uri;
+- }
+- else {
+- char *uri = apr_pstrdup(r->pool, r->uri);
+- ap_no2slash(uri);
+- entry_uri = uri;
+- }
++ entry_uri = r->uri;
+
+ /* If we have an cache->cached location that matches r->uri,
+ * and the vhost's list of locations hasn't changed, we can skip
+@@ -1449,7 +1444,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
+ * terminated (or at the end of the string) to match.
+ */
+ if (entry_core->r
+- ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0)
++ ? ap_regexec(entry_core->r, entry_uri, 0, NULL, 0)
+ : (entry_core->d_is_fnmatch
+ ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
+ : (strncmp(entry_core->d, cache->cached, len)
+diff --git a/server/util.c b/server/util.c
+index f9e3b51..4eac462 100644
+--- a/server/util.c
++++ b/server/util.c
+@@ -561,16 +561,20 @@ AP_DECLARE(void) ap_getparents(char *name)
+ name[l] = '\0';
+ }
+ }
+-
+-AP_DECLARE(void) ap_no2slash(char *name)
++AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
+ {
++
+ char *d, *s;
+
++ if (!*name) {
++ return;
++ }
++
+ s = d = name;
+
+ #ifdef HAVE_UNC_PATHS
+ /* Check for UNC names. Leave leading two slashes. */
+- if (s[0] == '/' && s[1] == '/')
++ if (is_fs_path && s[0] == '/' && s[1] == '/')
+ *d++ = *s++;
+ #endif
+
+@@ -587,6 +591,10 @@ AP_DECLARE(void) ap_no2slash(char *name)
+ *d = '\0';
+ }
+
++AP_DECLARE(void) ap_no2slash(char *name)
++{
++ ap_no2slash_ex(name, 1);
++}
+
+ /*
+ * copy at most n leading directories of s into d
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 5c951a2..b7e573b 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: 89%{?dist}.1
+Release: 90%{?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
@@ -215,6 +215,8 @@ Patch218: httpd-2.4.6-CVE-2017-7679.patch
Patch219: httpd-2.4.6-CVE-2017-9788.patch
Patch220: httpd-2.4.6-CVE-2017-9798.patch
Patch221: httpd-2.4.6-CVE-2018-1312.patch
+Patch222: httpd-2.4.6-CVE-2019-0217.patch
+Patch223: httpd-2.4.6-CVE-2019-0220.patch
License: ASL 2.0
Group: System Environment/Daemons
@@ -460,6 +462,8 @@ rm modules/ssl/ssl_engine_dh.c
%patch219 -p1 -b .cve9788
%patch220 -p1 -b .cve9798
%patch221 -p1 -b .cve1312
+%patch222 -p1 -b .cve0217
+%patch223 -p1 -b .cve0220
# Patch in the vendor string and the release string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@@ -613,10 +617,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
@@ -639,7 +641,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
@@ -825,7 +827,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
@@ -891,15 +893,12 @@ rm -rf $RPM_BUILD_ROOT
%{_sysconfdir}/rpm/macros.httpd
%changelog
-* Mon Jul 29 2019 CentOS Sources |
---|