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-2017-15710.patch b/SOURCES/httpd-2.4.6-CVE-2017-15710.patch new file mode 100644 index 0000000..d8f02c9 --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2017-15710.patch @@ -0,0 +1,19 @@ +--- a/modules/aaa/mod_authnz_ldap.c 2018/02/15 17:33:04 1824335 ++++ b/modules/aaa/mod_authnz_ldap.c 2018/02/15 17:42:14 1824336 +@@ -126,9 +126,13 @@ + + charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING); + +- if (!charset) { +- language[2] = '\0'; +- charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING); ++ /* ++ * Test if language values like 'en-US' return a match from the charset ++ * conversion map when shortened to 'en'. ++ */ ++ if (!charset && strlen(language) > 3 && language[2] == '-') { ++ char *language_short = apr_pstrndup(p, language, 2); ++ charset = (char*) apr_hash_get(charset_conversions, language_short, APR_HASH_KEY_STRING); + } + + if (charset) { diff --git a/SOURCES/httpd-2.4.6-CVE-2018-1301.patch b/SOURCES/httpd-2.4.6-CVE-2018-1301.patch new file mode 100644 index 0000000..e03a444 --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2018-1301.patch @@ -0,0 +1,198 @@ +diff --git a/server/protocol.c b/server/protocol.c +index 9e23325..8428129 100644 +--- a/server/protocol.c ++++ b/server/protocol.c +@@ -222,6 +222,12 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + int fold = flags & AP_GETLINE_FOLD; + int crlf = flags & AP_GETLINE_CRLF; + ++ if (!n) { ++ /* Needs room for NUL byte at least */ ++ *read = 0; ++ return APR_BADARG; ++ } ++ + /* + * Initialize last_char as otherwise a random value will be compared + * against APR_ASCII_LF at the end of the loop if bb only contains +@@ -235,14 +241,15 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0); + if (rv != APR_SUCCESS) { +- return rv; ++ goto cleanup; + } + + /* Something horribly wrong happened. Someone didn't block! + * (this also happens at the end of each keepalive connection) + */ + if (APR_BRIGADE_EMPTY(bb)) { +- return APR_EGENERAL; ++ rv = APR_EGENERAL; ++ goto cleanup; + } + + for (e = APR_BRIGADE_FIRST(bb); +@@ -260,7 +267,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + + rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { +- return rv; ++ goto cleanup; + } + + if (len == 0) { +@@ -273,17 +280,8 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + + /* Would this overrun our buffer? If so, we'll die. */ + if (n < bytes_handled + len) { +- *read = bytes_handled; +- if (*s) { +- /* ensure this string is NUL terminated */ +- if (bytes_handled > 0) { +- (*s)[bytes_handled-1] = '\0'; +- } +- else { +- (*s)[0] = '\0'; +- } +- } +- return APR_ENOSPC; ++ rv = APR_ENOSPC; ++ goto cleanup; + } + + /* Do we have to handle the allocation ourselves? */ +@@ -291,7 +289,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + /* We'll assume the common case where one bucket is enough. */ + if (!*s) { + current_alloc = len; +- *s = apr_palloc(r->pool, current_alloc); ++ *s = apr_palloc(r->pool, current_alloc + 1); + } + else if (bytes_handled + len > current_alloc) { + /* Increase the buffer size */ +@@ -302,7 +300,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + new_size = (bytes_handled + len) * 2; + } + +- new_buffer = apr_palloc(r->pool, new_size); ++ new_buffer = apr_palloc(r->pool, new_size + 1); + + /* Copy what we already had. */ + memcpy(new_buffer, *s, bytes_handled); +@@ -326,19 +324,15 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + } + } + +- if (crlf && (last_char <= *s || last_char[-1] != APR_ASCII_CR)) { +- *last_char = '\0'; +- bytes_handled = last_char - *s; +- *read = bytes_handled; +- return APR_EINVAL; +- } +- +- /* Now NUL-terminate the string at the end of the line; ++ /* Now terminate the string at the end of the line; + * if the last-but-one character is a CR, terminate there */ + if (last_char > *s && last_char[-1] == APR_ASCII_CR) { + last_char--; + } +- *last_char = '\0'; ++ else if (crlf) { ++ rv = APR_EINVAL; ++ goto cleanup; ++ } + bytes_handled = last_char - *s; + + /* If we're folding, we have more work to do. +@@ -358,7 +352,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_SPECULATIVE, + APR_BLOCK_READ, 1); + if (rv != APR_SUCCESS) { +- return rv; ++ goto cleanup; + } + + if (APR_BRIGADE_EMPTY(bb)) { +@@ -375,7 +369,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + apr_brigade_cleanup(bb); +- return rv; ++ goto cleanup; + } + + /* Found one, so call ourselves again to get the next line. +@@ -392,10 +386,8 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) { + /* Do we have enough space? We may be full now. */ + if (bytes_handled >= n) { +- *read = n; +- /* ensure this string is terminated */ +- (*s)[n-1] = '\0'; +- return APR_ENOSPC; ++ rv = APR_ENOSPC; ++ goto cleanup; + } + else { + apr_size_t next_size, next_len; +@@ -408,7 +400,6 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + tmp = NULL; + } + else { +- /* We're null terminated. */ + tmp = last_char; + } + +@@ -417,7 +408,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + rv = ap_rgetline_core(&tmp, next_size, + &next_len, r, 0, bb); + if (rv != APR_SUCCESS) { +- return rv; ++ goto cleanup; + } + + if (do_alloc && next_len > 0) { +@@ -431,7 +422,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + memcpy(new_buffer, *s, bytes_handled); + + /* copy the new line, including the trailing null */ +- memcpy(new_buffer + bytes_handled, tmp, next_len + 1); ++ memcpy(new_buffer + bytes_handled, tmp, next_len); + *s = new_buffer; + } + +@@ -444,8 +435,21 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + } + } + } ++ ++cleanup: ++ if (bytes_handled >= n) { ++ bytes_handled = n - 1; ++ } ++ if (*s) { ++ /* ensure the string is NUL terminated */ ++ (*s)[bytes_handled] = '\0'; ++ } + *read = bytes_handled; + ++ if (rv != APR_SUCCESS) { ++ return rv; ++ } ++ + /* PR#43039: We shouldn't accept NULL bytes within the line */ + if (strlen(*s) < bytes_handled) { + return APR_EINVAL; +@@ -484,6 +488,11 @@ AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags) + apr_size_t len; + apr_bucket_brigade *tmp_bb; + ++ if (n < 1) { ++ /* Can't work since we always NUL terminate */ ++ return -1; ++ } ++ + tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + rv = ap_rgetline(&tmp_s, n, &len, r, flags, tmp_bb); + apr_brigade_destroy(tmp_bb); diff --git a/SOURCES/httpd-2.4.6-CVE-2018-17199.patch b/SOURCES/httpd-2.4.6-CVE-2018-17199.patch new file mode 100644 index 0000000..70bfea2 --- /dev/null +++ b/SOURCES/httpd-2.4.6-CVE-2018-17199.patch @@ -0,0 +1,46 @@ +diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c +index 7213eb3..3e73c7a 100644 +--- a/modules/session/mod_session.c ++++ b/modules/session/mod_session.c +@@ -126,15 +126,9 @@ static apr_status_t ap_session_load(request_rec * r, session_rec ** z) + + /* found a session that hasn't expired? */ + now = apr_time_now(); +- if (!zz || (zz->expiry && zz->expiry < now)) { +- +- /* no luck, create a blank session */ +- zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec)); +- zz->pool = r->pool; +- zz->entries = apr_table_make(zz->pool, 10); +- +- } +- else { ++ ++ if (zz){ ++ /* load the session attibutes */ + rv = ap_run_session_decode(r, zz); + if (OK != rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817) +@@ -142,8 +136,22 @@ static apr_status_t ap_session_load(request_rec * r, session_rec ** z) + "session not loaded: %s", r->uri); + return rv; + } ++ ++ /* invalidate session if session is expired */ ++ if (zz && zz->expiry && zz->expiry < now){ ++ zz = NULL; ++ } + } + ++ if (!zz || (zz->expiry && zz->expiry < now)) { ++ ++ /* no luck, create a blank session */ ++ zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec)); ++ zz->pool = r->pool; ++ zz->entries = apr_table_make(zz->pool, 10); ++ ++ } ++ + /* make sure the expiry is set, if present */ + if (!zz->expiry && dconf->maxage) { + zz->expiry = now + dconf->maxage * APR_USEC_PER_SEC; diff --git a/SOURCES/httpd-2.4.6-r1583175.patch b/SOURCES/httpd-2.4.6-r1583175.patch new file mode 100644 index 0000000..4270a4c --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1583175.patch @@ -0,0 +1,19 @@ +--- a/modules/mappers/mod_alias.c 2014/03/30 18:15:25 1583174 ++++ b/modules/mappers/mod_alias.c 2014/03/30 18:20:09 1583175 +@@ -371,15 +371,11 @@ + } + } + else { +- int pathlen = strlen(found) - +- (strlen(r->uri + regm[0].rm_eo)); +- AP_DEBUG_ASSERT(pathlen >= 0); +- AP_DEBUG_ASSERT(pathlen <= strlen(found)); + ap_set_context_info(r, + apr_pstrmemdup(r->pool, r->uri, + regm[0].rm_eo), + apr_pstrmemdup(r->pool, found, +- pathlen)); ++ strlen(found))); + } + } + else { diff --git a/SOURCES/httpd-2.4.6-r1826995.patch b/SOURCES/httpd-2.4.6-r1826995.patch index abbcb33..c179178 100644 --- a/SOURCES/httpd-2.4.6-r1826995.patch +++ b/SOURCES/httpd-2.4.6-r1826995.patch @@ -132,8 +132,8 @@ index 5ff35f5..9dc236c 100644 * Perform OCSP-based revocation checks */ - if (ok && sc->server->ocsp_enabled) { -+ if (ok && ((sc->server->ocsp_mask & SSL_OCSPCHECK_CHAIN) || -+ (errdepth == 0 && (sc->server->ocsp_mask & SSL_OCSPCHECK_LEAF)))) { ++ if (ok && ((mctx->ocsp_mask & SSL_OCSPCHECK_CHAIN) || ++ (errdepth == 0 && (mctx->ocsp_mask & SSL_OCSPCHECK_LEAF)))) { /* If there was an optional verification error, it's not * possible to perform OCSP validation since the issuer may be * missing/untrusted. Fail in that case. */ diff --git a/SOURCES/httpd-2.4.6-r1861793+.patch b/SOURCES/httpd-2.4.6-r1861793+.patch new file mode 100644 index 0000000..dd7bd81 --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1861793+.patch @@ -0,0 +1,285 @@ +# ./pullrev.sh 1861793 1862611 1862612 +http://svn.apache.org/viewvc?view=revision&revision=1861793 +http://svn.apache.org/viewvc?view=revision&revision=1862611 +http://svn.apache.org/viewvc?view=revision&revision=1862612 +http://svn.apache.org/viewvc?view=revision&revision=1862724 + +--- httpd-2.4.6/configure.in.r1861793+ ++++ httpd-2.4.6/configure.in +@@ -464,6 +464,28 @@ + AC_SEARCH_LIBS(crypt, crypt) + CRYPT_LIBS="$LIBS" + APACHE_SUBST(CRYPT_LIBS) ++ ++if test "$ac_cv_search_crypt" != "no"; then ++ # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt ++ AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [ ++ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ ++#include ++#include ++#include ++ ++#define PASSWD_0 "Hello world!" ++#define SALT_0 "\$6\$saltstring" ++#define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \ ++ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" ++]], [char *result = crypt(PASSWD_0, SALT_0); ++ if (!result) return 1; ++ if (strcmp(result, EXPECT_0)) return 2; ++])], [ap_cv_crypt_sha2=yes], [ap_cv_crypt_sha2=no])]) ++ if test "$ap_cv_crypt_sha2" = yes; then ++ AC_DEFINE([HAVE_CRYPT_SHA2], 1, [Define if crypt() supports SHA-2 hashes]) ++ fi ++fi ++ + LIBS="$saved_LIBS" + + dnl See Comment #Spoon +--- httpd-2.4.6/docs/man/htpasswd.1.r1861793+ ++++ httpd-2.4.6/docs/man/htpasswd.1 +@@ -27,16 +27,16 @@ + .SH "SYNOPSIS" + + .PP +-\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR ++\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR + + .PP +-\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR ++\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR + + .PP +-\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR ++\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR + + .PP +-\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR ++\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR + + + .SH "SUMMARY" +@@ -48,7 +48,7 @@ + Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by htpasswd\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&. + + .PP +-htpasswd encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system's crypt() routine\&. Files managed by htpasswd may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with crypt()\&. +++\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&. + + .PP + This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. +@@ -73,17 +73,26 @@ + -m + Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&. + .TP ++-2 ++Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP ++-5 ++Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP + -B + Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&. + .TP + -C + This flag is only allowed in combination with -B (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 31)\&. + .TP ++-r ++This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&. ++.TP + -d + Use crypt() encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&. + .TP + -s +-Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. ++Use SHA-1 encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. + .TP + -p + Use plaintext passwords\&. Though htpasswd will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&. +@@ -152,11 +161,14 @@ + When using the crypt() algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&. + + .PP +-The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The crypt() and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. ++The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The crypt() and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. + + .PP +-The SHA and crypt() formats are insecure by today's standards\&. +- ++The SHA-1 and crypt() formats are insecure by today's standards\&. ++ ++.PP ++The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\& ++ + .SH "RESTRICTIONS" + + .PP +--- httpd-2.4.6/support/htpasswd.c.r1861793+ ++++ httpd-2.4.6/support/htpasswd.c +@@ -93,28 +93,32 @@ + static void usage(void) + { + apr_file_printf(errfile, "Usage:" NL +- "\thtpasswd [-cimBdpsDv] [-C cost] passwordfile username" NL +- "\thtpasswd -b[cmBdpsDv] [-C cost] passwordfile username password" NL ++ "\thtpasswd [-cimB25dpsDv] [-C cost] [-r rounds] passwordfile username" NL ++ "\thtpasswd -b[cmB25dpsDv] [-C cost] [-r rounds] passwordfile username password" NL + NL +- "\thtpasswd -n[imBdps] [-C cost] username" NL +- "\thtpasswd -nb[mBdps] [-C cost] username password" NL ++ "\thtpasswd -n[imB25dps] [-C cost] [-r rounds] username" NL ++ "\thtpasswd -nb[mB25dps] [-C cost] [-r rounds] username password" NL + " -c Create a new file." NL + " -n Don't update file; display results on stdout." NL + " -b Use the password from the command line rather than prompting " + "for it." NL + " -i Read password from stdin without verification (for script usage)." NL + " -m Force MD5 encryption of the password (default)." NL +- " -B Force bcrypt encryption of the password (very secure)." NL ++ " -2 Force SHA-256 crypt() hash of the password (secure)." NL ++ " -5 Force SHA-512 crypt() hash of the password (secure)." NL ++ " -B Force bcrypt aencryption of the password (very secure)." NL + " -C Set the computing time used for the bcrypt algorithm" NL + " (higher is more secure but slower, default: %d, valid: 4 to 31)." NL ++ " -r Set the number of rounds used for the SHA-256, SHA-512 algorithms" NL ++ " (higher is more secure but slower, default: 5000)." NL + " -d Force CRYPT encryption of the password (8 chars max, insecure)." NL +- " -s Force SHA encryption of the password (insecure)." NL ++ " -s Force SHA-1 encryption of the password (insecure)." NL + " -p Do not encrypt the password (plaintext, insecure)." NL + " -D Delete the specified user." NL + " -v Verify password for the specified user." NL + "On other systems than Windows and NetWare the '-p' flag will " + "probably not work." NL +- "The SHA algorithm does not use a salt and is less secure than the " ++ "The SHA-1 algorithm does not use a salt and is less secure than the " + "MD5 algorithm." NL, + BCRYPT_DEFAULT_COST + ); +@@ -173,7 +177,7 @@ + if (rv != APR_SUCCESS) + exit(ERR_SYNTAX); + +- while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) { ++ while ((rv = apr_getopt(state, "cnmspdBbDi25C:r:v", &opt, &opt_arg)) == APR_SUCCESS) { + switch (opt) { + case 'c': + *mask |= APHTP_NEWFILE; +--- httpd-2.4.6/support/passwd_common.c.r1861793+ ++++ httpd-2.4.6/support/passwd_common.c +@@ -185,10 +185,15 @@ + #if CRYPT_ALGO_SUPPORTED + char *cbuf; + #endif ++#ifdef HAVE_CRYPT_SHA2 ++ const char *setting; ++ char method; ++#endif + +- if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) { ++ if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT ++ && ctx->alg != ALG_CRYPT_SHA256 && ctx->alg != ALG_CRYPT_SHA512 ) { + apr_file_printf(errfile, +- "Warning: Ignoring -C argument for this algorithm." NL); ++ "Warning: Ignoring -C/-r argument for this algorithm." NL); + } + + if (ctx->passwd == NULL) { +@@ -246,6 +251,34 @@ + break; + #endif /* CRYPT_ALGO_SUPPORTED */ + ++#ifdef HAVE_CRYPT_SHA2 ++ case ALG_CRYPT_SHA256: ++ case ALG_CRYPT_SHA512: ++ ret = generate_salt(salt, 16, &ctx->errstr, ctx->pool); ++ if (ret != 0) ++ break; ++ ++ method = ctx->alg == ALG_CRYPT_SHA256 ? '5': '6'; ++ ++ if (ctx->cost) ++ setting = apr_psprintf(ctx->pool, "$%c$rounds=%d$%s", ++ method, ctx->cost, salt); ++ else ++ setting = apr_psprintf(ctx->pool, "$%c$%s", ++ method, salt); ++ ++ cbuf = crypt(pw, setting); ++ if (cbuf == NULL) { ++ rv = APR_FROM_OS_ERROR(errno); ++ ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv); ++ ret = ERR_PWMISMATCH; ++ break; ++ } ++ ++ apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1); ++ break; ++#endif /* HAVE_CRYPT_SHA2 */ ++ + #if BCRYPT_ALGO_SUPPORTED + case ALG_BCRYPT: + rv = apr_generate_random_bytes((unsigned char*)salt, 16); +@@ -294,6 +327,19 @@ + case 's': + ctx->alg = ALG_APSHA; + break; ++#ifdef HAVE_CRYPT_SHA2 ++ case '2': ++ ctx->alg = ALG_CRYPT_SHA256; ++ break; ++ case '5': ++ ctx->alg = ALG_CRYPT_SHA512; ++ break; ++#else ++ case '2': ++ case '5': ++ ctx->errstr = "SHA-2 crypt() algorithms are not supported on this platform."; ++ return ERR_ALG_NOT_SUPP; ++#endif + case 'p': + ctx->alg = ALG_PLAIN; + #if !PLAIN_ALGO_SUPPORTED +@@ -324,11 +370,12 @@ + return ERR_ALG_NOT_SUPP; + #endif + break; +- case 'C': { ++ case 'C': ++ case 'r': { + char *endptr; + long num = strtol(opt_arg, &endptr, 10); + if (*endptr != '\0' || num <= 0) { +- ctx->errstr = "argument to -C must be a positive integer"; ++ ctx->errstr = "argument to -C/-r must be a positive integer"; + return ERR_SYNTAX; + } + ctx->cost = num; +--- httpd-2.4.6/support/passwd_common.h.r1861793+ ++++ httpd-2.4.6/support/passwd_common.h +@@ -28,6 +28,8 @@ + #include "apu_version.h" + #endif + ++#include "ap_config_auto.h" ++ + #define MAX_STRING_LEN 256 + + #define ALG_PLAIN 0 +@@ -35,6 +37,8 @@ + #define ALG_APMD5 2 + #define ALG_APSHA 3 + #define ALG_BCRYPT 4 ++#define ALG_CRYPT_SHA256 5 ++#define ALG_CRYPT_SHA512 6 + + #define BCRYPT_DEFAULT_COST 5 + +@@ -79,7 +83,7 @@ + apr_size_t out_len; + char *passwd; + int alg; +- int cost; ++ int cost; /* cost for bcrypt, rounds for SHA-2 */ + enum { + PW_PROMPT = 0, + PW_ARG, diff --git a/SOURCES/httpd-2.4.6-r1862604.patch b/SOURCES/httpd-2.4.6-r1862604.patch new file mode 100644 index 0000000..83c6c4a --- /dev/null +++ b/SOURCES/httpd-2.4.6-r1862604.patch @@ -0,0 +1,22 @@ +--- a/docs/conf/magic 2019/07/05 11:22:46 1862603 ++++ b/docs/conf/magic 2019/07/05 11:26:12 1862604 +@@ -87,7 +87,7 @@ + # Microsoft WAVE format (*.wav) + # [GRR 950115: probably all of the shorts and longs should be leshort/lelong] + # Microsoft RIFF +-0 string RIFF audio/unknown ++0 string RIFF + # - WAVE format + >8 string WAVE audio/x-wav + # MPEG audio. +--- a/modules/metadata/mod_mime_magic.c 2019/07/05 11:22:46 1862603 ++++ b/modules/metadata/mod_mime_magic.c 2019/07/05 11:26:12 1862604 +@@ -606,7 +606,7 @@ + /* high overhead for 1 char - just hope they don't do this much */ + str[0] = c; + str[1] = '\0'; +- return magic_rsl_add(r, str); ++ return magic_rsl_add(r, apr_pstrdup(r->pool, str)); + } + + /* allocate and copy a contiguous string from a result string list */ 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 d4725ec..f56c376 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: 90%{?dist} +Release: 93%{?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 @@ -71,6 +71,7 @@ Patch36: httpd-2.4.6-r1573626.patch Patch37: httpd-2.4.6-uds.patch Patch38: httpd-2.4.6-upn.patch Patch39: httpd-2.4.6-r1664565.patch +Patch40: httpd-2.4.6-r1861793+.patch # Bug fixes Patch51: httpd-2.4.3-sslsninotreq.patch Patch55: httpd-2.4.4-malformed-host.patch @@ -191,6 +192,10 @@ Patch138: httpd-2.4.6-r1515372.patch Patch139: httpd-2.4.6-r1824872.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1583218 Patch140: httpd-2.4.6-r1833014.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1673457 +Patch141: httpd-2.4.6-r1583175.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1649470 +Patch142: httpd-2.4.6-r1862604.patch # Security fixes Patch200: httpd-2.4.6-CVE-2013-6438.patch @@ -217,6 +222,9 @@ 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 +Patch224: httpd-2.4.6-CVE-2017-15710.patch +Patch225: httpd-2.4.6-CVE-2018-1301.patch +Patch226: httpd-2.4.6-CVE-2018-17199.patch License: ASL 2.0 Group: System Environment/Daemons @@ -283,7 +291,7 @@ Summary: SSL/TLS module for the Apache HTTP Server Epoch: 1 BuildRequires: openssl-devel >= 1:1.0.1e-37 Requires: openssl-libs >= 1:1.0.1e-37 -Requires(post): openssl, /bin/cat +Requires(post): openssl, /bin/cat, hostname Requires(pre): httpd Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} Obsoletes: stronghold-mod_ssl @@ -319,6 +327,7 @@ authentication to the Apache HTTP Server. Group: System Environment/Daemons Summary: Session interface for the Apache HTTP Server Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: apr-util-openssl %description -n mod_session The mod_session module and associated backends provide an abstract @@ -351,6 +360,7 @@ rm modules/ssl/ssl_engine_dh.c %patch37 -p1 -b .uds %patch38 -p1 -b .upn %patch39 -p1 -b .r1664565 +%patch40 -p1 -b .r1861793+ %patch51 -p1 -b .sninotreq %patch55 -p1 -b .malformedhost @@ -438,6 +448,8 @@ rm modules/ssl/ssl_engine_dh.c %patch138 -p1 -b .r1515372 %patch139 -p1 -b .r1824872 %patch140 -p1 -b .r1833014 +%patch141 -p1 -b .r1583175 +%patch142 -p1 -b .1862604 %patch200 -p1 -b .cve6438 @@ -464,6 +476,9 @@ rm modules/ssl/ssl_engine_dh.c %patch221 -p1 -b .cve1312 %patch222 -p1 -b .cve0217 %patch223 -p1 -b .cve0220 +%patch224 -p1 -b .cve15710 +%patch225 -p1 -b .cve1301 +%patch226 -p1 -b .cve17199 # Patch in the vendor string and the release string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -617,10 +632,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 @@ -643,7 +656,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 @@ -829,7 +842,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 @@ -895,13 +908,26 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/rpm/macros.httpd %changelog -* Tue Aug 06 2019 CentOS Sources - 2.4.6-90.el7.centos -- Remove index.html, add centos-noindex.tar.gz -- change vstring -- change symlink for poweredby.png -- update welcome.conf with proper aliases - -* Sat Jun 08 2019 Lubos Uhliarik +* Tue Oct 08 2019 Lubos Uhliarik - 2.4.6-93 +- Resolves: #1677496 - CVE-2018-17199 httpd: mod_session_cookie does not respect + expiry time + +* Thu Aug 22 2019 Joe Orton - 2.4.6-92 +- htpasswd: add SHA-2 crypt() support (#1486889) + +* Wed Jul 31 2019 Lubos Uhliarik - 2.4.6-91 +- Resolves: #1630886 - scriptlet can fail if hostname is not installed +- Resolves: #1565465 - CVE-2017-15710 httpd: Out of bound write in + mod_authnz_ldap when using too small Accept-Language values +- Resolves: #1568298 - CVE-2018-1301 httpd: Out of bounds access after + failure in reading the HTTP request +- Resolves: #1673457 - Apache child process crashes because ScriptAliasMatch + directive +- Resolves: #1633152 - mod_session missing apr-util-openssl +- Resolves: #1649470 - httpd response contains garbage in Content-Type header +- Resolves: #1724034 - Unexpected OCSP in proxy SSL connection + +* Sat Jun 08 2019 Lubos Uhliarik - 2.4.6-90 - Resolves: #1566317 - CVE-2018-1312 httpd: Weak Digest auth nonce generation in mod_auth_digest - Resolves: #1696141 - CVE-2019-0217 httpd: mod_auth_digest: access control