diff -u -r -N squid-4.0.21/acinclude/lib-checks.m4 squid-4.0.22/acinclude/lib-checks.m4 --- squid-4.0.21/acinclude/lib-checks.m4 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/acinclude/lib-checks.m4 2017-12-08 04:12:12.000000000 +1300 @@ -72,6 +72,7 @@ AH_TEMPLATE(HAVE_LIBCRYPTO_X509_UP_REF, "Define to 1 if the X509_up_ref() OpenSSL API function exists") AH_TEMPLATE(HAVE_LIBCRYPTO_X509_CRL_UP_REF, "Define to 1 if the X509_CRL_up_ref() OpenSSL API function exists") AH_TEMPLATE(HAVE_LIBCRYPTO_DH_UP_REF, "Define to 1 if the DH_up_ref() OpenSSL API function exists") + AH_TEMPLATE(HAVE_LIBCRYPTO_X509_GET0_SIGNATURE, "Define to 1 if the X509_get0_signature() OpenSSL API function exists") SQUID_STATE_SAVE(check_openssl_libcrypto_api) LIBS="$LIBS $SSLLIB" AC_CHECK_LIB(crypto, EVP_PKEY_get0_RSA, AC_DEFINE(HAVE_LIBCRYPTO_EVP_PKEY_GET0_RSA, 1)) @@ -85,6 +86,7 @@ AC_CHECK_LIB(crypto, X509_up_ref, AC_DEFINE(HAVE_LIBCRYPTO_X509_UP_REF, 1)) AC_CHECK_LIB(crypto, X509_CRL_up_ref, AC_DEFINE(HAVE_LIBCRYPTO_X509_CRL_UP_REF, 1)) AC_CHECK_LIB(crypto, DH_up_ref, AC_DEFINE(HAVE_LIBCRYPTO_DH_UP_REF, 1)) + AC_CHECK_LIB(crypto, X509_get0_signature, AC_DEFINE(HAVE_LIBCRYPTO_X509_GET0_SIGNATURE, 1)) SQUID_STATE_ROLLBACK(check_openssl_libcrypto_api) ]) @@ -257,6 +259,31 @@ SQUID_STATE_ROLLBACK(check_const_SSL_CTX_sess_set_get_cb) ]) +dnl Checks whether the X509_get0_signature() has const arguments +AC_DEFUN([SQUID_CHECK_OPENSSL_CONST_X509_GET0_SIGNATURE_ARGS],[ + AH_TEMPLATE(SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS, "Define if X509_get0_signature() accepts const parameters") + SQUID_STATE_SAVE(check_const_X509_get0_signature_args) + AC_MSG_CHECKING("whether X509_get0_signature() accepts const parameters") + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ +#include + ],[ +#if HAVE_LIBCRYPTO_X509_GET0_SIGNATURE + const ASN1_BIT_STRING *sig = nullptr; + const X509_ALGOR *sig_alg; + X509_get0_signature(&sig, &sig_alg, nullptr); +#else +#error Missing X509_get0_signature() +#endif + ]) + ],[ + AC_DEFINE(SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS, 1) + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + ]) + SQUID_STATE_ROLLBACK(check_const_X509_get0_signature_args) +]) + dnl Try to handle TXT_DB related problems: dnl 1) The type of TXT_DB::data member changed in openSSL-1.0.1 version dnl 2) The IMPLEMENT_LHASH_* openSSL macros in openSSL-1.0.1 and later releases is not diff -u -r -N squid-4.0.21/ChangeLog squid-4.0.22/ChangeLog --- squid-4.0.21/ChangeLog 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/ChangeLog 2017-12-08 04:12:12.000000000 +1300 @@ -1,3 +1,21 @@ +Changes to squid-4.0.22 (07 Dec 2017): + + - Regression fix: Relay peer CONNECT error status line and headers to clients + - Bug 4767: SMP breaks IPv6 SNMP and cache manager queries + - Bug 4718: support filling raw buffer space of shared SBufs + - Bug 4648: object revalidation for HTTPS scheme + - Bug 4616: store_client.cc:92: "mem" assertion + - Bug 2821: ignore Content-Range in non-206 responses + - HTCP: Ignore packets with invalid URI + - TLS: Validate the shortest certificate chain + - TLS: Add checks for OpenSSL 1.1.0f API changes + - TLS: Fix reporting of validation errors for downloaded intermediate certs + - TLS: Fix SSL certificate cache refresh and collision handling + - Fix backwards compatibility for Squid-3.5 external_acl_type formats + - Fix invalid mime icon URLs in cache + - Do not die silently when dying early + - Docs: update translation files + Changes to squid-4.0.21 (02 Jul 2017): - Bug 4730: segfault while processing internal HTTP requests @@ -19,11 +37,11 @@ Changes to squid-4.0.20 (01 Jun 2017): - - Bug #4692: SslBump breaks intercepted IPv6 connections - - Bug #4682: ignoring http_access deny when client-first bumping mode is used - - Bug #4662: build errors with LibreSSL 2.4.4 - - Bug #4659: sslproxy_foreign_intermediate_certs does not work - - Bug #4321: ssl_bump terminate does not terminate at step1 + - Bug 4692: SslBump breaks intercepted IPv6 connections + - Bug 4682: ignoring http_access deny when client-first bumping mode is used + - Bug 4662: build errors with LibreSSL 2.4.4 + - Bug 4659: sslproxy_foreign_intermediate_certs does not work + - Bug 4321: ssl_bump terminate does not terminate at step1 - Add 'has' ACL - Do not forward HTTP requests to dead idle peers - Do not unconditionally revive dead peers after a DNS refresh @@ -324,6 +342,18 @@ - ... and many documentation changes - ... and much code cleanup and polishing +Changes to squid-3.5.27 (20 Aug 2017): + + - Regression Bug #4112: ssl_engine does not accept cryptodev + - Bug 4687: Wrong names of components in man page, section SEE ALSO + - Bug 4671: various GCC 7 compile errors + - Bug 4464: Reduce "!Comm::MonitorsRead(serverConnection->fd)" assertions + - Bug 2833: Collapse internal revalidation requests (SMP-unaware caches) + - Bug 2833: Do not respond with HTTP/304 to unconditional requests + - Fix message packing error handling in mgr and snmp SMP Forwarders + - Fix mgr query handoff from the original recipient to Coordinator. + - ... and some documentation updates + Changes to squid-3.5.26 (01 Jun 2017): - Bug 4711: SubjectAlternativeNames is missing in some generated certificates @@ -335,7 +365,7 @@ - Bug 3772: message from FTP server gets mangled - Bug 3102: FTP directory listing drops fist character of file names - Add OpenSSL library details to -v output - - ... and some documentatino updates + - ... and some documentation updates Changes to squid-3.5.25 (02 Apr 2017): diff -u -r -N squid-4.0.21/compat/compat_shared.h squid-4.0.22/compat/compat_shared.h --- squid-4.0.21/compat/compat_shared.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/compat/compat_shared.h 2017-12-08 04:12:12.000000000 +1300 @@ -77,7 +77,7 @@ * NP: FreeBSD 7 defines FD_SETSIZE as unsigned but Squid needs * it to be signed to compare it with signed values. * Linux and others including FreeBSD <7, define it as signed. - * If this causes any issues please contact squid-dev@squid-cache.org + * If this causes any issues please contact squid-dev mailing list. */ #if defined(USE_SELECT) || defined(USE_SELECT_WIN32) /* Limited by design */ diff -u -r -N squid-4.0.21/configure squid-4.0.22/configure --- squid-4.0.21/configure 2017-07-02 20:41:29.000000000 +1200 +++ squid-4.0.22/configure 2017-12-08 06:11:17.000000000 +1300 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.21. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.22. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='4.0.21' -PACKAGE_STRING='Squid Web Proxy 4.0.21' +PACKAGE_VERSION='4.0.22' +PACKAGE_STRING='Squid Web Proxy 4.0.22' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1647,7 +1647,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Squid Web Proxy 4.0.21 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 4.0.22 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1718,7 +1718,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 4.0.21:";; + short | recursive ) echo "Configuration of Squid Web Proxy 4.0.22:";; esac cat <<\_ACEOF @@ -2147,7 +2147,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 4.0.21 +Squid Web Proxy configure 4.0.22 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3251,7 +3251,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Squid Web Proxy $as_me 4.0.21, which was +It was created by Squid Web Proxy $as_me 4.0.22, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4118,7 +4118,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='4.0.21' + VERSION='4.0.22' cat >>confdefs.h <<_ACEOF @@ -4684,6 +4684,8 @@ + + ## Copyright (C) 1996-2017 The Squid Software Foundation and contributors ## ## Squid software is distributed under GPLv2+ license and includes @@ -23934,6 +23936,7 @@ + # save state, key is check_openssl_libcrypto_api check_openssl_libcrypto_api_CFLAGS="${CFLAGS}" check_openssl_libcrypto_api_CXXFLAGS="${CXXFLAGS}" @@ -24401,6 +24404,47 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X509_get0_signature in -lcrypto" >&5 +$as_echo_n "checking for X509_get0_signature in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_X509_get0_signature+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char X509_get0_signature (); +int +main () +{ +return X509_get0_signature (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_crypto_X509_get0_signature=yes +else + ac_cv_lib_crypto_X509_get0_signature=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_X509_get0_signature" >&5 +$as_echo "$ac_cv_lib_crypto_X509_get0_signature" >&6; } +if test "x$ac_cv_lib_crypto_X509_get0_signature" = xyes; then : + $as_echo "#define HAVE_LIBCRYPTO_X509_GET0_SIGNATURE 1" >>confdefs.h + +fi + # rollback state, key is check_openssl_libcrypto_api CFLAGS="${check_openssl_libcrypto_api_CFLAGS}" @@ -25299,6 +25343,92 @@ +# save state, key is check_const_X509_get0_signature_args +check_const_X509_get0_signature_args_CFLAGS="${CFLAGS}" +check_const_X509_get0_signature_args_CXXFLAGS="${CXXFLAGS}" +check_const_X509_get0_signature_args_LDFLAGS="${LDFLAGS}" +check_const_X509_get0_signature_args_LIBS="${LIBS}" +check_const_X509_get0_signature_args_CC="${CC}" +check_const_X509_get0_signature_args_CXX="${CXX}" +check_const_X509_get0_signature_args_CPPFLAGS="${CPPFLAGS}" +check_const_X509_get0_signature_args_squid_saved_vars="" +for squid_util_var_tosave in $check_const_X509_get0_signature_args_squid_saved_vars +do + squid_util_var_tosave2="check_const_X509_get0_signature_args_${squid_util_var_tosave}" + eval "${squid_util_var_tosave2}=\"${squid_util_var_tosave}\"" +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking \"whether X509_get0_signature() accepts const parameters\"" >&5 +$as_echo_n "checking \"whether X509_get0_signature() accepts const parameters\"... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +#if HAVE_LIBCRYPTO_X509_GET0_SIGNATURE + const ASN1_BIT_STRING *sig = nullptr; + const X509_ALGOR *sig_alg; + X509_get0_signature(&sig, &sig_alg, nullptr); +#else +#error Missing X509_get0_signature() +#endif + + ; + return 0; +} + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + $as_echo "#define SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# rollback state, key is check_const_X509_get0_signature_args +CFLAGS="${check_const_X509_get0_signature_args_CFLAGS}" +CXXFLAGS="${check_const_X509_get0_signature_args_CXXFLAGS}" +LDFLAGS="${check_const_X509_get0_signature_args_LDFLAGS}" +LIBS="${check_const_X509_get0_signature_args_LIBS}" +CC="${check_const_X509_get0_signature_args_CC}" +CXX="${check_const_X509_get0_signature_args_CXX}" +CPPFLAGS="${check_const_X509_get0_signature_args_CPPFLAGS}" +for squid_util_var_tosave in $check_const_X509_get0_signature_args_squid_saved_vars +do + squid_util_var_tosave2="\$check_const_X509_get0_signature_args_${squid_util_var_tosave}" + eval "$squid_util_var_tosave=\"${squid_util_var_tosave2}\"" +done + +# commit state, key is check_const_X509_get0_signature_args +unset check_const_X509_get0_signature_args_CFLAGS +unset check_const_X509_get0_signature_args_CXXFLAGS +unset check_const_X509_get0_signature_args_LDFLAGS +unset check_const_X509_get0_signature_args_LIBS +unset check_const_X509_get0_signature_args_CC +unset check_const_X509_get0_signature_args_CXX +unset check_const_X509_get0_signature_args_CPPFLAGS +for squid_util_var_tosave in $check_const_X509_get0_signature_args_squid_saved_vars +do + unset ${squid_util_var_tosave} +done + + + + + + @@ -36706,8 +36836,8 @@ eval "${squid_util_var_tosave2}=\"${squid_util_var_tosave}\"" done - as_fn_append CXXFLAGS $LIBCPPUNIT_CFLAGS - as_fn_append LIBS $LIBCPPUNIT_LIBS + CXXFLAGS="${CXXFLAGS} ${LIBCPPUNIT_CFLAGS}" + LIBS="${LIBS} ${LIBCPPUNIT_LIBS}" for ac_header in cppunit/extensions/HelperMacros.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "cppunit/extensions/HelperMacros.h" "ac_cv_header_cppunit_extensions_HelperMacros_h" "$ac_includes_default" @@ -43656,7 +43786,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Squid Web Proxy $as_me 4.0.21, which was +This file was extended by Squid Web Proxy $as_me 4.0.22, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -43722,7 +43852,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Squid Web Proxy config.status 4.0.21 +Squid Web Proxy config.status 4.0.22 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -u -r -N squid-4.0.21/configure.ac squid-4.0.22/configure.ac --- squid-4.0.21/configure.ac 2017-07-02 20:41:29.000000000 +1200 +++ squid-4.0.22/configure.ac 2017-12-08 06:11:17.000000000 +1300 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[4.0.21],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[4.0.22],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) @@ -1367,6 +1367,7 @@ SQUID_CHECK_OPENSSL_CONST_SSL_METHOD SQUID_CHECK_OPENSSL_CONST_CRYPTO_EX_DATA SQUID_CHECK_OPENSSL_CONST_SSL_SESSION_CB_ARG + SQUID_CHECK_OPENSSL_CONST_X509_GET0_SIGNATURE_ARGS SQUID_CHECK_OPENSSL_TXTDB SQUID_CHECK_OPENSSL_HELLO_OVERWRITE_HACK fi @@ -2755,8 +2756,8 @@ AS_UNSET(squid_cv_cppunit_version) SQUID_STATE_SAVE(squid_cppunit_state) - AS_VAR_APPEND(CXXFLAGS,[$LIBCPPUNIT_CFLAGS]) - AS_VAR_APPEND(LIBS,[$LIBCPPUNIT_LIBS]) + CXXFLAGS="${CXXFLAGS} ${LIBCPPUNIT_CFLAGS}" + LIBS="${LIBS} ${LIBCPPUNIT_LIBS}" AC_CHECK_HEADERS(cppunit/extensions/HelperMacros.h) SQUID_STATE_ROLLBACK(squid_cppunit_state) ],[ diff -u -r -N squid-4.0.21/CONTRIBUTORS squid-4.0.22/CONTRIBUTORS --- squid-4.0.21/CONTRIBUTORS 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/CONTRIBUTORS 2017-12-08 04:12:12.000000000 +1300 @@ -180,7 +180,7 @@ Isnard Ivan Mas??r Jakob Bohm - Jakub Wilk + Jakub Wilk James Bowe James Brotchie James R Grinter diff -u -r -N squid-4.0.21/doc/release-notes/release-4.html squid-4.0.22/doc/release-notes/release-4.html --- squid-4.0.21/doc/release-notes/release-4.html 2017-07-02 20:57:33.000000000 +1200 +++ squid-4.0.22/doc/release-notes/release-4.html 2017-12-08 06:18:59.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 4.0.21 release notes + Squid 4.0.22 release notes -

Squid 4.0.21 release notes

+

Squid 4.0.22 release notes

Squid Developers


@@ -62,7 +62,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.21 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.0.22 for testing.

This new release is available for download from http://www.squid-cache.org/Versions/v4/ or the mirrors.

diff -u -r -N squid-4.0.21/include/autoconf.h.in squid-4.0.22/include/autoconf.h.in --- squid-4.0.21/include/autoconf.h.in 2017-07-02 20:41:22.000000000 +1200 +++ squid-4.0.22/include/autoconf.h.in 2017-12-08 06:11:11.000000000 +1300 @@ -510,6 +510,9 @@ /* "Define to 1 if the X509_CRL_up_ref() OpenSSL API function exists" */ #undef HAVE_LIBCRYPTO_X509_CRL_UP_REF +/* "Define to 1 if the X509_get0_signature() OpenSSL API function exists" */ +#undef HAVE_LIBCRYPTO_X509_GET0_SIGNATURE + /* "Define to 1 if the X509_STORE_CTX_get0_cert() OpenSSL API function exists" */ #undef HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_CERT @@ -1383,6 +1386,9 @@ argument" */ #undef SQUID_USE_CONST_SSL_SESSION_CBID +/* "Define if X509_get0_signature() accepts const parameters" */ +#undef SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS + /* "Define to 1 if hello message can be overwritten in SSL struct" */ #undef SQUID_USE_OPENSSL_HELLO_OVERWRITE_HACK diff -u -r -N squid-4.0.21/include/version.h squid-4.0.22/include/version.h --- squid-4.0.21/include/version.h 2017-07-02 20:41:29.000000000 +1200 +++ squid-4.0.22/include/version.h 2017-12-08 06:11:17.000000000 +1300 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1498984863 +#define SQUID_RELEASE_TIME 1512666668 #endif /* diff -u -r -N squid-4.0.21/po4a.conf squid-4.0.22/po4a.conf --- squid-4.0.21/po4a.conf 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/po4a.conf 2017-12-08 04:12:12.000000000 +1300 @@ -38,6 +38,8 @@ [type: man] src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 $lang:doc/manuals/$lang/negotiate_kerberos_auth.8 +[type: man] src/auth/negotiate/SSPI/negotiate_sspi_auth.8 $lang:doc/manuals/$lang/negotiate_sspi_auth.8 + [type: man] src/auth/ntlm/SSPI/ntlm_sspi_auth.8 $lang:doc/manuals/$lang/ntlm_sspi_auth.8 [type: man] src/security/cert_generators/file/security_file_certgen.8.in $lang:doc/manuals/$lang/security_file_certgen.8.in diff -u -r -N squid-4.0.21/README squid-4.0.22/README --- squid-4.0.21/README 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/README 2017-12-08 04:12:12.000000000 +1300 @@ -1,6 +1,5 @@ - -SQUID Web Proxy Cache http://www.squid-cache.org/ -------------------------------------------------------------------------- +SQUID Web Proxy Cache http://www.squid-cache.org/ +------------------------------------------------------------------------ Copyright (C) 1996-2017 The Squid Software Foundation and contributors @@ -8,22 +7,28 @@ contributions from numerous individuals and organizations. Please see the COPYING and CONTRIBUTORS files for details. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses/. - -Please use our mailing lists for questions, feedback and bug fixes: - - squid-users@squid-cache.org # general questions, public forum - squid-bugs@squid-cache.org # bugs and fixes - squid@squid-cache.org # other feedback +For support, please use the following resources: + + * General help and support: squid-users@lists.squid-cache.org + * Public bug reports: http://bugs.squid-cache.org/ + * Security bug reports: squid-bugs@lists.squid-cache.org + * Development discussions: squid-dev@lists.squid-cache.org + +For mailing list subscription instructions, project maintainers contact +information, commercial services, and many other support details, please +visit http://www.squid-cache.org/Support/ + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see http://www.gnu.org/licenses/. diff -u -r -N squid-4.0.21/RELEASENOTES.html squid-4.0.22/RELEASENOTES.html --- squid-4.0.21/RELEASENOTES.html 2017-07-02 20:57:33.000000000 +1200 +++ squid-4.0.22/RELEASENOTES.html 2017-12-08 06:18:59.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 4.0.21 release notes + Squid 4.0.22 release notes -

Squid 4.0.21 release notes

+

Squid 4.0.22 release notes

Squid Developers


@@ -62,7 +62,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.21 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.0.22 for testing.

This new release is available for download from http://www.squid-cache.org/Versions/v4/ or the mirrors.

diff -u -r -N squid-4.0.21/SPONSORS squid-4.0.22/SPONSORS --- squid-4.0.21/SPONSORS 2017-07-02 20:41:29.000000000 +1200 +++ squid-4.0.22/SPONSORS 2017-12-08 06:11:17.000000000 +1300 @@ -25,7 +25,7 @@ Squid Project services. RM Education - http://www.rm.com/ - + RM Education has sponsored Squid performance optimizations and stability improvements. diff -u -r -N squid-4.0.21/src/acl/Asn.cc squid-4.0.22/src/acl/Asn.cc --- squid-4.0.21/src/acl/Asn.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/Asn.cc 2017-12-08 04:12:12.000000000 +1300 @@ -235,6 +235,7 @@ static void asnCacheStart(int as) { + // TODO: use class URL instead of generating a string and re-parsing LOCAL_ARRAY(char, asres, 4096); StoreEntry *e; ASState *asState = new ASState; diff -u -r -N squid-4.0.21/src/acl/external/AD_group/ext_ad_group_acl.8 squid-4.0.22/src/acl/external/AD_group/ext_ad_group_acl.8 --- squid-4.0.21/src/acl/external/AD_group/ext_ad_group_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/AD_group/ext_ad_group_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -250,7 +250,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -259,11 +259,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.8 squid-4.0.22/src/acl/external/delayer/ext_delayer_acl.8 --- squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.8 2017-07-02 20:57:34.000000000 +1200 +++ squid-4.0.22/src/acl/external/delayer/ext_delayer_acl.8 2017-12-08 06:19:00.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 8" -.TH EXT_DELAYER_ACL 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -208,7 +208,7 @@ .Ve .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -216,12 +216,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.pl.in squid-4.0.22/src/acl/external/delayer/ext_delayer_acl.pl.in --- squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/delayer/ext_delayer_acl.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -88,7 +88,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -97,9 +97,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.8 squid-4.0.22/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.8 --- squid-4.0.21/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -205,7 +205,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS .PP @@ -223,11 +223,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/file_userip/ext_file_userip_acl.8 squid-4.0.22/src/acl/external/file_userip/ext_file_userip_acl.8 --- squid-4.0.21/src/acl/external/file_userip/ext_file_userip_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/file_userip/ext_file_userip_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -93,7 +93,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -102,11 +102,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 squid-4.0.22/src/acl/external/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 --- squid-4.0.21/src/acl/external/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -237,7 +237,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -246,11 +246,11 @@ Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8) " diff -u -r -N squid-4.0.21/src/acl/external/LDAP_group/ChangeLog squid-4.0.22/src/acl/external/LDAP_group/ChangeLog --- squid-4.0.21/src/acl/external/LDAP_group/ChangeLog 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/LDAP_group/ChangeLog 2017-12-08 04:12:12.000000000 +1300 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996-2015 The Squid Software Foundation and contributors + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. diff -u -r -N squid-4.0.21/src/acl/external/LDAP_group/ext_ldap_group_acl.8 squid-4.0.22/src/acl/external/LDAP_group/ext_ldap_group_acl.8 --- squid-4.0.21/src/acl/external/LDAP_group/ext_ldap_group_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/LDAP_group/ext_ldap_group_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -255,7 +255,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' .PP Or contact your favorite LDAP list/friend if the question is more related to LDAP than Squid. @@ -267,11 +267,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/LM_group/ext_lm_group_acl.8 squid-4.0.22/src/acl/external/LM_group/ext_lm_group_acl.8 --- squid-4.0.21/src/acl/external/LM_group/ext_lm_group_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/LM_group/ext_lm_group_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -182,7 +182,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -191,11 +191,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/session/ext_session_acl.8 squid-4.0.22/src/acl/external/session/ext_session_acl.8 --- squid-4.0.21/src/acl/external/session/ext_session_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/session/ext_session_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -112,7 +112,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -121,11 +121,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-4.0.22/src/acl/external/SQL_session/ext_sql_session_acl.8 --- squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.8 2017-07-02 20:57:34.000000000 +1200 +++ squid-4.0.22/src/acl/external/SQL_session/ext_sql_session_acl.8 2017-12-08 06:19:00.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 8" -.TH EXT_SQL_SESSION_ACL 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -150,7 +150,7 @@ Taking an identity token to be validated (as determined by the external_acl_type format) it returns a username or tag associated with the identity token passed in. .PP -Common forms of identifiers are \s-1IP\s0 address, \s-1EUI \s0(\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens. +Common forms of identifiers are \s-1IP\s0 address, \s-1EUI\s0 (\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens. .PP This program uses Squid concurrency support. .SH "OPTIONS" @@ -208,7 +208,7 @@ .Ve .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -216,12 +216,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.pl.in squid-4.0.22/src/acl/external/SQL_session/ext_sql_session_acl.pl.in --- squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/SQL_session/ext_sql_session_acl.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -94,7 +94,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -103,9 +103,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/acl/external/time_quota/ext_time_quota_acl.8 squid-4.0.22/src/acl/external/time_quota/ext_time_quota_acl.8 --- squid-4.0.21/src/acl/external/time_quota/ext_time_quota_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/time_quota/ext_time_quota_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -230,7 +230,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -239,11 +239,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/acl/external/unix_group/ext_unix_group_acl.8 squid-4.0.22/src/acl/external/unix_group/ext_unix_group_acl.8 --- squid-4.0.21/src/acl/external/unix_group/ext_unix_group_acl.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/unix_group/ext_unix_group_acl.8 2017-12-08 04:12:12.000000000 +1300 @@ -85,7 +85,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -94,11 +94,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' .PP Additionally bugs or bug\-fixes can be reported to .if !'po4a'hide' .I Rodrigo Campos diff -u -r -N squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-4.0.22/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2017-07-02 20:57:34.000000000 +1200 +++ squid-4.0.22/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2017-12-08 06:19:00.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 8" -.TH EXT_WBINFO_GROUP_ACL 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -199,7 +199,7 @@ .Ve .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -207,9 +207,9 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq diff -u -r -N squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.pl.in squid-4.0.22/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.pl.in --- squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -75,7 +75,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -84,9 +84,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/acl/Options.cc squid-4.0.22/src/acl/Options.cc --- squid-4.0.21/src/acl/Options.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/acl/Options.cc 2017-12-08 04:12:12.000000000 +1300 @@ -246,14 +246,14 @@ const Acl::Options & Acl::NoOptions() { - static const Options none; + static const Options none = {}; return none; } const Acl::ParameterFlags & Acl::NoFlags() { - static const ParameterFlags none; + static const ParameterFlags none = {}; return none; } diff -u -r -N squid-4.0.21/src/adaptation/ecap/MessageRep.cc squid-4.0.22/src/adaptation/ecap/MessageRep.cc --- squid-4.0.21/src/adaptation/ecap/MessageRep.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/adaptation/ecap/MessageRep.cc 2017-12-08 04:12:12.000000000 +1300 @@ -201,10 +201,8 @@ { // TODO: if method is not set, URL::parse will assume it is not connect; // Can we change URL::parse API to remove the method parameter? - // TODO: optimize: URL::parse should take constant URL buffer - char *buf = xstrdup(aUri.toString().c_str()); + const char *buf = aUri.toString().c_str(); const bool ok = theMessage.url.parse(theMessage.method, buf); - xfree(buf); Must(ok); } diff -u -r -N squid-4.0.21/src/adaptation/icap/Xaction.cc squid-4.0.22/src/adaptation/icap/Xaction.cc --- squid-4.0.21/src/adaptation/icap/Xaction.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/adaptation/icap/Xaction.cc 2017-12-08 04:12:12.000000000 +1300 @@ -467,7 +467,7 @@ Must(readBuf.length() < SQUID_TCP_SO_RCVBUF); // now we can ensure that there is space to read new data, // even if readBuf.spaceSize() currently returns zero. - readBuf.rawSpace(1); + readBuf.rawAppendStart(1); CommIoCbParams rd(this); // will be expanded with ReadNow results rd.conn = io.conn; diff -u -r -N squid-4.0.21/src/anyp/PortCfg.cc squid-4.0.22/src/anyp/PortCfg.cc --- squid-4.0.21/src/anyp/PortCfg.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/anyp/PortCfg.cc 2017-12-08 04:12:12.000000000 +1300 @@ -40,19 +40,6 @@ vport(0), disable_pmtu_discovery(0), listenConn() -#if USE_OPENSSL - , - clientca(NULL), - sslContextSessionId(NULL), - generateHostCertificates(true), - dynamicCertMemCacheSize(4*1024*1024), // 4 MB - signingCert(), - signPkey(), - certsToChain(), - untrustedSigningCert(), - untrustedSignPkey(), - clientCA() -#endif { memset(&tcp_keepalive, 0, sizeof(tcp_keepalive)); } @@ -66,11 +53,6 @@ safe_free(name); safe_free(defaultsite); - -#if USE_OPENSSL - safe_free(clientca); - safe_free(sslContextSessionId); -#endif } AnyP::PortCfgPointer @@ -94,59 +76,6 @@ b->tcp_keepalive = tcp_keepalive; b->secure = secure; -#if USE_OPENSSL - if (clientca) - b->clientca = xstrdup(clientca); - if (sslContextSessionId) - b->sslContextSessionId = xstrdup(sslContextSessionId); - -#if 0 - // TODO: AYJ: 2015-01-15: for now SSL does not clone the context object. - // cloning should only be done before the PortCfg is post-configure initialized and opened - Security::ContextPointer sslContext; -#endif - -#endif /*0*/ - return b; } -#if USE_OPENSSL -void -AnyP::PortCfg::configureSslServerContext() -{ - if (!secure.certs.empty()) { - Security::KeyData &keys = secure.certs.front(); - Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, keys.certFile.c_str(), keys.privateKeyFile.c_str()); - } - - if (!signingCert) { - char buf[128]; - fatalf("No valid signing SSL certificate configured for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); - } - - if (!signPkey) - debugs(3, DBG_IMPORTANT, "No SSL private key configured for " << AnyP::ProtocolType_str[transport.protocol] << "_port " << s); - - Ssl::generateUntrustedCert(untrustedSigningCert, untrustedSignPkey, - signingCert, signPkey); - - if (!untrustedSigningCert) { - char buf[128]; - fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); - } - - if (clientca) { - clientCA.reset(SSL_load_client_CA_file(clientca)); - if (clientCA.get() == NULL) { - fatalf("Unable to read client CAs! from %s", clientca); - } - } - - if (!secure.createStaticServerContext(*this)) { - char buf[128]; - fatalf("%s_port %s initialization error", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf))); - } -} -#endif - diff -u -r -N squid-4.0.21/src/anyp/PortCfg.h squid-4.0.22/src/anyp/PortCfg.h --- squid-4.0.21/src/anyp/PortCfg.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/anyp/PortCfg.h 2017-12-08 04:12:12.000000000 +1300 @@ -16,10 +16,6 @@ #include "sbuf/SBuf.h" #include "security/ServerOptions.h" -#if USE_OPENSSL -#include "ssl/gadgets.h" -#endif - namespace AnyP { @@ -29,10 +25,6 @@ PortCfg(); ~PortCfg(); AnyP::PortCfgPointer clone() const; -#if USE_OPENSSL - /// creates, configures, and validates SSL context and related port options - void configureSslServerContext(); -#endif PortCfgPointer next; @@ -71,21 +63,6 @@ /// TLS configuration options for this listening port Security::ServerOptions secure; - -#if USE_OPENSSL - char *clientca; - char *sslContextSessionId; ///< "session id context" for secure.staticSslContext - bool generateHostCertificates; ///< dynamically make host cert for sslBump - size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache - - Security::CertPointer signingCert; ///< x509 certificate for signing generated certificates - Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates - Ssl::X509_STACK_Pointer certsToChain; ///< x509 certificates to send with the generated cert - Security::CertPointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates - Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates - - Ssl::X509_NAME_STACK_Pointer clientCA; ///< CA certificates to use when verifying client certificates -#endif }; } // namespace AnyP diff -u -r -N squid-4.0.21/src/auth/basic/DB/basic_db_auth.8 squid-4.0.22/src/auth/basic/DB/basic_db_auth.8 --- squid-4.0.21/src/auth/basic/DB/basic_db_auth.8 2017-07-02 20:57:35.000000000 +1200 +++ squid-4.0.22/src/auth/basic/DB/basic_db_auth.8 2017-12-08 06:19:01.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 8" -.TH BASIC_DB_AUTH 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -190,7 +190,7 @@ Keep a persistent database connection open between queries. .IP "\fB\-\-joomla\fR" 12 .IX Item "--joomla" -Tells helper that user database is Joomla \s-1DB. \s0 So their unusual salt +Tells helper that user database is Joomla \s-1DB.\s0 So their unusual salt hashing is understood. .SH "AUTHOR" .IX Header "AUTHOR" @@ -216,7 +216,7 @@ later version. .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -224,12 +224,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.21/src/auth/basic/DB/basic_db_auth.pl.in squid-4.0.22/src/auth/basic/DB/basic_db_auth.pl.in --- squid-4.0.21/src/auth/basic/DB/basic_db_auth.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/DB/basic_db_auth.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -106,7 +106,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -115,9 +115,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/auth/basic/getpwnam/basic_getpwnam_auth.8 squid-4.0.22/src/auth/basic/getpwnam/basic_getpwnam_auth.8 --- squid-4.0.21/src/auth/basic/getpwnam/basic_getpwnam_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/getpwnam/basic_getpwnam_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -87,7 +87,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -96,11 +96,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/LDAP/basic_ldap_auth.8 squid-4.0.22/src/auth/basic/LDAP/basic_ldap_auth.8 --- squid-4.0.21/src/auth/basic/LDAP/basic_ldap_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/LDAP/basic_ldap_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -318,7 +318,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' .PP Or to your favorite LDAP list/friend if the question is more related to LDAP than Squid. @@ -330,11 +330,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/NCSA/basic_ncsa_auth.8 squid-4.0.22/src/auth/basic/NCSA/basic_ncsa_auth.8 --- squid-4.0.21/src/auth/basic/NCSA/basic_ncsa_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/NCSA/basic_ncsa_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -77,7 +77,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -86,11 +86,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/PAM/basic_pam_auth.8 squid-4.0.22/src/auth/basic/PAM/basic_pam_auth.8 --- squid-4.0.21/src/auth/basic/PAM/basic_pam_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/PAM/basic_pam_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -97,7 +97,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -106,11 +106,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.8 squid-4.0.22/src/auth/basic/POP3/basic_pop3_auth.8 --- squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.8 2017-07-02 20:57:35.000000000 +1200 +++ squid-4.0.22/src/auth/basic/POP3/basic_pop3_auth.8 2017-12-08 06:19:02.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 8" -.TH BASIC_POP3_AUTH 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -185,7 +185,7 @@ .Ve .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -193,12 +193,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.pl.in squid-4.0.22/src/auth/basic/POP3/basic_pop3_auth.pl.in --- squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/POP3/basic_pop3_auth.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -58,7 +58,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -67,9 +67,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/auth/basic/RADIUS/basic_radius_auth.8 squid-4.0.22/src/auth/basic/RADIUS/basic_radius_auth.8 --- squid-4.0.21/src/auth/basic/RADIUS/basic_radius_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/RADIUS/basic_radius_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -109,7 +109,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' .PP Or contact your favorite RADIUS list/friend if the question is more related to RADIUS than Squid. @@ -121,11 +121,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/SASL/basic_sasl_auth.8 squid-4.0.22/src/auth/basic/SASL/basic_sasl_auth.8 --- squid-4.0.21/src/auth/basic/SASL/basic_sasl_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/SASL/basic_sasl_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -93,7 +93,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -102,11 +102,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/basic/SSPI/basic_sspi_auth.8 squid-4.0.22/src/auth/basic/SSPI/basic_sspi_auth.8 --- squid-4.0.21/src/auth/basic/SSPI/basic_sspi_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/basic/SSPI/basic_sspi_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -147,7 +147,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -156,11 +156,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/digest/file/digest_file_auth.8 squid-4.0.22/src/auth/digest/file/digest_file_auth.8 --- squid-4.0.21/src/auth/digest/file/digest_file_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/digest/file/digest_file_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -84,7 +84,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -93,11 +93,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 squid-4.0.22/src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 --- squid-4.0.21/src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -113,7 +113,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -122,11 +122,11 @@ Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8) " diff -u -r -N squid-4.0.21/src/auth/negotiate/SSPI/Makefile.am squid-4.0.22/src/auth/negotiate/SSPI/Makefile.am --- squid-4.0.21/src/auth/negotiate/SSPI/Makefile.am 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/negotiate/SSPI/Makefile.am 2017-12-08 04:12:12.000000000 +1300 @@ -9,6 +9,8 @@ libexec_PROGRAMS = negotiate_sspi_auth +man_MANS = negotiate_sspi_auth.8 + negotiate_sspi_auth_SOURCES = \ negotiate_sspi_auth.cc negotiate_sspi_auth_LDADD = \ @@ -19,5 +21,5 @@ $(XTRA_LIBS) EXTRA_DIST= \ - readme.txt \ + negotiate_sspi_auth.8 \ required.m4 diff -u -r -N squid-4.0.21/src/auth/negotiate/SSPI/Makefile.in squid-4.0.22/src/auth/negotiate/SSPI/Makefile.in --- squid-4.0.21/src/auth/negotiate/SSPI/Makefile.in 2017-07-02 20:41:26.000000000 +1200 +++ squid-4.0.22/src/auth/negotiate/SSPI/Makefile.in 2017-12-08 06:11:14.000000000 +1300 @@ -163,7 +163,7 @@ CONFIG_HEADER = $(top_builddir)/include/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(libexecdir)" +am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man8dir)" PROGRAMS = $(libexec_PROGRAMS) am_negotiate_sspi_auth_OBJECTS = negotiate_sspi_auth.$(OBJEXT) negotiate_sspi_auth_OBJECTS = $(am_negotiate_sspi_auth_OBJECTS) @@ -219,6 +219,36 @@ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -260,33 +290,6 @@ std=''; \ fi; \ } -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* @@ -698,6 +701,7 @@ @ENABLE_XPROF_STATS_TRUE@LIBPROFILER = $(top_builddir)/lib/profiler/libprofiler.la COMPAT_LIB = $(top_builddir)/compat/libcompatsquid.la $(LIBPROFILER) subst_perlshell = sed -e 's,[@]PERL[@],$(PERL),g' <$(srcdir)/$@.pl.in >$@ || ($(RM) -f $@ ; exit 1) +man_MANS = negotiate_sspi_auth.8 negotiate_sspi_auth_SOURCES = \ negotiate_sspi_auth.cc @@ -709,7 +713,7 @@ $(XTRA_LIBS) EXTRA_DIST = \ - readme.txt \ + negotiate_sspi_auth.8 \ required.m4 all: all-am @@ -846,6 +850,49 @@ clean-libtool: -rm -rf .libs _libs +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -1089,9 +1136,9 @@ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(PROGRAMS) +all-am: Makefile $(PROGRAMS) $(MANS) installdirs: - for dir in "$(DESTDIR)$(libexecdir)"; do \ + for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1151,7 +1198,7 @@ info-am: -install-data-am: +install-data-am: install-man install-dvi: install-dvi-am @@ -1167,7 +1214,7 @@ install-info-am: -install-man: +install-man: install-man8 install-pdf: install-pdf-am @@ -1197,7 +1244,9 @@ ps-am: -uninstall-am: uninstall-libexecPROGRAMS +uninstall-am: uninstall-libexecPROGRAMS uninstall-man + +uninstall-man: uninstall-man8 .MAKE: check-am install-am install-strip @@ -1209,13 +1258,13 @@ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ - install-libexecPROGRAMS install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ + install-libexecPROGRAMS install-man install-man8 install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ - uninstall-libexecPROGRAMS + uninstall-libexecPROGRAMS uninstall-man uninstall-man8 .PRECIOUS: Makefile diff -u -r -N squid-4.0.21/src/auth/negotiate/SSPI/negotiate_sspi_auth.8 squid-4.0.22/src/auth/negotiate/SSPI/negotiate_sspi_auth.8 --- squid-4.0.21/src/auth/negotiate/SSPI/negotiate_sspi_auth.8 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.22/src/auth/negotiate/SSPI/negotiate_sspi_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -0,0 +1,112 @@ +.if !'po4a'hide' .TH negotiate_sspi_auth.exe 8 +. +.SH NAME +.if !'po4a'hide' .B negotiate_sspi_auth.exe +.if !'po4a'hide' \- +Windows SSPI Negotiate authentication helper. +. +.SH SYNOPSIS +.if !'po4a'hide' .B negotiate_sspi_auth.exe +.if !'po4a'hide' .B [\-dhv] +. +.SH DESCRIPTION +.B negotiate_sspi_auth.exe +is an installed binary. Uses the Windows SSPI interface to perform Negotiate authentication. +. +.SH OPTIONS +.if !'po4a'hide' .TP 12 +.if !'po4a'hide' .B \-d +Write debug info to stderr. +. +.if !'po4a'hide' .TP +.if !'po4a'hide' .B \-h +Display the binary help and command line syntax info using stderr. +. +. +.if !'po4a'hide' .TP +.if !'po4a'hide' .B \-v +Display verbose Negotiate packet debugging. +. +.SH CONFIGURATION +.PP +Users that are allowed to access the web proxy must have the Windows NT +User Rights "logon from the network". +. +.PP +.B squid.conf +typical minimal required changes: +.if !'po4a'hide' .RS +.if !'po4a'hide' .B auth_param negotiate program c:/squid/libexec/mswin_negotiate_auth.exe +.if !'po4a'hide' .br +.if !'po4a'hide' .B auth_param negotiate children 5 +.if !'po4a'hide' .br +.if !'po4a'hide' .B acl password proxy_auth REQUIRED +.if !'po4a'hide' .br +.if !'po4a'hide' .B http_access deny !password +.if !'po4a'hide' .br +.if !'po4a'hide' .B http_access allow password +.if !'po4a'hide' .RE +. +.PP +Refer to Squid documentation for more details. +. +.PP +Currently Internet Explorer has some problems with ftp:// URLs when handling +internal Squid FTP icons. The following +.B squid.conf +ACL defined before authentication ACLs works around this: +.if !'po4a'hide' .RS +.if !'po4a'hide' .B acl internal_icons urlpath_regex -i /squid-internal-static/icons/ +.if !'po4a'hide' .br +.if !'po4a'hide' .B http_access allow our_networks internal_icons +.if !'po4a'hide' .RE +. +.SH AUTHOR +This program was written by +.if !'po4a'hide' .I Guido Serassio +.if !'po4a'hide' Acme Consulting S.r.l., Italy +. +.PP +Based on prior work of +.if !'po4a'hide' .I Francesco Chemolli , +.if !'po4a'hide' .I Robert Collins +. +.SH COPYRIGHT +.PP + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. +.PP +This program and documentation is copyright to the authors named above. +.PP +Distributed under the GNU General Public License (GNU GPL) version 2 or later (GPLv2+). +. +.SH QUESTIONS +Questions on the usage of this program can be sent to the +.I Squid Users mailing list +.if !'po4a'hide' +. +.SH REPORTING BUGS +Bug reports need to be made in English. +See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. +.PP +Report bugs or bug fixes using http://bugs.squid-cache.org/ +.PP +Report serious security bugs to +.I Squid Bugs +.PP +Report ideas for new improvements to the +.I Squid Developers mailing list +.if !'po4a'hide' +. +.SH SEE ALSO +.if !'po4a'hide' .BR squid "(8), " +.if !'po4a'hide' .BR GPL "(7), " +.br +The Squid FAQ wiki +.if !'po4a'hide' http://wiki.squid-cache.org/SquidFaq +.br +The Squid Configuration Manual +.if !'po4a'hide' http://www.squid-cache.org/Doc/config/ diff -u -r -N squid-4.0.21/src/auth/negotiate/SSPI/readme.txt squid-4.0.22/src/auth/negotiate/SSPI/readme.txt --- squid-4.0.21/src/auth/negotiate/SSPI/readme.txt 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/negotiate/SSPI/readme.txt 1970-01-01 12:00:00.000000000 +1200 @@ -1,41 +0,0 @@ -mswin_negotiate_auth.exe - -Native Windows Negotiate authenticator for Squid. - -===== -Usage -===== - -mswin_negotiate_auth [-d] [-v] [-h] - --d enables debugging. --v enables verbose Negotiate packet debugging. --h print program usage - -This is released under the GNU General Public License - -============== -Allowing Users -============== - -Users that are allowed to access the web proxy must have the Windows NT -User Rights "logon from the network". - -Squid.conf typical minimal required changes: - -auth_param negotiate program c:/squid/libexec/mswin_negotiate_auth.exe -auth_param negotiate children 5 - -acl password proxy_auth REQUIRED - -http_access allow password -http_access deny all - -Refer to Squid documentation for more details. - -Currently Internet Explorer has some problems with ftp:// URLs when handling -internal Squid FTP icons. The following squid.conf ACL works around this: - -acl internal_icons urlpath_regex -i /squid-internal-static/icons/ - -http_access allow our_networks internal_icons <== BEFORE authentication ACL !!! diff -u -r -N squid-4.0.21/src/auth/ntlm/SSPI/ntlm_sspi_auth.8 squid-4.0.22/src/auth/ntlm/SSPI/ntlm_sspi_auth.8 --- squid-4.0.21/src/auth/ntlm/SSPI/ntlm_sspi_auth.8 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/auth/ntlm/SSPI/ntlm_sspi_auth.8 2017-12-08 04:12:12.000000000 +1300 @@ -114,7 +114,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -123,11 +123,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/base/File.cc squid-4.0.22/src/base/File.cc --- squid-4.0.21/src/base/File.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/base/File.cc 2017-12-08 04:12:12.000000000 +1300 @@ -18,9 +18,6 @@ #if HAVE_FCNTL_H #include #endif -#if HAVE_SYS_FILE_H -#include -#endif #if HAVE_SYS_STAT_H #include #endif @@ -244,14 +241,15 @@ { SBuf buf; const auto readLimit = maxBytes + 1; // to detect excessively large files that we do not handle + char *rawBuf = buf.rawAppendStart(readLimit); #if _SQUID_WINDOWS_ DWORD result = 0; - if (!ReadFile(fd_, buf.rawSpace(readLimit), readLimit, &result, nullptr)) { + if (!ReadFile(fd_, rawBuf, readLimit, &result, nullptr)) { const auto savedError = GetLastError(); throw TexcHere(sysCallFailure("ReadFile", WindowsErrorMessage(savedError).c_str())); } #else - const auto result = ::read(fd_, buf.rawSpace(readLimit), readLimit); + const auto result = ::read(fd_, rawBuf, readLimit); if (result < 0) { const auto savedErrno = errno; throw TexcHere(sysCallError("read", savedErrno)); @@ -260,7 +258,7 @@ const auto bytesRead = static_cast(result); assert(bytesRead <= readLimit); Must(!buf.length()); - buf.forceSize(bytesRead); + buf.rawAppendFinish(rawBuf, bytesRead); if (buf.length() < minBytes) { const auto failure = buf.length() ? "premature eof" : "empty file"; diff -u -r -N squid-4.0.21/src/base/File.h squid-4.0.22/src/base/File.h --- squid-4.0.21/src/base/File.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/base/File.h 2017-12-08 04:12:12.000000000 +1300 @@ -11,6 +11,10 @@ #include "sbuf/SBuf.h" +#if HAVE_SYS_FILE_H +#include +#endif + /// How should a file be opened/created? Should it be locked? class FileOpeningConfig { diff -u -r -N squid-4.0.21/src/base/LruMap.h squid-4.0.22/src/base/LruMap.h --- squid-4.0.21/src/base/LruMap.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/base/LruMap.h 2017-12-08 04:12:12.000000000 +1300 @@ -14,19 +14,19 @@ #include #include -template class LruMap +template class LruMap { public: class Entry { public: - Entry(const char *aKey, EntryValue *t): key(aKey), value(t), date(squid_curtime) {} + Entry(const Key &aKey, EntryValue *t): key(aKey), value(t), date(squid_curtime) {} ~Entry() {delete value;} private: Entry(Entry &); Entry & operator = (Entry &); public: - std::string key; ///< the key of entry + Key key; ///< the key of entry EntryValue *value; ///< A pointer to the stored value time_t date; ///< The date the entry created }; @@ -34,18 +34,18 @@ typedef typename std::list::iterator QueueIterator; /// key:queue_item mapping for fast lookups by key - typedef std::map Map; + typedef std::map Map; typedef typename Map::iterator MapIterator; - typedef std::pair MapPair; + typedef std::pair MapPair; LruMap(int ttl, size_t size); ~LruMap(); /// Search for an entry, and return a pointer - EntryValue *get(const char *key); + EntryValue *get(const Key &key); /// Add an entry to the map - bool add(const char *key, EntryValue *t); + bool add(const Key &key, EntryValue *t); /// Delete an entry from the map - bool del(const char *key); + bool del(const Key &key); /// (Re-)set the maximum size for this map void setMemLimit(size_t aSize); /// The available size for the map @@ -64,7 +64,7 @@ void trim(); void touch(const MapIterator &i); bool del(const MapIterator &i); - void findEntry(const char *key, LruMap::MapIterator &i); + void findEntry(const Key &key, LruMap::MapIterator &i); Map storage; ///< The Key/value * pairs Queue index; ///< LRU cache index @@ -73,25 +73,25 @@ int entries_; ///< The stored entries }; -template -LruMap::LruMap(int aTtl, size_t aSize): entries_(0) +template +LruMap::LruMap(int aTtl, size_t aSize): entries_(0) { ttl = aTtl; setMemLimit(aSize); } -template -LruMap::~LruMap() +template +LruMap::~LruMap() { for (QueueIterator i = index.begin(); i != index.end(); ++i) { delete *i; } } -template +template void -LruMap::setMemLimit(size_t aSize) +LruMap::setMemLimit(size_t aSize) { if (aSize > 0) memLimit_ = aSize; @@ -99,9 +99,9 @@ memLimit_ = 0; } -template +template void -LruMap::findEntry(const char *key, LruMap::MapIterator &i) +LruMap::findEntry(const Key &key, LruMap::MapIterator &i) { i = storage.find(key); if (i == storage.end()) { @@ -121,9 +121,9 @@ i = storage.end(); } -template +template EntryValue * -LruMap::get(const char *key) +LruMap::get(const Key &key) { MapIterator i; findEntry(key, i); @@ -135,9 +135,9 @@ return NULL; } -template +template bool -LruMap::add(const char *key, EntryValue *t) +LruMap::add(const Key &key, EntryValue *t) { if (ttl == 0) return false; @@ -155,9 +155,9 @@ return true; } -template +template bool -LruMap::expired(const LruMap::Entry &entry) const +LruMap::expired(const LruMap::Entry &entry) const { if (ttl < 0) return false; @@ -165,9 +165,9 @@ return (entry.date + ttl < squid_curtime); } -template +template bool -LruMap::del(LruMap::MapIterator const &i) +LruMap::del(LruMap::MapIterator const &i) { if (i != storage.end()) { Entry *e = *i->second; @@ -180,31 +180,31 @@ return false; } -template +template bool -LruMap::del(const char *key) +LruMap::del(const Key &key) { MapIterator i; findEntry(key, i); return del(i); } -template +template void -LruMap::trim() +LruMap::trim() { while (size() >= memLimit()) { QueueIterator i = index.end(); --i; if (i != index.end()) { - del((*i)->key.c_str()); + del((*i)->key); } } } -template +template void -LruMap::touch(LruMap::MapIterator const &i) +LruMap::touch(LruMap::MapIterator const &i) { // this must not be done when nothing is being cached. if (ttl == 0) diff -u -r -N squid-4.0.21/src/cache_cf.cc squid-4.0.22/src/cache_cf.cc --- squid-4.0.21/src/cache_cf.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/cache_cf.cc 2017-12-08 04:12:12.000000000 +1300 @@ -169,9 +169,6 @@ static int parse_line(char *); static void parse_obsolete(const char *); static void parseBytesLine(size_t * bptr, const char *units); -#if USE_OPENSSL -static void parseBytesOptionValue(size_t * bptr, const char *units, char const * value); -#endif static void parseBytesLineSigned(ssize_t * bptr, const char *units); static size_t parseBytesUnits(const char *unit); static void free_all(void); @@ -915,14 +912,12 @@ } } -#if USE_OPENSSL for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) { if (!s->secure.encryptTransport) continue; debugs(3, DBG_IMPORTANT, "Initializing " << AnyP::UriScheme(s->transport.protocol) << "_port " << s->s << " TLS context"); - s->configureSslServerContext(); + s->secure.createSigningContexts(*s); } -#endif // prevent infinite fetch loops in the request parser // due to buffer full but not enough data recived to finish parse @@ -1257,7 +1252,8 @@ * Similar to the parseBytesLine function but parses the string value instead of * the current token value. */ -static void parseBytesOptionValue(size_t * bptr, const char *units, char const * value) +void +parseBytesOptionValue(size_t * bptr, const char *units, char const * value) { int u; if ((u = parseBytesUnits(units)) == 0) { @@ -3653,8 +3649,7 @@ } else if (strncmp(token, "cipher=", 7) == 0) { s->secure.parse(token); } else if (strncmp(token, "clientca=", 9) == 0) { - safe_free(s->clientca); - s->clientca = xstrdup(token + 9); + s->secure.parse(token); } else if (strncmp(token, "cafile=", 7) == 0) { debugs(3, DBG_PARSE_NOTE(1), "UPGRADE WARNING: '" << token << "' is deprecated " << "in " << cfg_directive << ". Use 'tls-cafile=' instead."); @@ -3671,17 +3666,13 @@ // NP: deprecation warnings output by secure.parse() when relevant s->secure.parse(token+3); } else if (strncmp(token, "sslcontext=", 11) == 0) { - safe_free(s->sslContextSessionId); - s->sslContextSessionId = xstrdup(token + 11); - } else if (strcmp(token, "generate-host-certificates") == 0) { - s->generateHostCertificates = true; - } else if (strcmp(token, "generate-host-certificates=on") == 0) { - s->generateHostCertificates = true; - } else if (strcmp(token, "generate-host-certificates=off") == 0) { - s->generateHostCertificates = false; - } else if (strncmp(token, "dynamic_cert_mem_cache_size=", 28) == 0) { - parseBytesOptionValue(&s->dynamicCertMemCacheSize, B_BYTES_STR, token + 28); + // NP: deprecation warnings output by secure.parse() when relevant + s->secure.parse(token+3); + } else if (strncmp(token, "generate-host-certificates", 26) == 0) { + s->secure.parse(token); #endif + } else if (strncmp(token, "dynamic_cert_mem_cache_size=", 28) == 0) { + s->secure.parse(token); } else if (strncmp(token, "tls-", 4) == 0) { s->secure.parse(token+4); } else if (strcmp(token, "ftp-track-dirs") == 0) { @@ -3736,12 +3727,7 @@ parse_port_option(s, token); } -#if USE_OPENSSL - // if clientca has been defined but not cafile, then use it to verify - // but if cafile has been defined, only use that to verify - if (s->clientca && !s->secure.caFiles.size()) - s->secure.caFiles.emplace_back(SBuf(s->clientca)); -#endif + s->secure.syncCaFiles(); if (s->transport.protocol == AnyP::PROTO_HTTPS) { s->secure.encryptTransport = true; @@ -3880,17 +3866,6 @@ #endif s->secure.dumpCfg(e, "tls-"); - -#if USE_OPENSSL - if (s->sslContextSessionId) - storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId); - - if (!s->generateHostCertificates) - storeAppendPrintf(e, " generate-host-certificates=off"); - - if (s->dynamicCertMemCacheSize != 4*1024*1024) // 4MB default - storeAppendPrintf(e, "dynamic_cert_mem_cache_size=%" PRIuSIZE "%s\n", s->dynamicCertMemCacheSize, B_BYTES_STR); -#endif } static void diff -u -r -N squid-4.0.21/src/cache_cf.h squid-4.0.22/src/cache_cf.h --- squid-4.0.21/src/cache_cf.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/cache_cf.h 2017-12-08 04:12:12.000000000 +1300 @@ -24,6 +24,8 @@ void parse_wordlist(wordlist ** list); void requirePathnameExists(const char *name, const char *path); void parse_time_t(time_t * var); +/// Parse bytes number from a string +void parseBytesOptionValue(size_t * bptr, const char *units, char const * value); #endif /* SQUID_CACHE_CF_H_ */ diff -u -r -N squid-4.0.21/src/cf.data.pre squid-4.0.22/src/cf.data.pre --- squid-4.0.21/src/cf.data.pre 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/cf.data.pre 2017-12-08 04:12:12.000000000 +1300 @@ -2375,6 +2375,8 @@ been redefined for use by ECN (RFC 3168 section 23.1). The squid parser will enforce this by masking away the ECN bits. + This clause only supports fast acl types. + See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details. DOC_END NAME: tcp_outgoing_mark @@ -2420,6 +2422,9 @@ Note: This feature is incompatible with qos_flows. Any mark values set here will be overwritten by mark values in qos_flows. + + This clause only supports fast acl types. + See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details. DOC_END NAME: qos_flows @@ -2542,6 +2547,8 @@ When needing to contact peers use the no-tproxy cache_peer option and the client_dst_passthru directive re-enable normal forwarding such as this. + This clause only supports fast acl types. + See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details. DOC_END NAME: host_verify_strict @@ -4418,6 +4425,18 @@ no certificate at all. Consider encoding the logged value because Issuer often has spaces. + ssl::cert_issuer + The Issuer field of the received server + TLS certificate or a dash ('-') if this is + not available. Consider encoding the logged + value because Issuer often has spaces. + ssl::content_range && - theFinalReply->sline.status() == Http::scPartialContent; - currentOffset = partial ? theFinalReply->content_range->spec.offset : 0; + const bool partial = theFinalReply->contentRange(); + currentOffset = partial ? theFinalReply->contentRange()->spec.offset : 0; } /// whether to prevent caching of an otherwise cachable response diff -u -r -N squid-4.0.21/src/client_side.cc squid-4.0.22/src/client_side.cc --- squid-4.0.21/src/client_side.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/client_side.cc 2017-12-08 04:12:12.000000000 +1300 @@ -2837,8 +2837,10 @@ Security::ContextPointer ctx(Security::GetFrom(fd_table[clientConnection->fd].ssl)); Ssl::configureUnconfiguredSslContext(ctx, signAlgorithm, *port); } else { - Security::ContextPointer ctx(Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), *port)); - getSslContextDone(ctx, true); + Security::ContextPointer ctx(Ssl::GenerateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), port->secure, (signAlgorithm == Ssl::algSignTrusted))); + if (ctx && !sslBumpCertKey.isEmpty()) + storeTlsContextToCache(sslBumpCertKey, ctx); + getSslContextDone(ctx); } return; } @@ -2852,9 +2854,8 @@ { certProperties.commonName = sslCommonName_.isEmpty() ? sslConnectHostOrIp.termedBuf() : sslCommonName_.c_str(); - const bool triedToConnect = sslServerBump && sslServerBump->entry; - const bool connectedOK = triedToConnect && sslServerBump->entry->isEmpty(); - if (connectedOK) { + const bool connectedOk = sslServerBump && sslServerBump->connectedOk(); + if (connectedOk) { if (X509 *mimicCert = sslServerBump->serverCert.get()) certProperties.mimicCert.resetAndLock(mimicCert); @@ -2910,21 +2911,49 @@ assert(certProperties.signAlgorithm != Ssl::algSignEnd); if (certProperties.signAlgorithm == Ssl::algSignUntrusted) { - assert(port->untrustedSigningCert.get()); - certProperties.signWithX509.resetAndLock(port->untrustedSigningCert.get()); - certProperties.signWithPkey.resetAndLock(port->untrustedSignPkey.get()); + assert(port->secure.untrustedSigningCert); + certProperties.signWithX509.resetAndLock(port->secure.untrustedSigningCert.get()); + certProperties.signWithPkey.resetAndLock(port->secure.untrustedSignPkey.get()); } else { - assert(port->signingCert.get()); - certProperties.signWithX509.resetAndLock(port->signingCert.get()); + assert(port->secure.signingCert.get()); + certProperties.signWithX509.resetAndLock(port->secure.signingCert.get()); - if (port->signPkey.get()) - certProperties.signWithPkey.resetAndLock(port->signPkey.get()); + if (port->secure.signPkey) + certProperties.signWithPkey.resetAndLock(port->secure.signPkey.get()); } signAlgorithm = certProperties.signAlgorithm; certProperties.signHash = Ssl::DefaultSignHash; } +Security::ContextPointer +ConnStateData::getTlsContextFromCache(const SBuf &cacheKey, const Ssl::CertificateProperties &certProperties) +{ + debugs(33, 5, "Finding SSL certificate for " << cacheKey << " in cache"); + Ssl::LocalContextStorage * ssl_ctx_cache = Ssl::TheGlobalContextStorage.getLocalStorage(port->s); + if (Security::ContextPointer *ctx = ssl_ctx_cache ? ssl_ctx_cache->get(cacheKey) : nullptr) { + if (Ssl::verifySslCertificate(*ctx, certProperties)) { + debugs(33, 5, "Cached SSL certificate for " << certProperties.commonName << " is valid"); + return *ctx; + } else { + debugs(33, 5, "Cached SSL certificate for " << certProperties.commonName << " is out of date. Delete this certificate from cache"); + if (ssl_ctx_cache) + ssl_ctx_cache->del(cacheKey); + } + } + return Security::ContextPointer(nullptr); +} + +void +ConnStateData::storeTlsContextToCache(const SBuf &cacheKey, Security::ContextPointer &ctx) +{ + Ssl::LocalContextStorage *ssl_ctx_cache = Ssl::TheGlobalContextStorage.getLocalStorage(port->s); + if (!ssl_ctx_cache || !ssl_ctx_cache->add(cacheKey, new Security::ContextPointer(ctx))) { + // If it is not in storage delete after using. Else storage deleted it. + fd_table[clientConnection->fd].dynamicTlsContext = ctx; + } +} + void ConnStateData::getSslContextStart() { @@ -2937,30 +2966,20 @@ } /* careful: finished() above frees request, host, etc. */ - if (port->generateHostCertificates) { + if (port->secure.generateHostCertificates) { Ssl::CertificateProperties certProperties; buildSslCertGenerationParams(certProperties); - sslBumpCertKey = certProperties.dbKey().c_str(); - assert(sslBumpCertKey.size() > 0 && sslBumpCertKey[0] != '\0'); // Disable caching for bumpPeekAndSplice mode if (!(sslServerBump && (sslServerBump->act.step1 == Ssl::bumpPeek || sslServerBump->act.step1 == Ssl::bumpStare))) { - debugs(33, 5, "Finding SSL certificate for " << sslBumpCertKey << " in cache"); - Ssl::LocalContextStorage * ssl_ctx_cache = Ssl::TheGlobalContextStorage.getLocalStorage(port->s); - Security::ContextPointer *cachedCtx = ssl_ctx_cache ? ssl_ctx_cache->get(sslBumpCertKey.termedBuf()) : nullptr; - if (cachedCtx) { - debugs(33, 5, "SSL certificate for " << sslBumpCertKey << " found in cache"); - if (Ssl::verifySslCertificate(*cachedCtx, certProperties)) { - debugs(33, 5, "Cached SSL certificate for " << sslBumpCertKey << " is valid"); - getSslContextDone(*cachedCtx); - return; - } else { - debugs(33, 5, "Cached SSL certificate for " << sslBumpCertKey << " is out of date. Delete this certificate from cache"); - if (ssl_ctx_cache) - ssl_ctx_cache->del(sslBumpCertKey.termedBuf()); - } - } else { - debugs(33, 5, "SSL certificate for " << sslBumpCertKey << " haven't found in cache"); + sslBumpCertKey.clear(); + Ssl::InRamCertificateDbKey(certProperties, sslBumpCertKey); + assert(!sslBumpCertKey.isEmpty()); + + Security::ContextPointer ctx(getTlsContextFromCache(sslBumpCertKey, certProperties)); + if (ctx) { + getSslContextDone(ctx); + return; } } @@ -2992,8 +3011,10 @@ Security::ContextPointer ctx(Security::GetFrom(fd_table[clientConnection->fd].ssl)); Ssl::configureUnconfiguredSslContext(ctx, certProperties.signAlgorithm, *port); } else { - Security::ContextPointer dynCtx(Ssl::generateSslContext(certProperties, *port)); - getSslContextDone(dynCtx, true); + Security::ContextPointer dynCtx(Ssl::GenerateSslContext(certProperties, port->secure, (signAlgorithm == Ssl::algSignTrusted))); + if (dynCtx && !sslBumpCertKey.isEmpty()) + storeTlsContextToCache(sslBumpCertKey, dynCtx); + getSslContextDone(dynCtx); } return; } @@ -3003,28 +3024,10 @@ } void -ConnStateData::getSslContextDone(Security::ContextPointer &ctx, bool isNew) +ConnStateData::getSslContextDone(Security::ContextPointer &ctx) { - // Try to add generated ssl context to storage. - if (port->generateHostCertificates && isNew) { - - if (ctx && (signAlgorithm == Ssl::algSignTrusted)) { - Ssl::chainCertificatesToSSLContext(ctx, *port); - } else if (signAlgorithm == Ssl::algSignTrusted) { - debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain because SSL context chain is invalid!"); - } - //else it is self-signed or untrusted do not attrach any certificate - - Ssl::LocalContextStorage *ssl_ctx_cache = Ssl::TheGlobalContextStorage.getLocalStorage(port->s); - assert(sslBumpCertKey.size() > 0 && sslBumpCertKey[0] != '\0'); - if (ctx) { - if (!ssl_ctx_cache || !ssl_ctx_cache->add(sslBumpCertKey.termedBuf(), new Security::ContextPointer(ctx))) { - // If it is not in storage delete after using. Else storage deleted it. - fd_table[clientConnection->fd].dynamicTlsContext = ctx; - } - } else { - debugs(33, 2, HERE << "Failed to generate SSL cert for " << sslConnectHostOrIp); - } + if (port->secure.generateHostCertificates && !ctx) { + debugs(33, 2, "Failed to generate TLS cotnext for " << sslConnectHostOrIp); } // If generated ssl context = NULL, try to use static ssl context. @@ -3255,7 +3258,7 @@ } // will call httpsPeeked() with certificate and connection, eventually - Security::ContextPointer unConfiguredCTX(Ssl::createSSLContext(port->signingCert, port->signPkey, *port)); + Security::ContextPointer unConfiguredCTX(Ssl::createSSLContext(port->secure.signingCert, port->secure.signPkey, port->secure)); fd_table[clientConnection->fd].dynamicTlsContext = unConfiguredCTX; if (!httpsCreate(clientConnection, unConfiguredCTX)) @@ -3487,7 +3490,7 @@ debugs(33, DBG_IMPORTANT, "WARNING: No ssl_bump configured. Disabling ssl-bump on " << scheme << "_port " << s->s); s->flags.tunnelSslBumping = false; } - if (!s->secure.staticContext && !s->generateHostCertificates) { + if (!s->secure.staticContext && !s->secure.generateHostCertificates) { debugs(1, DBG_IMPORTANT, "Will not bump SSL at " << scheme << "_port " << s->s << " due to TLS initialization failure."); s->flags.tunnelSslBumping = false; if (s->transport.protocol == AnyP::PROTO_HTTP) @@ -3495,8 +3498,7 @@ } if (s->flags.tunnelSslBumping) { // Create ssl_ctx cache for this port. - auto sz = s->dynamicCertMemCacheSize == std::numeric_limits::max() ? 4194304 : s->dynamicCertMemCacheSize; - Ssl::TheGlobalContextStorage.addLocalStorage(s->s, sz); + Ssl::TheGlobalContextStorage.addLocalStorage(s->s, s->secure.dynamicCertMemCacheSize); } } diff -u -r -N squid-4.0.21/src/client_side.h squid-4.0.22/src/client_side.h --- squid-4.0.21/src/client_side.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/client_side.h 2017-12-08 04:12:12.000000000 +1300 @@ -235,12 +235,10 @@ /// Start to create dynamic Security::ContextPointer for host or uses static port SSL context. void getSslContextStart(); - /** - * Done create dynamic ssl certificate. - * - * \param[in] isNew if generated certificate is new, so we need to add this certificate to storage. - */ - void getSslContextDone(Security::ContextPointer &, bool isNew = false); + + /// finish configuring the newly created SSL context" + void getSslContextDone(Security::ContextPointer &); + /// Callback function. It is called when squid receive message from ssl_crtd. static void sslCrtdHandleReplyWrapper(void *data, const Helper::Reply &reply); /// Proccess response from ssl_crtd. @@ -369,6 +367,15 @@ bool parseProxy2p0(); bool proxyProtocolError(const char *reason); +#if USE_OPENSSL + /// \returns a pointer to the matching cached TLS context or nil + Security::ContextPointer getTlsContextFromCache(const SBuf &cacheKey, const Ssl::CertificateProperties &certProperties); + + /// Attempts to add a given TLS context to the cache, replacing the old + /// same-key context, if any + void storeTlsContextToCache(const SBuf &cacheKey, Security::ContextPointer &ctx); +#endif + /// whether PROXY protocol header is still expected bool needProxyProtocolHeader_; @@ -390,7 +397,7 @@ /// TLS client delivered SNI value. Empty string if none has been received. SBuf tlsClientSni_; - String sslBumpCertKey; ///< Key to use to store/retrieve generated certificate + SBuf sslBumpCertKey; ///< Key to use to store/retrieve generated certificate /// HTTPS server cert. fetching state for bump-ssl-server-first Ssl::ServerBump *sslServerBump; diff -u -r -N squid-4.0.21/src/client_side_reply.cc squid-4.0.22/src/client_side_reply.cc --- squid-4.0.21/src/client_side_reply.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/client_side_reply.cc 2017-12-08 04:12:12.000000000 +1300 @@ -308,6 +308,7 @@ } if (entry) { + entry->ensureMemObject(url, http->log_uri, http->request->method); debugs(88, 5, "collapsed on existing revalidation entry: " << *entry); collapsedRevalidation = crSlave; } else { @@ -670,7 +671,7 @@ */ http->logType = LOG_TCP_CLIENT_REFRESH_MISS; processMiss(); - } else if (r->url.getScheme() == AnyP::PROTO_HTTP) { + } else if (r->url.getScheme() == AnyP::PROTO_HTTP || r->url.getScheme() == AnyP::PROTO_HTTPS) { debugs(88, 3, "validate HIT object? YES."); /* * Object needs to be revalidated @@ -993,7 +994,7 @@ http->storeEntry(entry); http->storeEntry()->lock("clientReplyContext::purgeFoundObject"); - http->storeEntry()->createMemObject(storeId(), http->log_uri, + http->storeEntry()->ensureMemObject(storeId(), http->log_uri, http->request->method); sc = storeClientListAdd(http->storeEntry(), this); @@ -1844,22 +1845,7 @@ http->storeEntry()->lock("clientReplyContext::doGetMoreData"); - MemObject *mem_obj = http->storeEntry()->makeMemObject(); - if (!mem_obj->hasUris()) { - /* - * This if-block exists because we don't want to clobber - * a preexiting mem_obj->method value if the mem_obj - * already exists. For example, when a HEAD request - * is a cache hit for a GET response, we want to keep - * the method as GET. - */ - mem_obj->setUris(storeId(), http->log_uri, http->request->method); - /** - * Here we can see if the object was - * created using URL or alternative StoreID from helper. - */ - debugs(88, 3, "storeId: " << http->storeEntry()->mem_obj->storeId()); - } + http->storeEntry()->ensureMemObject(storeId(), http->log_uri, http->request->method); sc = storeClientListAdd(http->storeEntry(), this); #if USE_DELAY_POOLS diff -u -r -N squid-4.0.21/src/client_side_request.cc squid-4.0.22/src/client_side_request.cc --- squid-4.0.21/src/client_side_request.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/client_side_request.cc 2017-12-08 04:12:12.000000000 +1300 @@ -344,7 +344,7 @@ /* allow size for url rewriting */ url_sz = strlen(url) + Config.appendDomainLen + 5; http->uri = (char *)xcalloc(url_sz, 1); - strcpy(http->uri, url); + strcpy(http->uri, url); // XXX: polluting http->uri before parser validation if ((request = HttpRequest::FromUrl(http->uri, mx, method)) == NULL) { debugs(85, 5, "Invalid URL: " << http->uri); @@ -1265,7 +1265,7 @@ // prevent broken helpers causing too much damage. If old URL == new URL skip the re-write. if (urlNote != NULL && strcmp(urlNote, http->uri)) { URL tmpUrl; - if (tmpUrl.parse(old_request->method, const_cast(urlNote))) { + if (tmpUrl.parse(old_request->method, urlNote)) { HttpRequest *new_request = old_request->clone(); new_request->url = tmpUrl; debugs(61, 2, "URL-rewriter diverts URL from " << old_request->effectiveRequestUri() << " to " << new_request->effectiveRequestUri()); diff -u -r -N squid-4.0.21/src/comm/Read.cc squid-4.0.22/src/comm/Read.cc --- squid-4.0.21/src/comm/Read.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/comm/Read.cc 2017-12-08 04:12:12.000000000 +1300 @@ -84,7 +84,7 @@ SBuf::size_type sz = buf.spaceSize(); if (params.size > 0 && params.size < sz) sz = params.size; - char *inbuf = buf.rawSpace(sz); + char *inbuf = buf.rawAppendStart(sz); errno = 0; const int retval = FD_READ_METHOD(params.conn->fd, inbuf, sz); params.xerrno = errno; @@ -92,7 +92,7 @@ debugs(5, 3, params.conn << ", size " << sz << ", retval " << retval << ", errno " << params.xerrno); if (retval > 0) { // data read most common case - buf.append(inbuf, retval); + buf.rawAppendFinish(inbuf, retval); fd_bytes(params.conn->fd, retval, FD_READ); params.flag = Comm::OK; params.size = retval; diff -u -r -N squid-4.0.21/src/debug.cc squid-4.0.22/src/debug.cc --- squid-4.0.21/src/debug.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/debug.cc 2017-12-08 04:12:12.000000000 +1300 @@ -26,8 +26,6 @@ int Debug::Levels[MAX_DEBUG_SECTIONS]; char *Debug::cache_log = NULL; int Debug::rotateNumber = -1; -FILE *debug_log = NULL; -static char *debug_log_file = NULL; static int Ctx_Lock = 0; static const char *debugLogTime(void); static const char *debugLogKid(void); @@ -46,6 +44,70 @@ typedef BOOL (WINAPI * PFInitializeCriticalSectionAndSpinCount) (LPCRITICAL_SECTION, DWORD); #endif +/// a (FILE*, file name) pair that uses stderr FILE as the last resort +class DebugFile +{ +public: + DebugFile() {} + ~DebugFile() { clear(); } + DebugFile(DebugFile &&) = delete; // no copying or moving of any kind + + /// switches to the new pair, absorbing FILE and duping the name + void reset(FILE *newFile, const char *newName); + + /// go back to the initial state + void clear() { reset(nullptr, nullptr); } + + /// logging stream; the only method that uses stderr as the last resort + FILE *file() { return file_ ? file_ : stderr; } + + char *name = nullptr; + +private: + friend void ResyncDebugLog(FILE *newFile); + + FILE *file_ = nullptr; ///< opened "real" file or nil; never stderr +}; + +/// configured cache.log file or stderr +/// safe during static initialization, even if it has not been constructed yet +static DebugFile TheLog; + +FILE * +DebugStream() { + return TheLog.file(); +} + +void +StopUsingDebugLog() +{ + TheLog.clear(); +} + +void +ResyncDebugLog(FILE *newFile) +{ + TheLog.file_ = newFile; +} + +void +DebugFile::reset(FILE *newFile, const char *newName) +{ + // callers must use nullptr instead of the used-as-the-last-resort stderr + assert(newFile != stderr || !stderr); + + if (file_) + fclose(file_); + file_ = newFile; // may be nil + + xfree(name); + name = newName ? xstrdup(newName) : nullptr; + + // all open files must have a name + // all cleared files must not have a name + assert(!file_ == !name); +} + void _db_print(const char *format,...) { @@ -210,18 +272,10 @@ debugOpenLog(const char *logfile) { if (logfile == NULL) { - debug_log = stderr; + TheLog.clear(); return; } - if (debug_log_file) - xfree(debug_log_file); - - debug_log_file = xstrdup(logfile); /* keep a static copy */ - - if (debug_log && debug_log != stderr) - fclose(debug_log); - // Bug 4423: ignore the stdio: logging module name if present const char *logfilename; if (strncmp(logfile, "stdio:",6) == 0) @@ -229,19 +283,18 @@ else logfilename = logfile; - debug_log = fopen(logfilename, "a+"); - - if (!debug_log) { + if (auto log = fopen(logfilename, "a+")) { +#if _SQUID_WINDOWS_ + setmode(fileno(log), O_TEXT); +#endif + TheLog.reset(log, logfilename); + } else { fprintf(stderr, "WARNING: Cannot write log file: %s\n", logfile); perror(logfile); fprintf(stderr, " messages will be sent to 'stderr'.\n"); fflush(stderr); - debug_log = stderr; + TheLog.clear(); } - -#if _SQUID_WINDOWS_ - setmode(fileno(debug_log), O_TEXT); -#endif } #if HAVE_SYSLOG @@ -445,12 +498,12 @@ void _db_rotate_log(void) { - if (debug_log_file == NULL) + if (!TheLog.name) return; #ifdef S_ISREG struct stat sb; - if (stat(debug_log_file, &sb) == 0) + if (stat(TheLog.name, &sb) == 0) if (S_ISREG(sb.st_mode) == 0) return; #endif @@ -469,8 +522,8 @@ /* Rotate numbers 0 through N up one */ for (int i = Debug::rotateNumber; i > 1;) { --i; - snprintf(from, MAXPATHLEN, "%s.%d", debug_log_file, i - 1); - snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, i); + snprintf(from, MAXPATHLEN, "%s.%d", TheLog.name, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", TheLog.name, i); #if _SQUID_WINDOWS_ remove (to); @@ -482,36 +535,31 @@ } } - /* - * You can't rename open files on Microsoft "operating systems" - * so we close before renaming. - */ -#if _SQUID_WINDOWS_ - if (debug_log != stderr) - fclose(debug_log); -#endif /* Rotate the current log to .0 */ if (Debug::rotateNumber > 0) { - snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, 0); + // form file names before we may clear TheLog below + snprintf(from, MAXPATHLEN, "%s", TheLog.name); + snprintf(to, MAXPATHLEN, "%s.%d", TheLog.name, 0); + #if _SQUID_WINDOWS_ errno = 0; if (remove(to) == -1) { const auto saved_errno = errno; debugs(0, DBG_IMPORTANT, "removal of log file " << to << " failed: " << xstrerr(saved_errno)); } + TheLog.clear(); // Windows cannot rename() open files #endif errno = 0; - if (rename(debug_log_file, to) == -1) { + if (rename(from, to) == -1) { const auto saved_errno = errno; - debugs(0, DBG_IMPORTANT, "renaming file " << debug_log_file << " to " + debugs(0, DBG_IMPORTANT, "renaming file " << from << " to " << to << "failed: " << xstrerr(saved_errno)); } } - /* Close and reopen the log. It may have been renamed "manually" - * before HUP'ing us. */ - if (debug_log != stderr) - debugOpenLog(Debug::cache_log); + // Close (if we have not already) and reopen the log because + // it may have been renamed "manually" before HUP'ing us. + debugOpenLog(Debug::cache_log); } static const char * diff -u -r -N squid-4.0.21/src/Debug.h squid-4.0.22/src/Debug.h --- squid-4.0.21/src/Debug.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/Debug.h 2017-12-08 04:12:12.000000000 +1300 @@ -99,7 +99,17 @@ static Context *Current; ///< deepest active context; nil outside debugs() }; -extern FILE *debug_log; +/// cache.log FILE or, as the last resort, stderr stream; +/// may be nil during static initialization and destruction! +FILE *DebugStream(); +/// change-avoidance macro; new code should call DebugStream() instead +#define debug_log DebugStream() + +/// start logging to stderr (instead of cache.log, if any) +void StopUsingDebugLog(); + +/// a hack for low-level file descriptor manipulations in ipcCreate() +void ResyncDebugLog(FILE *newDestination); size_t BuildPrefixInit(); const char * SkipBuildPrefix(const char* path); diff -u -r -N squid-4.0.21/src/Downloader.cc squid-4.0.22/src/Downloader.cc --- squid-4.0.21/src/Downloader.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/Downloader.cc 2017-12-08 04:12:12.000000000 +1300 @@ -128,12 +128,10 @@ { const HttpRequestMethod method = Http::METHOD_GET; - char *uri = xstrdup(url_.c_str()); const MasterXaction::Pointer mx = new MasterXaction(initiator_); - HttpRequest *const request = HttpRequest::FromUrl(uri, mx, method); + HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); if (!request) { debugs(33, 5, "Invalid URI: " << url_); - xfree(uri); return false; //earlyError(...) } request->http_ver = Http::ProtocolVersion(); @@ -156,7 +154,8 @@ http->request = request; HTTPMSGLOCK(http->request); http->req_sz = 0; - http->uri = uri; + // XXX: performance regression. c_str() reallocates + http->uri = xstrdup(url_.c_str()); setLogUri (http, urlCanonicalClean(request)); context_ = new DownloaderContext(this, http); diff -u -r -N squid-4.0.21/src/external_acl.cc squid-4.0.22/src/external_acl.cc --- squid-4.0.21/src/external_acl.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/external_acl.cc 2017-12-08 04:12:12.000000000 +1300 @@ -301,13 +301,31 @@ (*fmt)->data.header.header = (*fmt)->data.string; } else #endif - { - // we can use the Format::Token::parse() method since it - // only pulls off one token. Since we already checked - // for '%' prefix above this is guaranteed to be a token. - const size_t len = (*fmt)->parse(token, "e); - assert(len == strlen(token)); - } + if (strncmp(token,"%<{", 3) == 0) { + SBuf tmp("%parse(tmp.c_str(), "e); + assert(parsedLen == tmp.length()); + assert((*fmt)->type == Format::LFT_REPLY_HEADER || + (*fmt)->type == Format::LFT_REPLY_HEADER_ELEM); + + } else if (strncmp(token,"%>{", 3) == 0) { + SBuf tmp("%>ha"); + tmp.append(token+2); + debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type format %>{...} is deprecated. Use " << tmp); + const size_t parsedLen = (*fmt)->parse(tmp.c_str(), "e); + assert(parsedLen == tmp.length()); + assert((*fmt)->type == Format::LFT_ADAPTED_REQUEST_HEADER || + (*fmt)->type == Format::LFT_ADAPTED_REQUEST_HEADER_ELEM); + + } else { + // we can use the Format::Token::parse() method since it + // only pulls off one token. Since we already checked + // for '%' prefix above this is guaranteed to be a token. + const size_t len = (*fmt)->parse(token, "e); + assert(len == strlen(token)); + } // process special token-specific actions (only if necessary) #if USE_AUTH diff -u -r -N squid-4.0.21/src/format/Token.cc squid-4.0.22/src/format/Token.cc --- squid-4.0.21/src/format/Token.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/format/Token.cc 2017-12-08 04:12:12.000000000 +1300 @@ -152,6 +152,7 @@ TokenTableEntry("DATA", LFT_EXT_ACL_DATA), TokenTableEntry("DST", LFT_CLIENT_REQ_URLDOMAIN), TokenTableEntry("EXT_LOG", LFT_EXT_LOG), + TokenTableEntry("EXT_TAG", LFT_TAG), TokenTableEntry("EXT_USER", LFT_USER_EXTERNAL), TokenTableEntry("IDENT", LFT_USER_IDENT), TokenTableEntry("LOGIN", LFT_USER_LOGIN), diff -u -r -N squid-4.0.21/src/fs/rock/RockHeaderUpdater.cc squid-4.0.22/src/fs/rock/RockHeaderUpdater.cc --- squid-4.0.21/src/fs/rock/RockHeaderUpdater.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/fs/rock/RockHeaderUpdater.cc 2017-12-08 04:12:12.000000000 +1300 @@ -98,24 +98,25 @@ void Rock::HeaderUpdater::NoteRead(void *data, const char *buf, ssize_t result, StoreIOState::Pointer) { + IoCbParams io(buf, result); // TODO: Avoid Rock::StoreIOStateCb for jobs to protect jobs for "free". CallJobHere1(47, 7, CbcPointer(static_cast(data)), Rock::HeaderUpdater, noteRead, - result); + io); } void -Rock::HeaderUpdater::noteRead(ssize_t result) +Rock::HeaderUpdater::noteRead(const Rock::HeaderUpdater::IoCbParams result) { - debugs(47, 7, result); - if (!result) { // EOF + debugs(47, 7, result.size); + if (!result.size) { // EOF stopReading("eof"); } else { - Must(result > 0); - bytesRead += result; - readerBuffer.forceSize(readerBuffer.length() + result); + Must(result.size > 0); + bytesRead += result.size; + readerBuffer.rawAppendFinish(result.buf, result.size); exchangeBuffer.append(readerBuffer); debugs(47, 7, "accumulated " << exchangeBuffer.length()); } @@ -130,7 +131,7 @@ Must(reader); readerBuffer.clear(); storeRead(reader, - readerBuffer.rawSpace(store->slotSize), + readerBuffer.rawAppendStart(store->slotSize), store->slotSize, bytesRead, &NoteRead, diff -u -r -N squid-4.0.21/src/fs/rock/RockHeaderUpdater.h squid-4.0.22/src/fs/rock/RockHeaderUpdater.h --- squid-4.0.21/src/fs/rock/RockHeaderUpdater.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/fs/rock/RockHeaderUpdater.h 2017-12-08 04:12:12.000000000 +1300 @@ -28,6 +28,12 @@ CBDATA_CHILD(HeaderUpdater); public: + class IoCbParams { + public: + IoCbParams(const char *aBuf, ssize_t aSize) : buf(aBuf), size(aSize) {} + const char *buf; + ssize_t size; + }; HeaderUpdater(const Rock::SwapDir::Pointer &aStore, const Ipc::StoreMapUpdate &update); virtual ~HeaderUpdater() override = default; @@ -45,7 +51,7 @@ void startReading(); void stopReading(const char *why); void readMore(const char *why); - void noteRead(ssize_t result); + void noteRead(const IoCbParams result); void noteDoneReading(int errflag); void parseReadBytes(); @@ -67,6 +73,13 @@ SlotId staleSplicingPointNext; ///< non-updatable old HTTP body suffix start }; +inline +std::ostream &operator <<(std::ostream &os, const HeaderUpdater::IoCbParams ¶ms) +{ + os << static_cast(params.buf) << "," << params.size; + return os; +} + } // namespace Rock #endif /* SQUID_FS_ROCK_HEADER_UPDATER_H */ diff -u -r -N squid-4.0.21/src/fs_io.cc squid-4.0.22/src/fs_io.cc --- squid-4.0.21/src/fs_io.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/fs_io.cc 2017-12-08 04:12:12.000000000 +1300 @@ -117,7 +117,7 @@ close(fd); - debugs(6, F->flags.close_request ? 2 : 5, "file_close: FD " << fd << " really closing\n"); + debugs(6, F->flags.close_request ? 2 : 5, "file_close: FD " << fd << " really closing"); fd_close(fd); diff -u -r -N squid-4.0.21/src/htcp.cc squid-4.0.22/src/htcp.cc --- squid-4.0.21/src/htcp.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/htcp.cc 2017-12-08 04:12:12.000000000 +1300 @@ -680,6 +680,11 @@ const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp); s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method); + if (!s->request) { + debugs(31, 3, "failed to create request. Invalid URI?"); + return nil; + } + return s; } diff -u -r -N squid-4.0.21/src/http/Stream.cc squid-4.0.22/src/http/Stream.cc --- squid-4.0.21/src/http/Stream.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/http/Stream.cc 2017-12-08 04:12:12.000000000 +1300 @@ -163,12 +163,12 @@ return start; } - } else if (reply && reply->content_range) { + } else if (reply && reply->contentRange()) { /* request does not have ranges, but reply does */ /** \todo FIXME: should use range_iter_pos on reply, as soon as reply->content_range * becomes HttpHdrRange rather than HttpHdrRangeSpec. */ - return http->out.offset + reply->content_range->spec.offset; + return http->out.offset + reply->contentRange()->spec.offset; } return http->out.offset; @@ -221,14 +221,14 @@ // we got everything we wanted from the store return STREAM_COMPLETE; } - } else if (reply && reply->content_range) { + } else if (reply && reply->contentRange()) { /* reply has content-range, but Squid is not managing ranges */ const int64_t &bytesSent = http->out.offset; - const int64_t &bytesExpected = reply->content_range->spec.length; + const int64_t &bytesExpected = reply->contentRange()->spec.length; debugs(33, 7, "body bytes sent vs. expected: " << bytesSent << " ? " << bytesExpected << " (+" << - reply->content_range->spec.offset << ")"); + reply->contentRange()->spec.offset << ")"); // did we get at least what we expected, based on range specs? @@ -399,13 +399,20 @@ assert(request->range); /* check if we still want to do ranges */ int64_t roffLimit = request->getRangeOffsetLimit(); + auto contentRange = rep ? rep->contentRange() : nullptr; if (!rep) range_err = "no [parse-able] reply"; else if ((rep->sline.status() != Http::scOkay) && (rep->sline.status() != Http::scPartialContent)) range_err = "wrong status code"; - else if (hdr->has(Http::HdrType::CONTENT_RANGE)) - range_err = "origin server does ranges"; + else if (rep->sline.status() == Http::scPartialContent) + range_err = "too complex response"; // probably contains what the client needs + else if (rep->sline.status() != Http::scOkay) + range_err = "wrong status code"; + else if (hdr->has(Http::HdrType::CONTENT_RANGE)) { + Must(!contentRange); // this is a 200, not 206 response + range_err = "meaningless response"; // the status code or the header is wrong + } else if (rep->content_length < 0) range_err = "unknown length"; else if (rep->content_length != http->memObject()->getReply()->content_length) @@ -440,8 +447,9 @@ // web server responded with a valid, but unexpected range. // will (try-to) forward as-is. //TODO: we should cope with multirange request/responses - bool replyMatchRequest = rep->content_range != nullptr ? - request->range->contains(rep->content_range->spec) : + // TODO: review, since rep->content_range is always nil here. + bool replyMatchRequest = contentRange != nullptr ? + request->range->contains(contentRange->spec) : true; const int spec_count = http->request->range->specs.size(); int64_t actual_clen = -1; @@ -452,19 +460,18 @@ /* append appropriate header(s) */ if (spec_count == 1) { if (!replyMatchRequest) { - hdr->delById(Http::HdrType::CONTENT_RANGE); - hdr->putContRange(rep->content_range); + hdr->putContRange(contentRange); actual_clen = rep->content_length; //http->range_iter.pos = rep->content_range->spec.begin(); - (*http->range_iter.pos)->offset = rep->content_range->spec.offset; - (*http->range_iter.pos)->length = rep->content_range->spec.length; + (*http->range_iter.pos)->offset = contentRange->spec.offset; + (*http->range_iter.pos)->length = contentRange->spec.length; } else { HttpHdrRange::iterator pos = http->request->range->begin(); assert(*pos); /* append Content-Range */ - if (!hdr->has(Http::HdrType::CONTENT_RANGE)) { + if (!contentRange) { /* No content range, so this was a full object we are * sending parts of. */ diff -u -r -N squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-4.0.22/src/http/url_rewriters/LFS/url_lfs_rewrite.8 --- squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2017-07-02 20:57:35.000000000 +1200 +++ squid-4.0.22/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2017-12-08 06:19:02.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "URL_LFS_REWRITE 8" -.TH URL_LFS_REWRITE 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH URL_LFS_REWRITE 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -229,12 +229,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in squid-4.0.22/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in --- squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -107,9 +107,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/HttpHdrCc.h squid-4.0.22/src/HttpHdrCc.h --- squid-4.0.21/src/HttpHdrCc.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpHdrCc.h 2017-12-08 04:12:12.000000000 +1300 @@ -30,7 +30,7 @@ CC_MIN_FRESH, CC_ONLY_IF_CACHED, CC_STALE_IF_ERROR, - CC_IMMUTABLE, /* draft-mcmanus-immutable-00 */ + CC_IMMUTABLE, /* RFC 8246 */ CC_OTHER, CC_ENUM_END /* also used to mean "invalid" */ }; diff -u -r -N squid-4.0.21/src/HttpHdrRange.cc squid-4.0.22/src/HttpHdrRange.cc --- squid-4.0.21/src/HttpHdrRange.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpHdrRange.cc 2017-12-08 04:12:12.000000000 +1300 @@ -372,8 +372,8 @@ { assert(rep); - if (rep->content_range) - clen = rep->content_range->elength; + if (rep->contentRange()) + clen = rep->contentRange()->elength; else clen = rep->content_length; @@ -527,7 +527,7 @@ } bool -HttpHdrRange::contains(HttpHdrRangeSpec& r) const +HttpHdrRange::contains(const HttpHdrRangeSpec& r) const { assert(r.length >= 0); HttpHdrRangeSpec::HttpRange rrange(r.offset, r.offset + r.length); diff -u -r -N squid-4.0.21/src/HttpHeaderRange.h squid-4.0.22/src/HttpHeaderRange.h --- squid-4.0.21/src/HttpHeaderRange.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpHeaderRange.h 2017-12-08 04:12:12.000000000 +1300 @@ -78,7 +78,7 @@ int64_t firstOffset() const; int64_t lowestOffset(int64_t) const; bool offsetLimitExceeded(const int64_t limit) const; - bool contains(HttpHdrRangeSpec& r) const; + bool contains(const HttpHdrRangeSpec& r) const; std::vector specs; private: diff -u -r -N squid-4.0.21/src/HttpReply.cc squid-4.0.22/src/HttpReply.cc --- squid-4.0.21/src/HttpReply.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpReply.cc 2017-12-08 04:12:12.000000000 +1300 @@ -25,9 +25,16 @@ #include "Store.h" #include "StrList.h" -HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0), - expires (0), surrogate_control (NULL), content_range (NULL), keep_alive (0), - protoPrefix("HTTP/"), bodySizeMax(-2) +HttpReply::HttpReply(): + HttpMsg(hoReply), + date(0), + last_modified(0), + expires(0), + surrogate_control(nullptr), + keep_alive(0), + protoPrefix("HTTP/"), + bodySizeMax(-2), + content_range(nullptr) { init(); } @@ -304,7 +311,8 @@ date = header.getTime(Http::HdrType::DATE); last_modified = header.getTime(Http::HdrType::LAST_MODIFIED); surrogate_control = header.getSc(); - content_range = header.getContRange(); + content_range = (sline.status() == Http::scPartialContent) ? + header.getContRange() : nullptr; keep_alive = persistent() ? 1 : 0; const char *str = header.getStr(Http::HdrType::CONTENT_TYPE); @@ -317,6 +325,13 @@ expires = hdrExpirationTime(); } +const HttpHdrContRange * +HttpReply::contentRange() const +{ + assert(!content_range || sline.status() == Http::scPartialContent); + return content_range; +} + /* sync this routine when you update HttpReply struct */ void HttpReply::hdrCacheClean() diff -u -r -N squid-4.0.21/src/HttpReply.h squid-4.0.22/src/HttpReply.h --- squid-4.0.21/src/HttpReply.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpReply.h 2017-12-08 04:12:12.000000000 +1300 @@ -52,7 +52,8 @@ HttpHdrSc *surrogate_control; - HttpHdrContRange *content_range; + /// \returns parsed Content-Range for a 206 response and nil for others + const HttpHdrContRange *contentRange() const; short int keep_alive; @@ -142,6 +143,8 @@ mutable int64_t bodySizeMax; /**< cached result of calcMaxBodySize */ + HttpHdrContRange *content_range; ///< parsed Content-Range; nil for non-206 responses! + protected: virtual void packFirstLineInto(Packable * p, bool) const { sline.packInto(p); } diff -u -r -N squid-4.0.21/src/HttpRequest.cc squid-4.0.22/src/HttpRequest.cc --- squid-4.0.21/src/HttpRequest.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpRequest.cc 2017-12-08 04:12:12.000000000 +1300 @@ -332,7 +332,7 @@ * (char *) end = '\0'; // temp terminate URI, XXX dangerous? - const bool ret = url.parse(method, (char *) start); + const bool ret = url.parse(method, start); * (char *) end = save; @@ -520,7 +520,7 @@ * If the request cannot be created cleanly, NULL is returned */ HttpRequest * -HttpRequest::FromUrl(char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method) +HttpRequest::FromUrl(const char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method) { std::unique_ptr req(new HttpRequest(mx)); if (req->url.parse(method, url)) { diff -u -r -N squid-4.0.21/src/HttpRequest.h squid-4.0.22/src/HttpRequest.h --- squid-4.0.21/src/HttpRequest.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/HttpRequest.h 2017-12-08 04:12:12.000000000 +1300 @@ -201,7 +201,7 @@ static void httpRequestPack(void *obj, Packable *p); - static HttpRequest * FromUrl(char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET); + static HttpRequest * FromUrl(const char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET); ConnStateData *pinnedConnection(); diff -u -r -N squid-4.0.21/src/icmp/IcmpPinger.cc squid-4.0.22/src/icmp/IcmpPinger.cc --- squid-4.0.21/src/icmp/IcmpPinger.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/icmp/IcmpPinger.cc 2017-12-08 04:12:12.000000000 +1300 @@ -177,7 +177,7 @@ if (0 == n) { /* EOF indicator */ - debugs(42, DBG_CRITICAL, HERE << "EOF encountered. Pinger exiting.\n"); + debugs(42, DBG_CRITICAL, "EOF encountered. Pinger exiting."); errno = 0; Close(); exit(1); diff -u -r -N squid-4.0.21/src/icmp/net_db.cc squid-4.0.22/src/icmp/net_db.cc --- squid-4.0.21/src/icmp/net_db.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/icmp/net_db.cc 2017-12-08 04:12:12.000000000 +1300 @@ -132,9 +132,9 @@ netdbHashInsert(netdbEntry * n, Ip::Address &addr) { networkFromInaddr(addr).toStr(n->network, MAX_IPSTRLEN); - n->hash.key = n->network; + n->key = n->network; assert(hash_lookup(addr_table, n->network) == NULL); - hash_join(addr_table, &n->hash); + hash_join(addr_table, n); } static void @@ -154,7 +154,7 @@ next(e ? e->hosts : nullptr), net_db_entry(e) { - hash.key = xstrdup(hostname); + key = xstrdup(hostname); if (e) { e->hosts = this; ++ e->link_count; @@ -166,7 +166,7 @@ { net_db_name *x = new net_db_name(hostname, n); assert(hash_lookup(host_table, hostname) == NULL); - hash_join(host_table, &x->hash); + hash_join(host_table, x); } static void @@ -525,7 +525,7 @@ (int) n->last_use_time); for (x = n->hosts; x; x = x->next) - logfilePrintf(lf, " %s", hashKeyStr(&x->hash)); + logfilePrintf(lf, " %s", hashKeyStr(x)); logfilePrintf(lf, "\n"); @@ -1023,7 +1023,7 @@ n->hops); for (x = n->hosts; x; x = x->next) - storeAppendPrintf(sentry, " %s", hashKeyStr(&x->hash)); + storeAppendPrintf(sentry, " %s", hashKeyStr(x)); storeAppendPrintf(sentry, "\n"); @@ -1284,13 +1284,12 @@ CachePeer *p = (CachePeer *)data; static const SBuf netDB("netdb"); char *uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", netDB); - debugs(38, 3, "netdbExchangeStart: Requesting '" << uri << "'"); - assert(NULL != uri); + debugs(38, 3, "Requesting '" << uri << "'"); const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp); HttpRequest *req = HttpRequest::FromUrl(uri, mx); - if (req == NULL) { - debugs(38, DBG_IMPORTANT, "netdbExchangeStart: Bad URI " << uri); + if (!req) { + debugs(38, DBG_IMPORTANT, MYNAME << ": Bad URI " << uri); return; } diff -u -r -N squid-4.0.21/src/icmp/net_db.h squid-4.0.22/src/icmp/net_db.h --- squid-4.0.21/src/icmp/net_db.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/icmp/net_db.h 2017-12-08 04:12:12.000000000 +1300 @@ -19,15 +19,15 @@ class StoreEntry; class URL; -class net_db_name +class net_db_name: + public hash_link /* must be first */ { MEMPROXY_CLASS(net_db_name); public: net_db_name(const char *name, netdbEntry *); - ~net_db_name() {xfree(hash.key);} + ~net_db_name() { xfree(key); } - hash_link hash; /* must be first */ net_db_name *next; netdbEntry *net_db_entry; }; @@ -42,14 +42,14 @@ time_t expires; }; -class netdbEntry +class netdbEntry: + public hash_link /* must be first */ { MEMPROXY_CLASS(netdbEntry); public: netdbEntry() { *network = 0; } - hash_link hash; /* must be first */ char network[MAX_IPSTRLEN]; int pings_sent = 0; int pings_recv = 0; diff -u -r -N squid-4.0.21/src/ipc/UdsOp.cc squid-4.0.22/src/ipc/UdsOp.cc --- squid-4.0.21/src/ipc/UdsOp.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ipc/UdsOp.cc 2017-12-08 04:12:12.000000000 +1300 @@ -193,7 +193,7 @@ const Comm::ConnectionPointer & Ipc::ImportFdIntoComm(const Comm::ConnectionPointer &conn, int socktype, int protocol, Ipc::FdNoteId noteId) { - struct sockaddr_in addr; + struct sockaddr_storage addr; socklen_t len = sizeof(addr); if (getsockname(conn->fd, reinterpret_cast(&addr), &len) == 0) { conn->remote = addr; diff -u -r -N squid-4.0.21/src/ipc.cc squid-4.0.22/src/ipc.cc --- squid-4.0.21/src/ipc.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ipc.cc 2017-12-08 04:12:12.000000000 +1300 @@ -416,7 +416,7 @@ execvp(prog, (char *const *) args); xerrno = errno; - debug_log = fdopen(2, "a+"); + ResyncDebugLog(fdopen(2, "a+")); debugs(54, DBG_CRITICAL, "ipcCreate: " << prog << ": " << xstrerr(xerrno)); diff -u -r -N squid-4.0.21/src/log/DB/log_db_daemon.8 squid-4.0.22/src/log/DB/log_db_daemon.8 --- squid-4.0.21/src/log/DB/log_db_daemon.8 2017-07-02 20:57:36.000000000 +1200 +++ squid-4.0.22/src/log/DB/log_db_daemon.8 2017-12-08 06:19:03.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,21 +129,37 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 8" -.TH LOG_DB_DAEMON 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" log_db_daemon \- Database logging daemon for Squid +.PP +Version 0.5. .SH "SYNOPSIS" .IX Header "SYNOPSIS" log_db_daemon \s-1DSN\s0 [options] .SH "DESCRIPTION" .IX Header "DESCRIPTION" This program writes Squid access.log entries to a database. -Presently only accepts the \fBsquid\fR native format -.IP "\fB\s-1DSN\s0\fR" 8 +Presently only accepts the \fBsquid\fR native log format. +.PP +The script has been developed and tested in the following environment: +.IP "squid\-2.7 Squid\-3.2" 4 +.IX Item "squid-2.7 Squid-3.2" +.PD 0 +.IP "mysql 5.0.26 and 5.1" 4 +.IX Item "mysql 5.0.26 and 5.1" +.IP "perl 5.8.8" 4 +.IX Item "perl 5.8.8" +.IP "OpenSUSE 10.2" 4 +.IX Item "OpenSUSE 10.2" +.PD +.SH "OPTIONS" +.IX Header "OPTIONS" +.IP "\fB\s-1DSN\s0\fR" 12 .IX Item "DSN" Database \s-1DSN\s0 encoded as a path. This is sent as the access_log file path. .Sp @@ -156,12 +172,9 @@ .Ve .Sp Default \*(L"DBI:mysql:database=squid\*(R" -.IP "\fB\-\-debug\fR" 8 +.IP "\fB\-\-debug\fR" 12 .IX Item "--debug" -Write debug messages to Squid stderr or cache.log -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -This module exploits the new logfile daemon support available in squid 2.7 and 3.2 to store access log entries in a MySQL database. +Write debug info to stderr. .SH "CONFIGURATION" .IX Header "CONFIGURATION" .SS "Squid configuration" @@ -266,21 +279,6 @@ \& squid_request_status VARCHAR(20) \& ); .Ve -.SH "VERSION INFORMATION" -.IX Header "VERSION INFORMATION" -This document refers to \f(CW\*(C`log_db_daemon\*(C'\fR script version 0.5. -.PP -The script has been developed and tested in the following environment: -.IP "squid\-2.7 Squid\-3.2" 4 -.IX Item "squid-2.7 Squid-3.2" -.PD 0 -.IP "mysql 5.0.26 and 5.1" 4 -.IX Item "mysql 5.0.26 and 5.1" -.IP "perl 5.8.8" 4 -.IX Item "perl 5.8.8" -.IP "OpenSUSE 10.2" 4 -.IX Item "OpenSUSE 10.2" -.PD .SH "DATA EXTRACTION" .IX Header "DATA EXTRACTION" .SS "Sample queries." @@ -390,13 +388,13 @@ \& GROUP BY 1 \& ORDER BY 2 DESC; .Ve +.SH "KNOWN ISSUES" +.IX Header "KNOWN ISSUES" .SS "Speed issues" .IX Subsection "Speed issues" The MyISAM storage engine is known to be faster than the InnoDB one, so although it doesn't support transactions and referential integrity, it might be more appropriate in this scenario. You might want to append \*(L"ENGINE=MYISAM\*(R" at the end of the table creation code in the above \s-1SQL\s0 script. .PP Indexes should be created according to the queries that are more frequently run. The \s-1DDL\s0 script only creates an implicit index for the primary key column. -.SH "TODO" -.IX Header "TODO" .SS "Table cleanup" .IX Subsection "Table cleanup" This script currently implements only the \f(CW\*(C`L\*(C'\fR (i.e. \*(L"append a line to the log\*(R") command, therefore the log lines are never purged from the table. This approach has an obvious scalability problem. @@ -409,10 +407,11 @@ This script has only been tested in low-volume scenarios (single client, less than 10 req/s). Tests in high volume environments could reveal performance bottlenecks and bugs. .SH "AUTHOR" .IX Header "AUTHOR" -Marcello Romani, marcello.romani@libero.it -Amos Jeffries, amosjeffries@squid\-cache.org -.SH "COPYRIGHT AND LICENSE" -.IX Header "COPYRIGHT AND LICENSE" +This program was written by +\&\fIMarcello Romani , +\&\fIAmos Jeffries +.SH "COPYRIGHT" +.IX Header "COPYRIGHT" .Vb 5 \& * Copyright (C) 1996\-2017 The Squid Software Foundation and contributors \& * @@ -426,3 +425,23 @@ This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. +.SH "QUESTIONS" +.IX Header "QUESTIONS" +Questions on the usage of this program can be sent to the \fISquid Users mailing list +.SH "REPORTING BUGS" +.IX Header "REPORTING BUGS" +Bug reports need to be made in English. +See http://wiki.squid\-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. +.PP +Report bugs or bug fixes using http://bugs.squid\-cache.org/ +.PP +Report serious security bugs to \fISquid Bugs +.PP +Report ideas for new improvements to the \fISquid Developers mailing list +.SH "SEE ALSO" +.IX Header "SEE ALSO" +squid (8), \s-1GPL\s0 (7), +.PP +The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq +.PP +The Squid Configuration Manual http://www.squid\-cache.org/Doc/config/ diff -u -r -N squid-4.0.21/src/log/DB/log_db_daemon.pl.in squid-4.0.22/src/log/DB/log_db_daemon.pl.in --- squid-4.0.21/src/log/DB/log_db_daemon.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/log/DB/log_db_daemon.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -14,6 +14,8 @@ log_db_daemon - Database logging daemon for Squid +Version 0.5. + =head1 SYNOPSIS log_db_daemon DSN [options] @@ -21,188 +23,43 @@ =head1 DESCRIPTION This program writes Squid access.log entries to a database. -Presently only accepts the B native format - -=over 8 - -=item B +Presently only accepts the B native log format. -Database DSN encoded as a path. This is sent as the access_log file path. +The script has been developed and tested in the following environment: -Sample configuration: - access_log daemon:/host/database/table/username/password squid +=over 4 - to leave a parameter unspecified use a double slash: - access_log daemon://database/table/username/password squid +=item squid-2.7 Squid-3.2 -Default "DBI:mysql:database=squid" +=item mysql 5.0.26 and 5.1 -=item B<--debug> +=item perl 5.8.8 -Write debug messages to Squid stderr or cache.log +=item OpenSUSE 10.2 =back -=cut - -# the first argument to this script is the log file path describing the DSN -my $log_file = shift; - -# others may be options -my $debug = 0; -GetOptions( - 'debug' => \$debug, - ); - - -# utility routine to print messages on stderr (so they appear in cache log) -# without using warn, which would clutter the log with source line numbers -sub log_info { - my $msg = shift; - print STDERR "$msg\n"; -} - -# we use logfile to pass database access information to this script -# sample configuration: -# access_log daemon:/host/database/table/username/password squid -# to let a parmeter unspecified, e.g. the database host, use a double slash: -# access_log daemon://database/table/username/password squid -my ( $host, $database, $table, $user, $pass ) = $log_file =~ / \/(.*?)\/(.*?)\/(.*?)\/(.*?)\/(.*?) \z /xms; - -if ( !$host ) { - $host = 'localhost'; - log_info("Database host not specified. Using $host."); -} - -if ( !$database ) { - $database = 'squid_log'; - log_info("Database name not specified. Using $database."); -} - -if ( !$table ) { - $table = 'access_log'; - log_info("Table parameter not specified. Using $table."); -} - -if ( !$user ) { - $user = 'squid'; - log_info("User parameter not specified. Using $user."); -} - -if ( !$pass ) { - log_info('No password specified. Connecting with NO password.'); -} - -# fields that we should have in the table -# Order here must match the order of fields in the Log format and parse() output array. -my @db_fields = qw( - id - time_since_epoch - time_response - ip_client - squid_request_status - http_status_code - http_reply_size - http_method - http_url - http_username - squid_hier_status - ip_server - http_mime_type -); - -# perform db connection -my $dsn = "DBI:mysql:database=$database" . ($host ne "localhost" ? ":$host" : ""); -my $dbh; -my $sth; -eval { - warn "Connecting... dsn='$dsn', username='$user', password='...'"; - $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 1, RaiseError => 1, PrintError => 1 }); -}; -if ($EVAL_ERROR) { - die "Cannot connect to database: $DBI::errstr"; -} - +=head1 OPTIONS -# a simple test to assure the specified table exists -eval { - my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1"; - my $sth = $dbh->prepare($q); - $sth->execute; -}; -if ($EVAL_ERROR) { - # run a query to create the table of required syntax - my $create_query = 'CREATE TABLE ' . $table . ' (' . - " id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY," . - " time_since_epoch DECIMAL(15,3)," . - " time_response INTEGER," . - " ip_client CHAR(15)," . - " ip_server CHAR(15)," . - " http_status_code VARCHAR(10)," . - " http_reply_size INTEGER," . - " http_method VARCHAR(20)," . - " http_url TEXT," . - " http_username VARCHAR(20)," . - " http_mime_type VARCHAR(50)," . - " squid_request_status VARCHAR(50)," . - " squid_hier_status VARCHAR(20)" . - ");" ; - - $sth = $dbh->prepare($create_query); - $sth->execute; - # test again and fail hard if it is still broken. - eval { - my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1"; - my $sth = $dbh->prepare($q); - $sth->execute; - }; - if ($EVAL_ERROR) { - die "Error initializing database table: $EVAL_ERROR"; - }; -} -# test +=over 12 -# for better performance, prepare the statement at startup -eval { - my $q = "INSERT INTO $table (" . join(',',@db_fields) . ") VALUES(NULL" . ',?' x (scalar(@db_fields)-1) . ')'; - #$sth = $dbh->prepare("INSERT INTO $table VALUES(NULL,?,?,?,?,?,?,?,?,?,?,?,?)"); - $sth = $dbh->prepare($q); -}; -if ($EVAL_ERROR) { - die "Error while preparing sql statement: $EVAL_ERROR"; -} - -sub parse($) { - my ($line) = @_; - my (@t) = $line =~ /^L(\d+\.\d+) *(\d+?) (.*?) (.*?)\/(\d+?) (\d+?) (.*?) (.*?) (.*?) (.*?)\/(.*?) (.*)$/; -} - -# main loop -while (my $line = <>) { - chomp $line; +=item B - my $cmd = substr($line, 0, 1); # extract command byte +Database DSN encoded as a path. This is sent as the access_log file path. - if ( $cmd eq 'L' ) { - my @log_entry = parse($line); - eval { # we catch db errors to avoid crashing squid in case something goes wrong... - $sth->execute(@log_entry) or die $sth->errstr - }; - if ( $EVAL_ERROR ) { # leave a trace of the error in the logs - warn $EVAL_ERROR . " values=(" . join(', ', @log_entry) . ')'; - } - } -} +Sample configuration: + access_log daemon:/host/database/table/username/password squid -$dbh->disconnect(); + to leave a parameter unspecified use a double slash: + access_log daemon://database/table/username/password squid -__END__ +Default "DBI:mysql:database=squid" -=pod +=item B<--debug> -=head1 DESCRIPTION +Write debug info to stderr. -This module exploits the new logfile daemon support available in squid 2.7 and 3.2 to store access log entries in a MySQL database. +=back =head1 CONFIGURATION @@ -300,24 +157,6 @@ squid_request_status VARCHAR(20) ); -=head1 VERSION INFORMATION - -This document refers to C script version 0.5. - -The script has been developed and tested in the following environment: - -=over 4 - -=item squid-2.7 Squid-3.2 - -=item mysql 5.0.26 and 5.1 - -=item perl 5.8.8 - -=item OpenSUSE 10.2 - -=back - =head1 DATA EXTRACTION =head2 Sample queries. @@ -421,14 +260,14 @@ =back +=head1 KNOWN ISSUES + =head2 Speed issues The MyISAM storage engine is known to be faster than the InnoDB one, so although it doesn't support transactions and referential integrity, it might be more appropriate in this scenario. You might want to append "ENGINE=MYISAM" at the end of the table creation code in the above SQL script. Indexes should be created according to the queries that are more frequently run. The DDL script only creates an implicit index for the primary key column. -=head1 TODO - =head2 Table cleanup This script currently implements only the C (i.e. "append a line to the log") command, therefore the log lines are never purged from the table. This approach has an obvious scalability problem. @@ -443,10 +282,11 @@ =head1 AUTHOR -Marcello Romani, marcello.romani@libero.it -Amos Jeffries, amosjeffries@squid-cache.org +This program was written by +I> , +I> -=head1 COPYRIGHT AND LICENSE +=head1 COPYRIGHT * Copyright (C) 1996-2017 The Squid Software Foundation and contributors * @@ -460,4 +300,180 @@ it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. +=head1 QUESTIONS + +Questions on the usage of this program can be sent to the I> + +=head1 REPORTING BUGS + +Bug reports need to be made in English. +See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. + +Report bugs or bug fixes using http://bugs.squid-cache.org/ + +Report serious security bugs to I> + +Report ideas for new improvements to the I> + +=head1 SEE ALSO + +squid (8), GPL (7), + +The Squid FAQ wiki http://wiki.squid-cache.org/SquidFaq + +The Squid Configuration Manual http://www.squid-cache.org/Doc/config/ + =cut + +# the first argument to this script is the log file path describing the DSN +my $log_file = shift; + +# others may be options +my $debug = 0; +GetOptions( + 'debug' => \$debug, + ); + + +# utility routine to print messages on stderr (so they appear in cache log) +# without using warn, which would clutter the log with source line numbers +sub log_info { + my $msg = shift; + print STDERR "$msg\n"; +} + +# we use logfile to pass database access information to this script +# sample configuration: +# access_log daemon:/host/database/table/username/password squid +# to let a parmeter unspecified, e.g. the database host, use a double slash: +# access_log daemon://database/table/username/password squid +my ( $host, $database, $table, $user, $pass ) = $log_file =~ / \/(.*?)\/(.*?)\/(.*?)\/(.*?)\/(.*?) \z /xms; + +if ( !$host ) { + $host = 'localhost'; + log_info("Database host not specified. Using $host."); +} + +if ( !$database ) { + $database = 'squid_log'; + log_info("Database name not specified. Using $database."); +} + +if ( !$table ) { + $table = 'access_log'; + log_info("Table parameter not specified. Using $table."); +} + +if ( !$user ) { + $user = 'squid'; + log_info("User parameter not specified. Using $user."); +} + +if ( !$pass ) { + log_info('No password specified. Connecting with NO password.'); +} + +# fields that we should have in the table +# Order here must match the order of fields in the Log format and parse() output array. +my @db_fields = qw( + id + time_since_epoch + time_response + ip_client + squid_request_status + http_status_code + http_reply_size + http_method + http_url + http_username + squid_hier_status + ip_server + http_mime_type +); + +# perform db connection +my $dsn = "DBI:mysql:database=$database" . ($host ne "localhost" ? ":$host" : ""); +my $dbh; +my $sth; +eval { + warn "Connecting... dsn='$dsn', username='$user', password='...'"; + $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 1, RaiseError => 1, PrintError => 1 }); +}; +if ($EVAL_ERROR) { + die "Cannot connect to database: $DBI::errstr"; +} + + +# a simple test to assure the specified table exists +eval { + my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1"; + my $sth = $dbh->prepare($q); + $sth->execute; +}; +if ($EVAL_ERROR) { + # run a query to create the table of required syntax + my $create_query = 'CREATE TABLE ' . $table . ' (' . + " id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY," . + " time_since_epoch DECIMAL(15,3)," . + " time_response INTEGER," . + " ip_client CHAR(15)," . + " ip_server CHAR(15)," . + " http_status_code VARCHAR(10)," . + " http_reply_size INTEGER," . + " http_method VARCHAR(20)," . + " http_url TEXT," . + " http_username VARCHAR(20)," . + " http_mime_type VARCHAR(50)," . + " squid_request_status VARCHAR(50)," . + " squid_hier_status VARCHAR(20)" . + ");" ; + + $sth = $dbh->prepare($create_query); + $sth->execute; + # test again and fail hard if it is still broken. + eval { + my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1"; + my $sth = $dbh->prepare($q); + $sth->execute; + }; + if ($EVAL_ERROR) { + die "Error initializing database table: $EVAL_ERROR"; + }; +} +# test + +# for better performance, prepare the statement at startup +eval { + my $q = "INSERT INTO $table (" . join(',',@db_fields) . ") VALUES(NULL" . ',?' x (scalar(@db_fields)-1) . ')'; + #$sth = $dbh->prepare("INSERT INTO $table VALUES(NULL,?,?,?,?,?,?,?,?,?,?,?,?)"); + $sth = $dbh->prepare($q); +}; +if ($EVAL_ERROR) { + die "Error while preparing sql statement: $EVAL_ERROR"; +} + +sub parse($) { + my ($line) = @_; + my (@t) = $line =~ /^L(\d+\.\d+) *(\d+?) (.*?) (.*?)\/(\d+?) (\d+?) (.*?) (.*?) (.*?) (.*?)\/(.*?) (.*)$/; +} + +# main loop +while (my $line = <>) { + chomp $line; + + my $cmd = substr($line, 0, 1); # extract command byte + + if ( $cmd eq 'L' ) { + my @log_entry = parse($line); + eval { # we catch db errors to avoid crashing squid in case something goes wrong... + $sth->execute(@log_entry) or die $sth->errstr + }; + if ( $EVAL_ERROR ) { # leave a trace of the error in the logs + warn $EVAL_ERROR . " values=(" . join(', ', @log_entry) . ')'; + } + } +} + +$dbh->disconnect(); + +__END__ diff -u -r -N squid-4.0.21/src/main.cc squid-4.0.22/src/main.cc --- squid-4.0.21/src/main.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/main.cc 2017-12-08 04:12:12.000000000 +1300 @@ -1457,7 +1457,6 @@ ConfigureCurrentKid(argv[0]); Debug::parseOptions(NULL); - debug_log = stderr; #if defined(SQUID_MAXFD_LIMIT) @@ -1612,7 +1611,7 @@ return 0; } - debugs(1,2, HERE << "Doing post-config initialization\n"); + debugs(1,2, "Doing post-config initialization"); leave_suid(); RunRegisteredHere(RegisteredRunner::finalizeConfig); @@ -1717,7 +1716,7 @@ static void sendSignal(void) { - debug_log = stderr; + StopUsingDebugLog(); #if USE_WIN32_SERVICE // WIN32_sendSignal() does not need the PID value to signal, diff -u -r -N squid-4.0.21/src/MemObject.cc squid-4.0.22/src/MemObject.cc --- squid-4.0.21/src/MemObject.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/MemObject.cc 2017-12-08 04:12:12.000000000 +1300 @@ -77,7 +77,11 @@ void MemObject::setUris(char const *aStoreId, char const *aLogUri, const HttpRequestMethod &aMethod) { + if (hasUris()) + return; + storeId_ = aStoreId; + debugs(88, 3, this << " storeId: " << storeId_); // fast pointer comparison for a common storeCreateEntry(url,url,...) case if (!aLogUri || aLogUri == aStoreId) diff -u -r -N squid-4.0.21/src/MemObject.h squid-4.0.22/src/MemObject.h --- squid-4.0.21/src/MemObject.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/MemObject.h 2017-12-08 04:12:12.000000000 +1300 @@ -42,7 +42,12 @@ MemObject(); ~MemObject(); - /// sets store ID, log URI, and request method; TODO: find a better name + /// Sets store ID, log URI, and request method (unless already set). Does + /// not clobber the method so that, say, a HEAD hit for a GET entry keeps + /// the GET method that matches the entry key. Same for the other parts of + /// the trio because the entry filling code may expect them to be constant. + /// XXX: Avoid this method. We plan to remove it and make the trio constant + /// after addressing the XXX in MemStore::get(). void setUris(char const *aStoreId, char const *aLogUri, const HttpRequestMethod &aMethod); /// whether setUris() has been called diff -u -r -N squid-4.0.21/src/MemStore.cc squid-4.0.22/src/MemStore.cc --- squid-4.0.21/src/MemStore.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/MemStore.cc 2017-12-08 04:12:12.000000000 +1300 @@ -323,7 +323,7 @@ // XXX: We do not know the URLs yet, only the key, but we need to parse and // store the response for the Root().get() callers to be happy because they // expect IN_MEMORY entries to already have the response headers and body. - e->makeMemObject(); + e->createMemObject(); anchorEntry(*e, index, *slot); diff -u -r -N squid-4.0.21/src/mgr/Inquirer.cc squid-4.0.22/src/mgr/Inquirer.cc --- squid-4.0.21/src/mgr/Inquirer.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/mgr/Inquirer.cc 2017-12-08 04:12:12.000000000 +1300 @@ -74,8 +74,7 @@ std::unique_ptr replyBuf; if (strands.empty()) { - LOCAL_ARRAY(char, url, MAX_URL); - snprintf(url, MAX_URL, "%s", aggrAction->command().params.httpUri.termedBuf()); + const char *url = aggrAction->command().params.httpUri.termedBuf(); const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc); HttpRequest *req = HttpRequest::FromUrl(url, mx); ErrorState err(ERR_INVALID_URL, Http::scNotFound, req); diff -u -r -N squid-4.0.21/src/mime.cc squid-4.0.22/src/mime.cc --- squid-4.0.21/src/mime.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/mime.cc 2017-12-08 04:12:12.000000000 +1300 @@ -394,6 +394,11 @@ status = Http::scNoContent; } + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); + HttpRequest *r = HttpRequest::FromUrl(url_, mx); + if (!r) + fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); + // fill newEntry with a canned 2xx response object RequestFlags flags; flags.cachable = true; @@ -402,11 +407,6 @@ EBIT_SET(e->flags, ENTRY_SPECIAL); e->setPublicKey(); e->buffer(); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); - HttpRequest *r = HttpRequest::FromUrl(url_, mx); - - if (NULL == r) - fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); e->mem_obj->request = r; HTTPMSGLOCK(e->mem_obj->request); diff -u -r -N squid-4.0.21/src/neighbors.cc squid-4.0.22/src/neighbors.cc --- squid-4.0.21/src/neighbors.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/neighbors.cc 2017-12-08 04:12:12.000000000 +1300 @@ -1371,19 +1371,20 @@ { CachePeer *p = (CachePeer *)data; ps_state *psstate; - StoreEntry *fake; MemObject *mem; icp_common_t *query; int reqnum; + // TODO: use class URL instead of constructing and re-parsing a string LOCAL_ARRAY(char, url, MAX_URL); assert(p->type == PEER_MULTICAST); p->mcast.flags.count_event_pending = false; snprintf(url, MAX_URL, "http://"); p->in_addr.toUrl(url+7, MAX_URL -8 ); strcat(url, "/"); - fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast); HttpRequest *req = HttpRequest::FromUrl(url, mx); + assert(req != nullptr); + StoreEntry *fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); psstate = new ps_state; psstate->request = req; HTTPMSGLOCK(psstate->request); diff -u -r -N squid-4.0.21/src/redirect.cc squid-4.0.22/src/redirect.cc --- squid-4.0.21/src/redirect.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/redirect.cc 2017-12-08 04:12:12.000000000 +1300 @@ -108,10 +108,6 @@ // if we still have anything in other() after all that // parse it into status=, url= and rewrite-url= keys if (replySize) { - /* 2012-06-28: This cast is due to URL::parse() truncating too-long URLs itself. - * At this point altering the helper buffer in that way is not harmful, but annoying. - * When Bug 1961 is resolved and URL::parse has a const API, this needs to die. - */ MemBuf replyBuffer; replyBuffer.init(replySize, replySize); replyBuffer.append(reply.other().content(), reply.other().contentSize()); diff -u -r -N squid-4.0.21/src/refresh.cc squid-4.0.22/src/refresh.cc --- squid-4.0.21/src/refresh.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/refresh.cc 2017-12-08 04:12:12.000000000 +1300 @@ -420,7 +420,7 @@ int maxAge = -1; if (cc->hasMaxAge(&maxAge)) { - // draft-mcmanus-immutable-00: reply contains CC:immutable then ignore client CC:max-age=N + // RFC 8246: reply contains CC:immutable then ignore client CC:max-age=N if (reply && reply->cache_control && reply->cache_control->hasImmutable()) { debugs(22, 3, "MAYBE: Ignoring client CC:max-age=" << maxAge << " request - 'Cache-Control: immutable'"); diff -u -r -N squid-4.0.21/src/sbuf/SBuf.cc squid-4.0.22/src/sbuf/SBuf.cc --- squid-4.0.21/src/sbuf/SBuf.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/sbuf/SBuf.cc 2017-12-08 04:12:12.000000000 +1300 @@ -144,6 +144,28 @@ } char * +SBuf::rawAppendStart(size_type anticipatedSize) +{ + char *space = rawSpace(anticipatedSize); + debugs(24, 8, id << " start appending up to " << anticipatedSize << " bytes"); + return space; +} + +void +SBuf::rawAppendFinish(const char *start, size_type actualSize) +{ + Must(bufEnd() == start); + Must(store_->canAppend(off_ + len_, actualSize)); + debugs(24, 8, id << " finish appending " << actualSize << " bytes"); + + size_type newSize = length() + actualSize; + if (newSize > min(maxSize,store_->capacity-off_)) + throw SBufTooBigException(__FILE__,__LINE__); + len_ = newSize; + store_->size = off_ + newSize; +} + +char * SBuf::rawSpace(size_type minSpace) { Must(length() <= maxSize - minSpace); @@ -520,18 +542,6 @@ return buf(); } -void -SBuf::forceSize(size_type newSize) -{ - debugs(24, 8, id << " force " << (newSize > length() ? "grow" : "shrink") << " to length=" << newSize); - - Must(store_->LockCount() == 1); - if (newSize > min(maxSize,store_->capacity-off_)) - throw SBufTooBigException(__FILE__,__LINE__); - len_ = newSize; - store_->size = newSize; -} - const char* SBuf::c_str() { diff -u -r -N squid-4.0.21/src/sbuf/SBuf.h squid-4.0.22/src/sbuf/SBuf.h --- squid-4.0.21/src/sbuf/SBuf.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/sbuf/SBuf.h 2017-12-08 04:12:12.000000000 +1300 @@ -364,24 +364,18 @@ */ const char* rawContent() const; - /** Exports a writable pointer to the SBuf internal storage. - * \warning Use with EXTREME caution, this is a dangerous operation. - * - * Returns a pointer to the first unused byte in the SBuf's storage, - * which can be be used for appending. At least minSize bytes will - * be available for writing. - * The returned pointer must not be stored by the caller, as it will - * be invalidated by the first call to a non-const method call - * on the SBuf. - * This call guarantees to never return NULL. - * \see reserveSpace - * \note Unlike reserveSpace(), this method does not guarantee exclusive - * buffer ownership. It is instead optimized for a one writer - * (appender), many readers scenario by avoiding unnecessary - * copying and allocations. - * \throw SBufTooBigException if the user tries to allocate too big a SBuf - */ - char *rawSpace(size_type minSize); + /// \returns a buffer suitable for appending at most `anticipatedSize` bytes + /// The buffer must be used "immediately" because it is invalidated by most + /// non-constant SBuf method calls, including such calls against other SBuf + /// objects that just happen to share the same underlying MemBlob storage! + char *rawAppendStart(size_type anticipatedSize); + + /// Updates SBuf metadata to reflect appending `actualSize` bytes to the + /// buffer returned by the corresponding rawAppendStart() call. Throws if + /// rawAppendStart(actualSize) would have returned a different value now. + /// \param start raw buffer previously returned by rawAppendStart() + /// \param actualSize the number of appended bytes + void rawAppendFinish(const char *start, size_type actualSize); /** Obtain how much free space is available in the backing store. * @@ -390,16 +384,6 @@ */ size_type spaceSize() const { return store_->spaceSize(); } - /** Force a SBuf's size - * \warning use with EXTREME caution, this is a dangerous operation - * - * Adapt the SBuf internal state after external interference - * such as writing into it via rawSpace. - * \throw TextException if SBuf doesn't have exclusive ownership of store - * \throw SBufTooBigException if new size is bigger than available store space - */ - void forceSize(size_type newSize); - /** exports a null-terminated reference to the SBuf internal storage. * \warning ACCESSING RAW STORAGE IS DANGEROUS! DO NOT EVER USE * THE RETURNED POINTER FOR WRITING @@ -672,6 +656,25 @@ void checkAccessBounds(size_type pos) const; + /** Exports a writable pointer to the SBuf internal storage. + * \warning Use with EXTREME caution, this is a dangerous operation. + * + * Returns a pointer to the first unused byte in the SBuf's storage, + * which can be be used for appending. At least minSize bytes will + * be available for writing. + * The returned pointer must not be stored by the caller, as it will + * be invalidated by the first call to a non-const method call + * on the SBuf. + * This call guarantees to never return nullptr. + * \see reserveSpace + * \note Unlike reserveSpace(), this method does not guarantee exclusive + * buffer ownership. It is instead optimized for a one writer + * (appender), many readers scenario by avoiding unnecessary + * copying and allocations. + * \throw SBufTooBigException if the user tries to allocate too big a SBuf + */ + char *rawSpace(size_type minSize); + /** Low-level append operation * * Takes as input a contiguous area of memory and appends its contents diff -u -r -N squid-4.0.21/src/security/cert_generators/file/certificate_db.cc squid-4.0.22/src/security/cert_generators/file/certificate_db.cc --- squid-4.0.21/src/security/cert_generators/file/certificate_db.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/cert_generators/file/certificate_db.cc 2017-12-08 04:12:12.000000000 +1300 @@ -17,12 +17,12 @@ #if HAVE_SYS_STAT_H #include #endif -#if HAVE_SYS_FILE_H -#include -#endif #if HAVE_FCNTL_H #include #endif +#if HAVE_SYS_FILE_H +#include +#endif #define HERE "(security_file_certgen) " << __FILE__ << ':' << __LINE__ << ": " @@ -208,7 +208,7 @@ Row row(rrow, cnlNumber); // row wrapper used to free the rrow - const Columns db_indexes[]= {cnlSerial, cnlName}; + const Columns db_indexes[]= {cnlSerial, cnlKey}; for (unsigned int i = 0; i < countof(db_indexes); ++i) { void *data = NULL; #if SQUID_SSLTXTDB_PSTRINGDATA @@ -238,11 +238,11 @@ } unsigned long Ssl::CertificateDb::index_name_hash(const char **a) { - return(lh_strhash(a[Ssl::CertificateDb::cnlName])); + return(lh_strhash(a[Ssl::CertificateDb::cnlKey])); } int Ssl::CertificateDb::index_name_cmp(const char **a, const char **b) { - return(strcmp(a[Ssl::CertificateDb::cnlName], b[CertificateDb::cnlName])); + return(strcmp(a[Ssl::CertificateDb::cnlKey], b[CertificateDb::cnlKey])); } const std::string Ssl::CertificateDb::db_file("index.txt"); @@ -264,10 +264,12 @@ throw std::runtime_error("security_file_certgen is missing the required parameter. There should be -s and -M parameters together."); } -bool Ssl::CertificateDb::find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { +bool +Ssl::CertificateDb::find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey) +{ const Locker locker(dbLock, Here); load(); - return pure_find(host_name, cert, pkey); + return pure_find(key, expectedOrig, cert, pkey); } bool Ssl::CertificateDb::purgeCert(std::string const & key) { @@ -276,19 +278,24 @@ if (!db) return false; - if (!deleteByHostname(key)) + if (!deleteByKey(key)) return false; save(); return true; } -bool Ssl::CertificateDb::addCertAndPrivateKey(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName) { +bool +Ssl::CertificateDb::addCertAndPrivateKey(std::string const &useKey, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig) +{ const Locker locker(dbLock, Here); load(); if (!db || !cert || !pkey) return false; + if(useKey.empty()) + return false; + // Functor to wrap xfree() for std::unique_ptr typedef HardFun CharDeleter; @@ -309,20 +316,8 @@ return true; } - { - std::unique_ptr subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0)); - Security::CertPointer findCert; - Ssl::EVP_PKEY_Pointer findPkey; - if (pure_find(useName.empty() ? subject.get() : useName, findCert, findPkey)) { - // Replace with database certificate - cert = std::move(findCert); - pkey = std::move(findPkey); - return true; - } - // pure_find may fail because the entry is expired, or because the - // certs file is corrupted. Remove any entry with given hostname - deleteByHostname(useName.empty() ? subject.get() : useName); - } + // Remove any entry with given key + deleteByKey(useKey); // check db size while trying to minimize calls to size() size_t dbSize = size(); @@ -346,16 +341,11 @@ dbSize = size(); // get the current database size } - row.setValue(cnlType, "V"); ASN1_UTCTIME * tm = X509_get_notAfter(cert.get()); row.setValue(cnlExp_date, std::string(reinterpret_cast(tm->data), tm->length).c_str()); - row.setValue(cnlFile, "unknown"); - if (!useName.empty()) - row.setValue(cnlName, useName.c_str()); - else { - std::unique_ptr subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0)); - row.setValue(cnlName, subject.get()); - } + std::unique_ptr subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0)); + row.setValue(cnlName, subject.get()); + row.setValue(cnlKey, useKey.c_str()); if (!TXT_DB_insert(db.get(), row.getRow())) { // failed to add index (???) but we may have already modified @@ -367,7 +357,7 @@ row.reset(); std::string filename(cert_full + "/" + serial_string + ".pem"); - if (!writeCertAndPrivateKeyToFile(cert, pkey, filename.c_str())) { + if (!WriteEntry(filename.c_str(), cert, pkey, orig)) { //remove row from txt_db and save sq_TXT_DB_delete(db.get(), (const char **)rrow); save(); @@ -379,7 +369,8 @@ return true; } -void Ssl::CertificateDb::create(std::string const & db_path) { +void +Ssl::CertificateDb::Create(std::string const & db_path) { if (db_path == "") throw std::runtime_error("Path to db is empty"); std::string db_full(db_path + "/" + db_file); @@ -402,7 +393,8 @@ throw std::runtime_error("Cannot open " + db_full + " to open"); } -void Ssl::CertificateDb::check(std::string const & db_path, size_t max_db_size, size_t fs_block_size) { +void +Ssl::CertificateDb::Check(std::string const & db_path, size_t max_db_size, size_t fs_block_size) { CertificateDb db(db_path, max_db_size, fs_block_size); db.load(); @@ -432,26 +424,32 @@ return dbSize; } -bool Ssl::CertificateDb::pure_find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { +bool +Ssl::CertificateDb::pure_find(std::string const &key, const Security::CertPointer &expectedOrig, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey) +{ if (!db) return false; Row row; - row.setValue(cnlName, host_name.c_str()); + row.setValue(cnlKey, key.c_str()); - char **rrow = TXT_DB_get_by_index(db.get(), cnlName, row.getRow()); + char **rrow = TXT_DB_get_by_index(db.get(), cnlKey, row.getRow()); if (rrow == NULL) return false; if (!sslDateIsInTheFuture(rrow[cnlExp_date])) return false; + Security::CertPointer storedOrig; // read cert and pkey from file. std::string filename(cert_full + "/" + rrow[cnlSerial] + ".pem"); - readCertAndPrivateKeyFromFiles(cert, pkey, filename.c_str(), NULL); - if (!cert || !pkey) + if (!ReadEntry(filename.c_str(), cert, pkey, storedOrig)) return false; - return true; + + if (!storedOrig && !expectedOrig) + return true; + else + return Ssl::CertificatesCmp(expectedOrig, storedOrig); } size_t Ssl::CertificateDb::size() { @@ -514,7 +512,7 @@ if (!corrupt && !TXT_DB_create_index(temp_db.get(), cnlSerial, NULL, LHASH_HASH_FN(index_serial_hash), LHASH_COMP_FN(index_serial_cmp))) corrupt = true; - if (!corrupt && !TXT_DB_create_index(temp_db.get(), cnlName, NULL, LHASH_HASH_FN(index_name_hash), LHASH_COMP_FN(index_name_cmp))) + if (!corrupt && !TXT_DB_create_index(temp_db.get(), cnlKey, NULL, LHASH_HASH_FN(index_name_hash), LHASH_COMP_FN(index_name_cmp))) corrupt = true; if (corrupt) @@ -596,7 +594,8 @@ return true; } -bool Ssl::CertificateDb::deleteByHostname(std::string const & host) { +bool +Ssl::CertificateDb::deleteByKey(std::string const & key) { if (!db) return false; @@ -611,7 +610,7 @@ for (int i = 0; i < sk_num(db.get()->data); ++i) { const char ** current_row = ((const char **)sk_value(db.get()->data, i)); #endif - if (host == current_row[cnlName]) { + if (key == current_row[cnlKey]) { deleteRow(current_row, i); return true; } @@ -637,3 +636,33 @@ return enabled_disk_store; } +bool +Ssl::CertificateDb::WriteEntry(const std::string &filename, const Security::CertPointer &cert, const Security::PrivateKeyPointer &pkey, const Security::CertPointer &orig) +{ + Ssl::BIO_Pointer bio; + if (!Ssl::OpenCertsFileForWriting(bio, filename.c_str())) + return false; + if (!Ssl::WriteX509Certificate(bio, cert)) + return false; + if (!Ssl::WritePrivateKey(bio, pkey)) + return false; + if (orig && !Ssl::WriteX509Certificate(bio, orig)) + return false; + return true; +} + +bool +Ssl::CertificateDb::ReadEntry(std::string filename, Security::CertPointer &cert, Security::PrivateKeyPointer &pkey, Security::CertPointer &orig) +{ + Ssl::BIO_Pointer bio; + if (!Ssl::OpenCertsFileForReading(bio, filename.c_str())) + return false; + if (!Ssl::ReadX509Certificate(bio, cert)) + return false; + if (!Ssl::ReadPrivateKey(bio, pkey, NULL)) + return false; + // The orig certificate is not mandatory + (void)Ssl::ReadX509Certificate(bio, orig); + return true; +} + diff -u -r -N squid-4.0.21/src/security/cert_generators/file/certificate_db.h squid-4.0.22/src/security/cert_generators/file/certificate_db.h --- squid-4.0.21/src/security/cert_generators/file/certificate_db.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/cert_generators/file/certificate_db.h 2017-12-08 04:12:12.000000000 +1300 @@ -69,11 +69,10 @@ public: /// Names of db columns. enum Columns { - cnlType = 0, + cnlKey = 0, //< The key to use for storing/retrieving entries from DB. cnlExp_date, cnlRev_date, cnlSerial, - cnlFile, cnlName, cnlNumber }; @@ -97,17 +96,19 @@ }; CertificateDb(std::string const & db_path, size_t aMax_db_size, size_t aFs_block_size); - /// Find certificate and private key for host name - bool find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); + /// finds matching generated certificate and its private key + bool find(std::string const & key, const Security::CertPointer &expectedOrig, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey); /// Delete a certificate from database bool purgeCert(std::string const & key); /// Save certificate to disk. - bool addCertAndPrivateKey(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName); + bool addCertAndPrivateKey(std::string const & useKey, const Security::CertPointer & cert, const Security::PrivateKeyPointer & pkey, const Security::CertPointer &orig); + + bool IsEnabledDiskStore() const; ///< Check enabled of dist store. + /// Create and initialize a database under the db_path - static void create(std::string const & db_path); + static void Create(std::string const & db_path); /// Check the database stored under the db_path. - static void check(std::string const & db_path, size_t max_db_size, size_t fs_block_size); - bool IsEnabledDiskStore() const; ///< Check enabled of dist store. + static void Check(std::string const & db_path, size_t max_db_size, size_t fs_block_size); private: void load(); ///< Load db from disk. void save(); ///< Save db to disk. @@ -121,14 +122,20 @@ size_t getFileSize(std::string const & filename); ///< get file size on disk. size_t rebuildSize(); ///< Rebuild size_file /// Only find certificate in current db and return it. - bool pure_find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); + bool pure_find(std::string const & key, const Security::CertPointer & expectedOrig, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey); void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB bool deleteInvalidCertificate(); ///< Delete invalid certificate. bool deleteOldestCertificate(); ///< Delete oldest certificate. - bool deleteByHostname(std::string const & host); ///< Delete using host name. + bool deleteByKey(std::string const & key); ///< Delete using key. bool hasRows() const; ///< Whether the TXT_DB has stored items. + /// stores the db entry into a file + static bool WriteEntry(const std::string &filename, const Security::CertPointer & cert, const Security::PrivateKeyPointer & pkey, const Security::CertPointer &orig); + + /// loads a db entry from the file + static bool ReadEntry(std::string filename, Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, Security::CertPointer &orig); + /// Removes the first matching row from TXT_DB. Ignores failures. static void sq_TXT_DB_delete(TXT_DB *db, const char **row); /// Remove the row on position idx from TXT_DB. Ignores failures. diff -u -r -N squid-4.0.21/src/security/cert_generators/file/security_file_certgen.8.in squid-4.0.22/src/security/cert_generators/file/security_file_certgen.8.in --- squid-4.0.21/src/security/cert_generators/file/security_file_certgen.8.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/cert_generators/file/security_file_certgen.8.in 2017-12-08 04:12:12.000000000 +1300 @@ -146,7 +146,7 @@ .PP This manual was written by .if !'po4a'hide' .I Christos Tsantilas -.if !'po4a'hide' .I Amos Jeffries +.if !'po4a'hide' .I Amos Jeffries . .SH COPYRIGHT .PP @@ -159,7 +159,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -168,11 +168,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/src/security/cert_generators/file/security_file_certgen.cc squid-4.0.22/src/security/cert_generators/file/security_file_certgen.cc --- squid-4.0.21/src/security/cert_generators/file/security_file_certgen.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/cert_generators/file/security_file_certgen.cc 2017-12-08 04:12:12.000000000 +1300 @@ -189,34 +189,25 @@ Ssl::CertificateDb db(db_path, max_db_size, fs_block_size); Security::CertPointer cert; - Ssl::EVP_PKEY_Pointer pkey; - std::string &cert_subject = certProperties.dbKey(); + Security::PrivateKeyPointer pkey; + Security::CertPointer orig; + std::string &certKey = Ssl::OnDiskCertificateDbKey(certProperties); bool dbFailed = false; try { - db.find(cert_subject, cert, pkey); + db.find(certKey, certProperties.mimicCert, cert, pkey); } catch (std::runtime_error &err) { dbFailed = true; error = err.what(); } - if (cert) { - if (!Ssl::certificateMatchesProperties(cert.get(), certProperties)) { - // The certificate changed (renewed or other reason). - // Generete a new one with the updated fields. - cert.reset(); - pkey.reset(); - db.purgeCert(cert_subject); - } - } - if (!cert || !pkey) { if (!Ssl::generateSslCertificate(cert, pkey, certProperties)) throw std::runtime_error("Cannot create ssl certificate or private key."); if (!dbFailed && db.IsEnabledDiskStore()) { try { - if (!db.addCertAndPrivateKey(cert, pkey, cert_subject)) { + if (!db.addCertAndPrivateKey(certKey, cert, pkey, certProperties.mimicCert)) { dbFailed = true; error = "Cannot add certificate to db."; } @@ -289,7 +280,7 @@ if (create_new_db) { std::cout << "Initialization SSL db..." << std::endl; - Ssl::CertificateDb::create(db_path); + Ssl::CertificateDb::Create(db_path); std::cout << "Done" << std::endl; exit(0); } @@ -308,7 +299,7 @@ } { - Ssl::CertificateDb::check(db_path, max_db_size, fs_block_size); + Ssl::CertificateDb::Check(db_path, max_db_size, fs_block_size); } // Initialize SSL subsystem SSL_load_error_strings(); diff -u -r -N squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.8 squid-4.0.22/src/security/cert_validators/fake/security_fake_certverify.8 --- squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.8 2017-07-02 20:57:36.000000000 +1200 +++ squid-4.0.22/src/security/cert_validators/fake/security_fake_certverify.8 2017-12-08 06:19:03.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SECURITY_FAKE_CERTVERIFY 8" -.TH SECURITY_FAKE_CERTVERIFY 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH SECURITY_FAKE_CERTVERIFY 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -139,15 +139,21 @@ .SH "SYNOPSIS" .IX Header "SYNOPSIS" security_fake_certverify [\-d | \-\-debug] [\-h | \-\-help] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +Retrieves the \s-1SSL\s0 certificate error list from Squid and echo back without any change. +.SH "OPTIONS" +.IX Header "OPTIONS" .IP "\fB\-h | \-\-help\fR" 8 .IX Item "-h | --help" brief help message .IP "\fB\-d | \-\-debug\fR" 8 .IX Item "-d | --debug" enable debug messages to stderr -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -Retrieves the \s-1SSL\s0 certificate error list from squid and echo back without any change. +.SH "AUTHOR" +.IX Header "AUTHOR" +This program and documentation was written by +\&\fIChristos Tsantilas .SH "COPYRIGHT" .IX Header "COPYRIGHT" .Vb 5 @@ -163,3 +169,23 @@ This program is free software. You may redistribute copies of it under the terms of the \s-1GNU\s0 General Public License version 2, or (at your opinion) any later version. +.SH "QUESTIONS" +.IX Header "QUESTIONS" +Questions on the usage of this program can be sent to the \fISquid Users mailing list +.SH "REPORTING BUGS" +.IX Header "REPORTING BUGS" +Bug reports need to be made in English. +See http://wiki.squid\-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. +.PP +Report bugs or bug fixes using http://bugs.squid\-cache.org/ +.PP +Report serious security bugs to \fISquid Bugs +.PP +Report ideas for new improvements to the \fISquid Developers mailing list +.SH "SEE ALSO" +.IX Header "SEE ALSO" +squid (8), \s-1GPL\s0 (7), +.PP +The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq +.PP +The Squid Configuration Manual http://www.squid\-cache.org/Doc/config/ diff -u -r -N squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.pl.in squid-4.0.22/src/security/cert_validators/fake/security_fake_certverify.pl.in --- squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/cert_validators/fake/security_fake_certverify.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -1,8 +1,4 @@ #!@PERL@ -# -# A dummy SSL certificate validator helper that -# echos back all the SSL errors sent by Squid. -# use warnings; use strict; @@ -25,6 +21,12 @@ security_fake_certverify [-d | --debug] [-h | --help] +=head1 DESCRIPTION + +Retrieves the SSL certificate error list from Squid and echo back without any change. + +=head1 OPTIONS + =over 8 =item B<-h | --help> @@ -37,9 +39,10 @@ =back -=head1 DESCRIPTION +=head1 AUTHOR -Retrieves the SSL certificate error list from squid and echo back without any change. +This program and documentation was written by +I> =head1 COPYRIGHT @@ -55,6 +58,29 @@ terms of the GNU General Public License version 2, or (at your opinion) any later version. +=head1 QUESTIONS + +Questions on the usage of this program can be sent to the I> + +=head1 REPORTING BUGS + +Bug reports need to be made in English. +See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. + +Report bugs or bug fixes using http://bugs.squid-cache.org/ + +Report serious security bugs to I> + +Report ideas for new improvements to the I> + +=head1 SEE ALSO + +squid (8), GPL (7), + +The Squid FAQ wiki http://wiki.squid-cache.org/SquidFaq + +The Squid Configuration Manual http://www.squid-cache.org/Doc/config/ + =cut GetOptions( diff -u -r -N squid-4.0.21/src/security/forward.h squid-4.0.22/src/security/forward.h --- squid-4.0.21/src/security/forward.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/forward.h 2017-12-08 04:12:12.000000000 +1300 @@ -55,6 +55,14 @@ #endif /* OpenSSL 1.0 CRYPTO_LOCK_X509_CRL */ #endif /* OpenSSL 1.1 DH_up_ref */ +#if !HAVE_LIBCRYPTO_EVP_PKEY_UP_REF +#if defined(CRYPTO_LOCK_EVP_PKEY) // OpenSSL 1.0 +inline int EVP_PKEY_up_ref(EVP_PKEY *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_EVP_PKEY); return 0;} +#endif +#else +#error missing both OpenSSL API features EVP_PKEY_up_ref (v1.1) and CRYPTO_LOCK_EVP_PKEY (v1.0) +#endif + #endif /* USE_OPENSSL */ /* flags a SSL connection can be configured with */ @@ -155,6 +163,15 @@ class PeerConnector; class PeerOptions; + +#if USE_OPENSSL +CtoCpp1(EVP_PKEY_free, EVP_PKEY *) +typedef Security::LockingPointer > PrivateKeyPointer; +#else +// XXX: incompatible with the other PrivateKeyPointer declaration (lacks self-initialization) +typedef void *PrivateKeyPointer; +#endif + class ServerOptions; } // namespace Security diff -u -r -N squid-4.0.21/src/security/Handshake.cc squid-4.0.22/src/security/Handshake.cc --- squid-4.0.21/src/security/Handshake.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/Handshake.cc 2017-12-08 04:12:12.000000000 +1300 @@ -535,9 +535,12 @@ return false; // unreached } -void -Security::HandshakeParser::ParseCertificate(const SBuf &raw, Security::CertPointer &pCert) +/// Creates and returns a certificate by parsing a DER-encoded X509 structure. +/// Throws on failures. +Security::CertPointer +Security::HandshakeParser::ParseCertificate(const SBuf &raw) { + Security::CertPointer pCert; #if USE_OPENSSL auto x509Start = reinterpret_cast(raw.rawContent()); auto x509Pos = x509Start; @@ -546,27 +549,31 @@ Must(x509); // successfully parsed Must(x509Pos == x509Start + raw.length()); // no leftovers #else - // workaround GCC -O3 error with unused variables. see bug 4663. - (void)pCert; - debugs(83, 2, "TLS parsing is not supported without OpenSSL. " << raw); + assert(false); // this code should never be reached + pCert = Security::CertPointer(nullptr); // avoid warnings about uninitialized pCert; XXX: Fix CertPoint declaration. + (void)raw; // avoid warnings about unused method parameter; TODO: Add a SimulateUse() macro. #endif + assert(pCert); + return pCert; } void Security::HandshakeParser::parseServerCertificates(const SBuf &raw) { +#if USE_OPENSSL Parser::BinaryTokenizer tkList(raw); const SBuf clist = tkList.pstring24("CertificateList"); Must(tkList.atEnd()); // no leftovers after all certificates Parser::BinaryTokenizer tkItems(clist); while (!tkItems.atEnd()) { - Security::CertPointer cert; - ParseCertificate(tkItems.pstring24("Certificate"), cert); - serverCertificates.push_back(cert); + if (Security::CertPointer cert = ParseCertificate(tkItems.pstring24("Certificate"))) + serverCertificates.push_back(cert); debugs(83, 7, "parsed " << serverCertificates.size() << " certificates so far"); } - +#else + debugs(83, 7, "no support for CertificateList parsing; ignoring " << raw.length() << " bytes"); +#endif } /// A helper function to create a set of all supported TLS extensions diff -u -r -N squid-4.0.21/src/security/Handshake.h squid-4.0.22/src/security/Handshake.h --- squid-4.0.21/src/security/Handshake.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/Handshake.h 2017-12-08 04:12:12.000000000 +1300 @@ -101,7 +101,7 @@ void parseV23Ciphers(const SBuf &raw); void parseServerCertificates(const SBuf &raw); - static void ParseCertificate(const SBuf &raw, CertPointer &cert); + static CertPointer ParseCertificate(const SBuf &raw); unsigned int currentContentType; ///< The current TLS/SSL record content type diff -u -r -N squid-4.0.21/src/security/PeerConnector.cc squid-4.0.22/src/security/PeerConnector.cc --- squid-4.0.21/src/security/PeerConnector.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/PeerConnector.cc 2017-12-08 04:12:12.000000000 +1300 @@ -660,8 +660,9 @@ if (X509 *cert = d2i_X509(NULL, &raw, obj.length())) { char buffer[1024]; debugs(81, 5, "Retrieved certificate: " << X509_NAME_oneline(X509_get_subject_name(cert), buffer, 1024)); + ContextPointer ctx(getTlsContext()); const Security::CertList &certsList = srvBio->serverCertificatesIfAny(); - if (const char *issuerUri = Ssl::uriOfIssuerIfMissing(cert, certsList)) { + if (const char *issuerUri = Ssl::uriOfIssuerIfMissing(cert, certsList, ctx)) { urlsOfMissingCerts.push(SBuf(issuerUri)); } Ssl::SSL_add_untrusted_cert(session.get(), cert); @@ -698,7 +699,8 @@ if (certs.size()) { debugs(83, 5, "SSL server sent " << certs.size() << " certificates"); - Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs); + ContextPointer ctx(getTlsContext()); + Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs, ctx); if (urlsOfMissingCerts.size()) { startCertDownloading(urlsOfMissingCerts.front()); urlsOfMissingCerts.pop(); diff -u -r -N squid-4.0.21/src/security/PeerOptions.cc squid-4.0.22/src/security/PeerOptions.cc --- squid-4.0.21/src/security/PeerOptions.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/PeerOptions.cc 2017-12-08 04:12:12.000000000 +1300 @@ -282,10 +282,9 @@ Security::ContextPointer t(createBlankContext()); if (t) { + if (setOptions) + updateContextOptions(t); #if USE_OPENSSL - // NP: GnuTLS uses 'priorities' which are set per-session instead. - SSL_CTX_set_options(t.get(), (setOptions ? parsedOptions : 0)); - // XXX: temporary performance regression. c_str() data copies and prevents this being a const method Ssl::InitClientContext(t, *this, parsedFlags); #endif @@ -594,6 +593,16 @@ #endif } +void +Security::PeerOptions::updateContextOptions(Security::ContextPointer &ctx) const +{ +#if USE_OPENSSL + SSL_CTX_set_options(ctx.get(), parsedOptions); +#elif USE_GNUTLS + // NP: GnuTLS uses 'priorities' which are set per-session instead. +#endif +} + #if USE_OPENSSL && defined(TLSEXT_TYPE_next_proto_neg) // Dummy next_proto_neg callback static int @@ -641,11 +650,16 @@ { debugs(83, 8, "Setting CA certificate locations."); #if USE_OPENSSL - const char *path = caDir.isEmpty() ? nullptr : caDir.c_str(); + if (const char *path = caDir.isEmpty() ? nullptr : caDir.c_str()) { + if (!SSL_CTX_load_verify_locations(ctx.get(), nullptr, path)) { + const auto x = ERR_get_error(); + debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " << path << ": " << Security::ErrorString(x)); + } + } #endif for (auto i : caFiles) { #if USE_OPENSSL - if (!SSL_CTX_load_verify_locations(ctx.get(), i.c_str(), path)) { + if (!SSL_CTX_load_verify_locations(ctx.get(), i.c_str(), nullptr)) { const auto x = ERR_get_error(); debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " << i << ": " << Security::ErrorString(x)); diff -u -r -N squid-4.0.21/src/security/PeerOptions.h squid-4.0.22/src/security/PeerOptions.h --- squid-4.0.21/src/security/PeerOptions.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/PeerOptions.h 2017-12-08 04:12:12.000000000 +1300 @@ -44,6 +44,9 @@ /// sync the context options with tls-min-version=N configuration void updateTlsVersionLimits(); + /// Setup the library specific 'options=' parameters for the given context. + void updateContextOptions(Security::ContextPointer &) const; + /// setup the NPN extension details for the given context void updateContextNpn(Security::ContextPointer &); diff -u -r -N squid-4.0.21/src/security/ServerOptions.cc squid-4.0.22/src/security/ServerOptions.cc --- squid-4.0.21/src/security/ServerOptions.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/ServerOptions.cc 2017-12-08 04:12:12.000000000 +1300 @@ -7,9 +7,14 @@ */ #include "squid.h" +#include "anyp/PortCfg.h" #include "base/Packable.h" +#include "cache_cf.h" +#include "fatal.h" #include "globals.h" #include "security/ServerOptions.h" +#include "security/Session.h" +#include "SquidConfig.h" #if USE_OPENSSL #include "ssl/support.h" #endif @@ -21,6 +26,34 @@ #include #endif +Security::ServerOptions & +Security::ServerOptions::operator =(const Security::ServerOptions &old) { + if (this != &old) { + Security::PeerOptions::operator =(old); + clientCaFile = old.clientCaFile; + dh = old.dh; + dhParamsFile = old.dhParamsFile; + eecdhCurve = old.eecdhCurve; + parsedDhParams = old.parsedDhParams; +#if USE_OPENSSL + if (auto *stk = SSL_dup_CA_list(old.clientCaStack.get())) + clientCaStack = Security::ServerOptions::X509_NAME_STACK_Pointer(stk); + else +#endif + clientCaStack = nullptr; + + staticContextSessionId = old.staticContextSessionId; + generateHostCertificates = old.generateHostCertificates; + signingCert = old.signingCert; + signPkey = old.signPkey; + certsToChain = old.certsToChain; + untrustedSigningCert = old.untrustedSigningCert; + untrustedSignPkey = old.untrustedSignPkey; + dynamicCertMemCacheSize = old.dynamicCertMemCacheSize; + } + return *this; +} + void Security::ServerOptions::parse(const char *token) { @@ -65,6 +98,34 @@ loadDhParams(); + } else if (strncmp(token, "dynamic_cert_mem_cache_size=", 28) == 0) { + parseBytesOptionValue(&dynamicCertMemCacheSize, "bytes", token + 28); + // XXX: parseBytesOptionValue() self_destruct()s on invalid values, + // probably making this comparison and misleading ERROR unnecessary. + if (dynamicCertMemCacheSize == std::numeric_limits::max()) { + debugs(3, DBG_CRITICAL, "ERROR: Cannot allocate memory for '" << token << "'. Using default of 4MB instead."); + dynamicCertMemCacheSize = 4*1024*1024; // 4 MB + } + + } else if (strcmp(token, "generate-host-certificates") == 0) { + generateHostCertificates = true; + } else if (strcmp(token, "generate-host-certificates=on") == 0) { + generateHostCertificates = true; + } else if (strcmp(token, "generate-host-certificates=off") == 0) { + generateHostCertificates = false; + + } else if (strncmp(token, "context=", 8) == 0) { +#if USE_OPENSSL + staticContextSessionId = SBuf(token+8); + // to hide its arguably sensitive value, do not print token in these debugs + if (staticContextSessionId.length() > SSL_MAX_SSL_SESSION_ID_LENGTH) { + debugs(83, DBG_CRITICAL, "FATAL: Option 'context=' value is too long. Maximum " << SSL_MAX_SSL_SESSION_ID_LENGTH << " characters."); + self_destruct(); + } +#else + debugs(83, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: Option 'context=' requires --with-openssl. Ignoring."); +#endif + } else { // parse generic TLS options Security::PeerOptions::parse(token); @@ -83,6 +144,15 @@ // dump the server-only options if (!dh.isEmpty()) p->appendf(" %sdh=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(dh)); + + if (!generateHostCertificates) + p->appendf(" %sgenerate-host-certificates=off", pfx); + + if (dynamicCertMemCacheSize != 4*1024*1024) // 4MB default, no 'tls-' prefix + p->appendf(" dynamic_cert_mem_cache_size=%" PRIuSIZE "bytes", dynamicCertMemCacheSize); + + if (!staticContextSessionId.isEmpty()) + p->appendf(" %scontext=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(staticContextSessionId)); } Security::ContextPointer @@ -130,6 +200,8 @@ if (!Ssl::InitServerContext(t, port)) return false; #endif + if (!loadClientCaFile()) + return false; } staticContext = std::move(t); @@ -137,6 +209,75 @@ } void +Security::ServerOptions::createSigningContexts(AnyP::PortCfg &port) +{ + const char *portType = AnyP::ProtocolType_str[port.transport.protocol]; + if (!certs.empty()) { +#if USE_OPENSSL + Security::KeyData &keys = certs.front(); + Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, keys.certFile.c_str(), keys.privateKeyFile.c_str()); +#else + char buf[128]; + fatalf("Directive '%s_port %s' requires --with-openssl.", portType, port.s.toUrl(buf, sizeof(buf))); +#endif + } + + if (!signingCert) { + char buf[128]; + fatalf("No valid signing SSL certificate configured for %s_port %s", portType, port.s.toUrl(buf, sizeof(buf))); + } + + if (!signPkey) + debugs(3, DBG_IMPORTANT, "No SSL private key configured for " << portType << "_port " << port.s); + +#if USE_OPENSSL + Ssl::generateUntrustedCert(untrustedSigningCert, untrustedSignPkey, signingCert, signPkey); +#endif + + if (!untrustedSigningCert) { + char buf[128]; + fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", portType, port.s.toUrl(buf, sizeof(buf))); + } + + if (!createStaticServerContext(port)) { + char buf[128]; + fatalf("%s_port %s initialization error", portType, port.s.toUrl(buf, sizeof(buf))); + } +} + +void +Security::ServerOptions::syncCaFiles() +{ + // if caFiles is set, just use that + if (caFiles.size()) + return; + + // otherwise fall back to clientca if it is defined + if (!clientCaFile.isEmpty()) + caFiles.emplace_back(clientCaFile); +} + +/// load clientca= file (if any) into memory. +/// \retval true clientca is not set, or loaded successfully +/// \retval false unable to load the file, or not using OpenSSL +bool +Security::ServerOptions::loadClientCaFile() +{ + if (clientCaFile.isEmpty()) + return true; + +#if USE_OPENSSL + auto *stk = SSL_load_client_CA_file(clientCaFile.c_str()); + clientCaStack = Security::ServerOptions::X509_NAME_STACK_Pointer(stk); +#endif + if (!clientCaStack) { + debugs(83, DBG_CRITICAL, "FATAL: Unable to read client CAs from file: " << clientCaFile); + } + + return bool(clientCaStack); +} + +void Security::ServerOptions::loadDhParams() { if (dhParamsFile.isEmpty()) @@ -167,6 +308,78 @@ #endif } +bool +Security::ServerOptions::updateContextConfig(Security::ContextPointer &ctx) +{ + updateContextOptions(ctx); + updateContextSessionId(ctx); + +#if USE_OPENSSL + if (parsedFlags & SSL_FLAG_NO_SESSION_REUSE) { + SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF); + } + + if (Config.SSL.unclean_shutdown) { + debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation)."); + SSL_CTX_set_quiet_shutdown(ctx.get(), 1); + } + + if (!sslCipher.isEmpty()) { + debugs(83, 5, "Using cipher suite " << sslCipher << "."); + if (!SSL_CTX_set_cipher_list(ctx.get(), sslCipher.c_str())) { + auto ssl_error = ERR_get_error(); + debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << sslCipher << "': " << Security::ErrorString(ssl_error)); + return false; + } + } + + Ssl::MaybeSetupRsaCallback(ctx); +#endif + + updateContextEecdh(ctx); + updateContextCa(ctx); + updateContextClientCa(ctx); + +#if USE_OPENSSL + if (parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN) + SSL_CTX_set_ex_data(ctx.get(), ssl_ctx_ex_index_dont_verify_domain, (void *) -1); + + Security::SetSessionCacheCallbacks(ctx); +#endif + return true; +} + +void +Security::ServerOptions::updateContextClientCa(Security::ContextPointer &ctx) +{ +#if USE_OPENSSL + if (clientCaStack) { + ERR_clear_error(); + if (STACK_OF(X509_NAME) *clientca = SSL_dup_CA_list(clientCaStack.get())) { + SSL_CTX_set_client_CA_list(ctx.get(), clientca); + } else { + auto ssl_error = ERR_get_error(); + debugs(83, DBG_CRITICAL, "ERROR: Failed to dupe the client CA list: " << Security::ErrorString(ssl_error)); + return; + } + + if (parsedFlags & SSL_FLAG_DELAYED_AUTH) { + debugs(83, 9, "Not requesting client certificates until acl processing requires one"); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, nullptr); + } else { + debugs(83, 9, "Requiring client certificates."); + Ssl::SetupVerifyCallback(ctx); + } + + updateContextCrl(ctx); + + } else { + debugs(83, 9, "Not requiring any client certificates"); + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL); + } +#endif +} + void Security::ServerOptions::updateContextEecdh(Security::ContextPointer &ctx) { @@ -208,3 +421,12 @@ #endif } +void +Security::ServerOptions::updateContextSessionId(Security::ContextPointer &ctx) +{ +#if USE_OPENSSL + if (!staticContextSessionId.isEmpty()) + SSL_CTX_set_session_id_context(ctx.get(), reinterpret_cast(staticContextSessionId.rawContent()), staticContextSessionId.length()); +#endif +} + diff -u -r -N squid-4.0.21/src/security/ServerOptions.h squid-4.0.22/src/security/ServerOptions.h --- squid-4.0.21/src/security/ServerOptions.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/ServerOptions.h 2017-12-08 04:12:12.000000000 +1300 @@ -19,15 +19,20 @@ class ServerOptions : public PeerOptions { public: +#if USE_OPENSSL + sk_dtor_wrapper(sk_X509_NAME, STACK_OF(X509_NAME) *, X509_NAME_free); + typedef std::unique_ptr X509_NAME_STACK_Pointer; +#endif + ServerOptions() : PeerOptions() { // Bug 4005: dynamic contexts use a lot of memory and it // is more secure to have only a small set of trusted CA. flags.tlsDefaultCa.defaultTo(false); } ServerOptions(const ServerOptions &) = default; - ServerOptions &operator =(const ServerOptions &) = default; - ServerOptions(ServerOptions &&) = default; - ServerOptions &operator =(ServerOptions &&) = default; + ServerOptions &operator =(const ServerOptions &); + ServerOptions(ServerOptions &&o) { this->operator =(o); } + ServerOptions &operator =(ServerOptions &&o) { this->operator =(o); return *this; } virtual ~ServerOptions() = default; /* Security::PeerOptions API */ @@ -41,17 +46,54 @@ /// \returns true if a context could be created bool createStaticServerContext(AnyP::PortCfg &); + /// initialize contexts for signing dynamic TLS certificates (if needed) + /// the resulting context is stored in signingCert, signPKey, untrustedSigningCert, untrustedSignPKey + void createSigningContexts(AnyP::PortCfg &); + + /// update the given TLS security context using squid.conf settings + bool updateContextConfig(Security::ContextPointer &); + /// update the context with DH, EDH, EECDH settings void updateContextEecdh(Security::ContextPointer &); + /// update the context with CA details used to verify client certificates + void updateContextClientCa(Security::ContextPointer &); + + /// update the context with a configured session ID (if any) + void updateContextSessionId(Security::ContextPointer &); + + /// sync the various sources of CA files to be loaded + void syncCaFiles(); + public: /// TLS context to use for HTTPS accelerator or static SSL-Bump Security::ContextPointer staticContext; + SBuf staticContextSessionId; ///< "session id context" for staticContext + + bool generateHostCertificates = true; ///< dynamically make host cert + + Security::CertPointer signingCert; ///< x509 certificate for signing generated certificates + Security::PrivateKeyPointer signPkey; ///< private key for signing generated certificates + Security::CertList certsToChain; ///< x509 certificates to send with the generated cert + Security::CertPointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates + Security::PrivateKeyPointer untrustedSignPkey; ///< private key for signing untrusted generated certificates + + /// max size of generated certificates memory cache (4 MB default) + size_t dynamicCertMemCacheSize = 4*1024*1024; private: + bool loadClientCaFile(); void loadDhParams(); private: + SBuf clientCaFile; ///< name of file to load client CAs from +#if USE_OPENSSL + /// CA certificate(s) to use when verifying client certificates + X509_NAME_STACK_Pointer clientCaStack; +#else + void *clientCaStack = nullptr; +#endif + SBuf dh; ///< Diffi-Helman cipher config SBuf dhParamsFile; ///< Diffi-Helman ciphers parameter file SBuf eecdhCurve; ///< Elliptic curve for ephemeral EC-based DH key exchanges diff -u -r -N squid-4.0.21/src/security/Session.cc squid-4.0.22/src/security/Session.cc --- squid-4.0.21/src/security/Session.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/Session.cc 2017-12-08 04:12:12.000000000 +1300 @@ -364,7 +364,7 @@ } if (!session) - debugs(83, 5, "Failed to retrieve SSL_SESSION from cache\n"); + debugs(83, 5, "Failed to retrieve SSL_SESSION from cache"); // With the parameter copy the callback can require the SSL engine // to increment the reference count of the SSL_SESSION object, Normally diff -u -r -N squid-4.0.21/src/security/Session.h squid-4.0.22/src/security/Session.h --- squid-4.0.21/src/security/Session.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/security/Session.h 2017-12-08 04:12:12.000000000 +1300 @@ -78,7 +78,7 @@ void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &); #if USE_OPENSSL -// TODO: remove from public API. It is only public because of configureSslContext() in ssl/support.cc +// TODO: remove from public API. It is only public because of Security::ServerOptions::updateContextConfig /// Setup the given TLS context with callbacks used to manage the session cache void SetSessionCacheCallbacks(Security::ContextPointer &); diff -u -r -N squid-4.0.21/src/servers/FtpServer.cc squid-4.0.22/src/servers/FtpServer.cc --- squid-4.0.21/src/servers/FtpServer.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/servers/FtpServer.cc 2017-12-08 04:12:12.000000000 +1300 @@ -339,6 +339,7 @@ void Ftp::Server::calcUri(const SBuf *file) { + // TODO: fill a class URL instead of string uri = "ftp://"; uri.append(host); if (port->ftp_track_dirs && master->workingDir.length()) { @@ -723,16 +724,15 @@ const SBuf *path = (params.length() && CommandHasPathParameter(cmd)) ? ¶ms : NULL; calcUri(path); - char *newUri = xstrdup(uri.c_str()); MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); mx->tcpClient = clientConnection; - HttpRequest *const request = HttpRequest::FromUrl(newUri, mx, method); + HttpRequest *const request = HttpRequest::FromUrl(uri.c_str(), mx, method); if (!request) { debugs(33, 5, "Invalid FTP URL: " << uri); uri.clear(); - safe_free(newUri); return earlyError(EarlyErrorKind::InvalidUri); } + char *newUri = xstrdup(uri.c_str()); request->flags.ftpNative = true; request->http_ver = Http::ProtocolVersion(Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor); diff -u -r -N squid-4.0.21/src/servers/Http1Server.cc squid-4.0.22/src/servers/Http1Server.cc --- squid-4.0.21/src/servers/Http1Server.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/servers/Http1Server.cc 2017-12-08 04:12:12.000000000 +1300 @@ -132,6 +132,7 @@ return false; } + // TODO: move URL parse into Http Parser and INVALID_URL into the above parse error handling MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); mx->tcpClient = clientConnection; if ((request = HttpRequest::FromUrl(http->uri, mx, parser_->method())) == NULL) { diff -u -r -N squid-4.0.21/src/squid.8.in squid-4.0.22/src/squid.8.in --- squid-4.0.21/src/squid.8.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/squid.8.in 2017-12-08 04:12:12.000000000 +1300 @@ -253,7 +253,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS Bug reports need to be made in English. @@ -262,11 +262,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .B cachemgr.cgi "(8), " diff -u -r -N squid-4.0.21/src/SquidString.h squid-4.0.22/src/SquidString.h --- squid-4.0.21/src/SquidString.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/SquidString.h 2017-12-08 04:12:12.000000000 +1300 @@ -45,7 +45,7 @@ /// The absolute size limit on data held in a String. /// Since Strings can be nil-terminated implicitly it is best to ensure /// the useful content length is strictly less than this limit. - static const size_type SizeMaxXXX() { return SizeMax_; } + static size_type SizeMaxXXX() { return SizeMax_; } _SQUID_INLINE_ size_type size() const; /// variant of size() suited to be used for printf-alikes. diff -u -r -N squid-4.0.21/src/ssl/bio.cc squid-4.0.22/src/ssl/bio.cc --- squid-4.0.21/src/ssl/bio.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/bio.cc 2017-12-08 04:12:12.000000000 +1300 @@ -336,12 +336,12 @@ int Ssl::ServerBio::readAndBuffer(BIO *table) { - char *space = rbuf.rawSpace(SQUID_TCP_SO_RCVBUF); - const int result = Ssl::Bio::read(space, rbuf.spaceSize(), table); + char *space = rbuf.rawAppendStart(SQUID_TCP_SO_RCVBUF); + const int result = Ssl::Bio::read(space, SQUID_TCP_SO_RCVBUF, table); if (result <= 0) return result; - rbuf.forceSize(rbuf.length() + result); + rbuf.rawAppendFinish(space, result); return result; } diff -u -r -N squid-4.0.21/src/ssl/cert_validate_message.cc squid-4.0.22/src/ssl/cert_validate_message.cc --- squid-4.0.21/src/ssl/cert_validate_message.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/cert_validate_message.cc 2017-12-08 04:12:12.000000000 +1300 @@ -16,12 +16,28 @@ #include "ssl/support.h" #include "util.h" +/// Retrieves the certificates chain used to verify the peer. +/// This is the full chain built by OpenSSL while verifying the server +/// certificate or, if this is not available, the chain sent by server. +/// \return the certificates chain or nil +static STACK_OF(X509) * +PeerValidationCertificatesChain(const Security::SessionPointer &ssl) +{ + assert(ssl); + // The full chain built by openSSL while verifying the server cert, + // retrieved from verify callback: + if (const auto certs = static_cast(SSL_get_ex_data(ssl.get(), ssl_ex_index_ssl_cert_chain))) + return certs; + + /// Last resort: certificates chain sent by server + return SSL_get_peer_cert_chain(ssl.get()); // may be nil +} + void Ssl::CertValidationMsg::composeRequest(CertValidationRequest const &vcert) { body.clear(); body += Ssl::CertValidationMsg::param_host + "=" + vcert.domainName; - STACK_OF(X509) *peerCerts = static_cast(SSL_get_ex_data(vcert.ssl.get(), ssl_ex_index_ssl_cert_chain)); if (const char *sslVersion = SSL_get_version(vcert.ssl.get())) body += "\n" + Ssl::CertValidationMsg::param_proto_version + "=" + sslVersion; @@ -29,9 +45,7 @@ if (const char *cipherName = SSL_CIPHER_get_name(SSL_get_current_cipher(vcert.ssl.get()))) body += "\n" + Ssl::CertValidationMsg::param_cipher + "=" + cipherName; - if (!peerCerts) - peerCerts = SSL_get_peer_cert_chain(vcert.ssl.get()); - + STACK_OF(X509) *peerCerts = PeerValidationCertificatesChain(vcert.ssl); if (peerCerts) { Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); for (int i = 0; i < sk_X509_num(peerCerts); ++i) { @@ -75,10 +89,12 @@ } bool -Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp, STACK_OF(X509) *peerCerts, std::string &error) +Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp, std::string &error) { std::vector certs; + const STACK_OF(X509) *peerCerts = PeerValidationCertificatesChain(resp.ssl); + const char *param = body.c_str(); while (*param) { while (xisspace(*param)) param++; diff -u -r -N squid-4.0.21/src/ssl/cert_validate_message.h squid-4.0.22/src/ssl/cert_validate_message.h --- squid-4.0.21/src/ssl/cert_validate_message.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/cert_validate_message.h 2017-12-08 04:12:12.000000000 +1300 @@ -59,12 +59,13 @@ }; typedef std::vector RecvdErrors; - + explicit CertValidationResponse(const Security::SessionPointer &aSession) : ssl(aSession) {} /// Search in errors list for the error item with id=errorId. /// If none found a new RecvdError item added with the given id; RecvdError &getError(int errorId); RecvdErrors errors; ///< The list of parsed errors Helper::ResultCode resultCode; ///< The helper result code + Security::SessionPointer ssl; }; /** @@ -99,7 +100,7 @@ void composeRequest(CertValidationRequest const &vcert); /// Parse a response message and fill the resp object with parsed informations - bool parseResponse(CertValidationResponse &resp, STACK_OF(X509) *peerCerts, std::string &error); + bool parseResponse(CertValidationResponse &resp, std::string &error); /// Search a CertItems list for the certificate with ID "name" X509 *getCertByName(std::vector const &, std::string const & name); diff -u -r -N squid-4.0.21/src/ssl/context_storage.h squid-4.0.22/src/ssl/context_storage.h --- squid-4.0.21/src/ssl/context_storage.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/context_storage.h 2017-12-08 04:12:12.000000000 +1300 @@ -48,7 +48,7 @@ virtual bool aggregatable() const { return false; } }; -typedef LruMap LocalContextStorage; +typedef LruMap LocalContextStorage; /// Class for storing/manipulating LocalContextStorage per local listening address/port. class GlobalContextStorage diff -u -r -N squid-4.0.21/src/ssl/gadgets.cc squid-4.0.22/src/ssl/gadgets.cc --- squid-4.0.21/src/ssl/gadgets.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/gadgets.cc 2017-12-08 04:12:12.000000000 +1300 @@ -9,13 +9,14 @@ #include "squid.h" #include "ssl/gadgets.h" +#include #if HAVE_OPENSSL_X509V3_H #include #endif EVP_PKEY * Ssl::createSslPrivateKey() { - Ssl::EVP_PKEY_Pointer pkey(EVP_PKEY_new()); + Security::PrivateKeyPointer pkey(EVP_PKEY_new()); if (!pkey) return NULL; @@ -69,7 +70,7 @@ return true; } -bool Ssl::writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite) +bool Ssl::writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey, std::string & bufferToWrite) { bufferToWrite.clear(); if (!pkey || !cert) @@ -117,27 +118,7 @@ return true; } -bool Ssl::writeCertAndPrivateKeyToFile(Security::CertPointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, char const * filename) -{ - if (!pkey || !cert) - return false; - - Ssl::BIO_Pointer bio(BIO_new(BIO_s_file())); - if (!bio) - return false; - if (!BIO_write_filename(bio.get(), const_cast(filename))) - return false; - - if (!PEM_write_bio_X509(bio.get(), cert.get())) - return false; - - if (!PEM_write_bio_PrivateKey(bio.get(), pkey.get(), NULL, NULL, 0, NULL, NULL)) - return false; - - return true; -} - -bool Ssl::readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * bufferToRead) +bool Ssl::readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, char const * bufferToRead) { Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); BIO_puts(bio.get(), bufferToRead); @@ -238,40 +219,53 @@ signHash(NULL) {} -std::string & Ssl::CertificateProperties::dbKey() const +static void +printX509Signature(const Security::CertPointer &cert, std::string &out) +{ + const ASN1_BIT_STRING *sig = Ssl::X509_get_signature(cert); + if (sig && sig->data) { + const unsigned char *s = sig->data; + for (int i = 0; i < sig->length; ++i) { + char hex[3]; + snprintf(hex, sizeof(hex), "%02x", s[i]); + out.append(hex); + } + } +} + +std::string & +Ssl::OnDiskCertificateDbKey(const Ssl::CertificateProperties &properties) { static std::string certKey; certKey.clear(); certKey.reserve(4096); - if (mimicCert.get()) { - char buf[1024]; - certKey.append(X509_NAME_oneline(X509_get_subject_name(mimicCert.get()), buf, sizeof(buf))); - } + if (properties.mimicCert.get()) + printX509Signature(properties.mimicCert, certKey); if (certKey.empty()) { certKey.append("/CN=", 4); - certKey.append(commonName); + certKey.append(properties.commonName); } - if (setValidAfter) + if (properties.setValidAfter) certKey.append("+SetValidAfter=on", 17); - if (setValidBefore) + if (properties.setValidBefore) certKey.append("+SetValidBefore=on", 18); - if (setCommonName) { + if (properties.setCommonName) { certKey.append("+SetCommonName=", 15); - certKey.append(commonName); + certKey.append(properties.commonName); } - if (signAlgorithm != Ssl::algSignEnd) { + if (properties.signAlgorithm != Ssl::algSignEnd) { certKey.append("+Sign=", 6); - certKey.append(certSignAlgorithm(signAlgorithm)); + certKey.append(certSignAlgorithm(properties.signAlgorithm)); } - if (signHash != NULL) { + if (properties.signHash != NULL) { certKey.append("+SignHash=", 10); - certKey.append(EVP_MD_name(signHash)); + certKey.append(EVP_MD_name(properties.signHash)); } return certKey; @@ -560,9 +554,9 @@ return true; } -static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties, Ssl::BIGNUM_Pointer const &serial) +static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Security::PrivateKeyPointer & pkeyToStore, Ssl::CertificateProperties const &properties, Ssl::BIGNUM_Pointer const &serial) { - Ssl::EVP_PKEY_Pointer pkey; + Security::PrivateKeyPointer pkey; // Use signing certificates private key as generated certificate private key if (properties.signWithPkey.get()) pkey.resetAndLock(properties.signWithPkey.get()); @@ -666,7 +660,7 @@ /// for a new generated certificate static bool createSerial(Ssl::BIGNUM_Pointer &serial, Ssl::CertificateProperties const &properties) { - Ssl::EVP_PKEY_Pointer fakePkey; + Security::PrivateKeyPointer fakePkey; Security::CertPointer fakeCert; serial.reset(x509Pubkeydigest(properties.signWithX509)); @@ -688,7 +682,7 @@ return true; } -bool Ssl::generateSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties) +bool Ssl::generateSslCertificate(Security::CertPointer & certToStore, Security::PrivateKeyPointer & pkeyToStore, Ssl::CertificateProperties const &properties) { Ssl::BIGNUM_Pointer serial; @@ -698,46 +692,79 @@ return generateFakeSslCertificate(certToStore, pkeyToStore, properties, serial); } -/** - \ingroup ServerProtocolSSLInternal - * Read certificate from file. - */ -static X509 * readSslX509Certificate(char const * certFilename) +bool +Ssl::OpenCertsFileForReading(Ssl::BIO_Pointer &bio, const char *filename) { - if (!certFilename) - return NULL; - Ssl::BIO_Pointer bio(BIO_new(BIO_s_file())); + bio.reset(BIO_new(BIO_s_file())); if (!bio) - return NULL; - if (!BIO_read_filename(bio.get(), certFilename)) - return NULL; - X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL); - return certificate; + return false; + if (!BIO_read_filename(bio.get(), filename)) + return false; + return true; +} + +bool +Ssl::ReadX509Certificate(Ssl::BIO_Pointer &bio, Security::CertPointer & cert) +{ + assert(bio); + if (X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) { + cert.resetWithoutLocking(certificate); + return true; + } + return false; } -EVP_PKEY * Ssl::readSslPrivateKey(char const * keyFilename, pem_password_cb *passwd_callback) +bool +Ssl::ReadPrivateKey(Ssl::BIO_Pointer &bio, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback) +{ + assert(bio); + if (EVP_PKEY *akey = PEM_read_bio_PrivateKey(bio.get(), NULL, passwd_callback, NULL)) { + pkey.resetWithoutLocking(akey); + return true; + } + return false; +} + +void +Ssl::ReadPrivateKeyFromFile(char const * keyFilename, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback) { if (!keyFilename) - return NULL; - Ssl::BIO_Pointer bio(BIO_new(BIO_s_file())); + return; + Ssl::BIO_Pointer bio; + if (!OpenCertsFileForReading(bio, keyFilename)) + return; + ReadPrivateKey(bio, pkey, passwd_callback); +} + +bool +Ssl::OpenCertsFileForWriting(Ssl::BIO_Pointer &bio, const char *filename) +{ + bio.reset(BIO_new(BIO_s_file())); if (!bio) - return NULL; - if (!BIO_read_filename(bio.get(), keyFilename)) - return NULL; - EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio.get(), NULL, passwd_callback, NULL); - return pkey; + return false; + if (!BIO_write_filename(bio.get(), const_cast(filename))) + return false; + return true; } -void Ssl::readCertAndPrivateKeyFromFiles(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename) +bool +Ssl::WriteX509Certificate(Ssl::BIO_Pointer &bio, const Security::CertPointer & cert) { - if (keyFilename == NULL) - keyFilename = certFilename; - pkey.resetWithoutLocking(readSslPrivateKey(keyFilename)); - cert.resetWithoutLocking(readSslX509Certificate(certFilename)); - if (!pkey || !cert || !X509_check_private_key(cert.get(), pkey.get())) { - pkey.reset(); - cert.reset(); - } + if (!cert || !bio) + return false; + if (!PEM_write_bio_X509(bio.get(), cert.get())) + return false; + return true; +} + +bool +Ssl::WritePrivateKey(Ssl::BIO_Pointer &bio, const Security::PrivateKeyPointer &pkey) +{ + if (!pkey || !bio) + return false; + if (!PEM_write_bio_PrivateKey(bio.get(), pkey.get(), NULL, NULL, 0, NULL, NULL)) + return false; + return true; } bool Ssl::sslDateIsInTheFuture(char const * date) @@ -893,3 +920,46 @@ return getSubjectEntry(x509, NID_organizationName); } +bool +Ssl::CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2) +{ + if (!cert1 || ! cert2) + return false; + + int cert1Len; + unsigned char *cert1Asn = NULL; + cert1Len = ASN1_item_i2d((ASN1_VALUE *)cert1.get(), &cert1Asn, ASN1_ITEM_rptr(X509)); + + int cert2Len; + unsigned char *cert2Asn = NULL; + cert2Len = ASN1_item_i2d((ASN1_VALUE *)cert2.get(), &cert2Asn, ASN1_ITEM_rptr(X509)); + + if (cert1Len != cert2Len) + return false; + + bool ret = (memcmp(cert1Asn, cert2Asn, cert1Len) == 0); + + OPENSSL_free(cert1Asn); + OPENSSL_free(cert2Asn); + + return ret; +} + +const ASN1_BIT_STRING * +Ssl::X509_get_signature(const Security::CertPointer &cert) +{ +#if HAVE_LIBCRYPTO_X509_GET0_SIGNATURE +#if SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS + const ASN1_BIT_STRING *sig = nullptr; + const X509_ALGOR *sig_alg = nullptr; +#else + ASN1_BIT_STRING *sig = nullptr; + X509_ALGOR *sig_alg = nullptr; +#endif + X509_get0_signature(&sig, &sig_alg, cert.get()); + return sig; +#else + return cert->signature; +#endif +} + diff -u -r -N squid-4.0.21/src/ssl/gadgets.h squid-4.0.22/src/ssl/gadgets.h --- squid-4.0.21/src/ssl/gadgets.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/gadgets.h 2017-12-08 04:12:12.000000000 +1300 @@ -45,12 +45,6 @@ sk_dtor_wrapper(sk_X509, STACK_OF(X509) *, X509_free); typedef std::unique_ptr X509_STACK_Pointer; -CtoCpp1(EVP_PKEY_free, EVP_PKEY *) -#if defined(CRYPTO_LOCK_EVP_PKEY) // OpenSSL 1.0 -inline int EVP_PKEY_up_ref(EVP_PKEY *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_EVP_PKEY); return 0;} -#endif -typedef Security::LockingPointer > EVP_PKEY_Pointer; - typedef std::unique_ptr> BIGNUM_Pointer; typedef std::unique_ptr> BIO_Pointer; @@ -67,9 +61,6 @@ typedef std::unique_ptr> X509_REQ_Pointer; -sk_dtor_wrapper(sk_X509_NAME, STACK_OF(X509_NAME) *, X509_NAME_free); -typedef std::unique_ptr X509_NAME_STACK_Pointer; - typedef std::unique_ptr> AUTHORITY_KEYID_Pointer; sk_dtor_wrapper(sk_GENERAL_NAME, STACK_OF(GENERAL_NAME) *, GENERAL_NAME_free); @@ -89,7 +80,7 @@ \ingroup SslCrtdSslAPI * Write private key and SSL certificate to memory. */ -bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite); +bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey, std::string & bufferToWrite); /** \ingroup SslCrtdSslAPI @@ -99,21 +90,58 @@ /** \ingroup SslCrtdSslAPI - * Write private key and SSL certificate to file. + * Write private key and SSL certificate to memory. */ -bool writeCertAndPrivateKeyToFile(Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey, char const * filename); +bool readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, char const * bufferToRead); /** \ingroup SslCrtdSslAPI - * Write private key and SSL certificate to memory. + * Read SSL certificate from memory. */ -bool readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, char const * bufferToRead); +bool readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead); /** \ingroup SslCrtdSslAPI - * Read SSL certificate from memory. + * Read private key from file. */ -bool readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead); +void ReadPrivateKeyFromFile(char const * keyFilename, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback); + +/** + \ingroup SslCrtdSslAPI + * Initialize the bio with the file 'filename' openned for reading + */ +bool OpenCertsFileForReading(BIO_Pointer &bio, const char *filename); + +/** + \ingroup SslCrtdSslAPI + * Read a certificate from bio + */ +bool ReadX509Certificate(BIO_Pointer &bio, Security::CertPointer & cert); + +/** + \ingroup SslCrtdSslAPI + * Read a private key from bio + */ +bool ReadPrivateKey(BIO_Pointer &bio, Security::PrivateKeyPointer &pkey, pem_password_cb *passwd_callback); + +/** + \ingroup SslCrtdSslAPI + * Initialize the bio with the file 'filename' openned for writting + */ + +bool OpenCertsFileForWriting(BIO_Pointer &bio, const char *filename); + +/** + \ingroup SslCrtdSslAPI + * Write certificate to BIO. + */ +bool WriteX509Certificate(BIO_Pointer &bio, const Security::CertPointer & cert); + +/** + \ingroup SslCrtdSslAPI + * Write private key to BIO. + */ +bool WritePrivateKey(BIO_Pointer &bio, const Security::PrivateKeyPointer &pkey); /** \ingroup SslCrtdSslAPI @@ -187,21 +215,22 @@ CertificateProperties(); Security::CertPointer mimicCert; ///< Certificate to mimic Security::CertPointer signWithX509; ///< Certificate to sign the generated request - EVP_PKEY_Pointer signWithPkey; ///< The key of the signing certificate + Security::PrivateKeyPointer signWithPkey; ///< The key of the signing certificate bool setValidAfter; ///< Do not mimic "Not Valid After" field bool setValidBefore; ///< Do not mimic "Not Valid Before" field bool setCommonName; ///< Replace the CN field of the mimicing subject with the given std::string commonName; ///< A CN to use for the generated certificate CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use const EVP_MD *signHash; ///< The signing hash to use - /// Returns certificate database primary key. New fake certificates - /// purge old fake certificates with the same key. - std::string & dbKey() const; private: CertificateProperties(CertificateProperties &); CertificateProperties &operator =(CertificateProperties const &); }; +/// \ingroup SslCrtdSslAPI +/// \returns certificate database key +std::string & OnDiskCertificateDbKey(const CertificateProperties &); + /** \ingroup SslCrtdSslAPI * Decide on the kind of certificate and generate a CA- or self-signed one. @@ -209,21 +238,7 @@ * Return generated certificate and private key in resultX509 and resultPkey * variables. */ -bool generateSslCertificate(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, CertificateProperties const &properties); - -/** - \ingroup SslCrtdSslAPI - * Read private key from file. Make sure that this is not encrypted file. - */ -EVP_PKEY * readSslPrivateKey(char const * keyFilename, pem_password_cb *passwd_callback = NULL); - -/** - \ingroup SslCrtdSslAPI - * Read certificate and private key from files. - * \param certFilename name of file with certificate. - * \param keyFilename name of file with private key. - */ -void readCertAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename); +bool generateSslCertificate(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, CertificateProperties const &properties); /** \ingroup SslCrtdSslAPI @@ -254,6 +269,14 @@ */ const char *getOrganization(X509 *x509); +/// \ingroup ServerProtocolSSLAPI +/// \return whether both certificates exist and are the same (e.g., have identical ASN.1 images) +bool CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2); + +/// wrapper for OpenSSL X509_get0_signature() which takes care of +/// portability issues with older OpenSSL versions +const ASN1_BIT_STRING *X509_get_signature(const Security::CertPointer &); + } // namespace Ssl #endif // SQUID_SSL_GADGETS_H diff -u -r -N squid-4.0.21/src/ssl/helper.cc squid-4.0.22/src/ssl/helper.cc --- squid-4.0.21/src/ssl/helper.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/helper.cc 2017-12-08 04:12:12.000000000 +1300 @@ -90,7 +90,7 @@ // TODO: generate host certificates for SNI enabled accel ports bool found = false; for (AnyP::PortCfgPointer s = HttpPortList; !found && s != NULL; s = s->next) - found = s->flags.tunnelSslBumping && s->generateHostCertificates; + found = s->flags.tunnelSslBumping && s->secure.generateHostCertificates; if (!found) return; @@ -254,7 +254,7 @@ CBDATA_CLASS(submitData); public: - std::string query; + SBuf query; AsyncCall::Pointer callback; Security::SessionPointer ssl; }; @@ -264,11 +264,11 @@ sslCrtvdHandleReplyWrapper(void *data, const ::Helper::Reply &reply) { Ssl::CertValidationMsg replyMsg(Ssl::CrtdMessage::REPLY); - Ssl::CertValidationResponse::Pointer validationResponse = new Ssl::CertValidationResponse; std::string error; submitData *crtdvdData = static_cast(data); - STACK_OF(X509) *peerCerts = SSL_get_peer_cert_chain(crtdvdData->ssl.get()); + assert(crtdvdData->ssl.get()); + Ssl::CertValidationResponse::Pointer validationResponse = new Ssl::CertValidationResponse(crtdvdData->ssl); if (reply.result == ::Helper::BrokenHelper) { debugs(83, DBG_IMPORTANT, "\"ssl_crtvd\" helper error response: " << reply.other().content()); validationResponse->resultCode = ::Helper::BrokenHelper; @@ -276,7 +276,7 @@ debugs(83, DBG_IMPORTANT, "\"ssl_crtvd\" helper returned NULL response"); validationResponse->resultCode = ::Helper::BrokenHelper; } else if (replyMsg.parse(reply.other().content(), reply.other().contentSize()) != Ssl::CrtdMessage::OK || - !replyMsg.parseResponse(*validationResponse, peerCerts, error) ) { + !replyMsg.parseResponse(*validationResponse, error) ) { debugs(83, DBG_IMPORTANT, "WARNING: Reply from ssl_crtvd for " << " is incorrect"); debugs(83, DBG_IMPORTANT, "Certificate cannot be validated. ssl_crtvd response: " << replyMsg.getBody()); validationResponse->resultCode = ::Helper::BrokenHelper; @@ -291,7 +291,7 @@ if (Ssl::CertValidationHelper::HelperCache && (validationResponse->resultCode == ::Helper::Okay || validationResponse->resultCode == ::Helper::Error)) { Ssl::CertValidationResponse::Pointer *item = new Ssl::CertValidationResponse::Pointer(validationResponse); - if (!Ssl::CertValidationHelper::HelperCache->add(crtdvdData->query.c_str(), item)) + if (!Ssl::CertValidationHelper::HelperCache->add(crtdvdData->query, item)) delete item; } @@ -308,14 +308,14 @@ debugs(83, 5, "SSL crtvd request: " << message.compose().c_str()); submitData *crtdvdData = new submitData; - crtdvdData->query = message.compose(); - crtdvdData->query += '\n'; + crtdvdData->query.assign(message.compose().c_str()); + crtdvdData->query.append('\n'); crtdvdData->callback = callback; crtdvdData->ssl = request.ssl; Ssl::CertValidationResponse::Pointer const*validationResponse; if (CertValidationHelper::HelperCache && - (validationResponse = CertValidationHelper::HelperCache->get(crtdvdData->query.c_str()))) { + (validationResponse = CertValidationHelper::HelperCache->get(crtdvdData->query))) { CertValidationHelper::CbDialer *dialer = dynamic_cast(callback->getDialer()); Must(dialer); @@ -326,7 +326,7 @@ } if (!ssl_crt_validator->trySubmit(crtdvdData->query.c_str(), sslCrtvdHandleReplyWrapper, crtdvdData)) { - Ssl::CertValidationResponse::Pointer resp = new Ssl::CertValidationResponse;; + Ssl::CertValidationResponse::Pointer resp = new Ssl::CertValidationResponse(crtdvdData->ssl); resp->resultCode = ::Helper::BrokenHelper; Ssl::CertValidationHelper::CbDialer *dialer = dynamic_cast(callback->getDialer()); Must(dialer); diff -u -r -N squid-4.0.21/src/ssl/helper.h squid-4.0.22/src/ssl/helper.h --- squid-4.0.21/src/ssl/helper.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/helper.h 2017-12-08 04:12:12.000000000 +1300 @@ -61,7 +61,7 @@ helper * ssl_crt_validator; ///< helper for management of ssl_crtd. public: - typedef LruMap LruCache; + typedef LruMap LruCache; static LruCache *HelperCache; ///< cache for cert validation helper }; diff -u -r -N squid-4.0.21/src/ssl/ServerBump.h squid-4.0.22/src/ssl/ServerBump.h --- squid-4.0.21/src/ssl/ServerBump.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/ServerBump.h 2017-12-08 04:12:12.000000000 +1300 @@ -15,6 +15,7 @@ #include "HttpRequest.h" #include "ip/Address.h" #include "security/forward.h" +#include "Store.h" class ConnStateData; class store_client; @@ -35,6 +36,9 @@ void attachServerSession(const Security::SessionPointer &); ///< Sets the server TLS session object const Security::CertErrors *sslErrors() const; ///< SSL [certificate validation] errors + /// whether there was a successful connection to (and peeking at) the origin server + bool connectedOk() const {return entry && entry->isEmpty();} + /// faked, minimal request; required by Client API HttpRequest::Pointer request; StoreEntry *entry; ///< for receiving Squid-generated error messages diff -u -r -N squid-4.0.21/src/ssl/support.cc squid-4.0.22/src/ssl/support.cc --- squid-4.0.21/src/ssl/support.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/support.cc 2017-12-08 04:12:12.000000000 +1300 @@ -146,8 +146,8 @@ } #endif -static void -maybeSetupRsaCallback(Security::ContextPointer &ctx) +void +Ssl::MaybeSetupRsaCallback(Security::ContextPointer &ctx) { #if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK debugs(83, 9, "Setting RSA key generation callback."); @@ -376,6 +376,12 @@ return ok; } +void +Ssl::SetupVerifyCallback(Security::ContextPointer &ctx) +{ + SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb); +} + // "dup" function for SSL_get_ex_new_index("cert_err_check") #if SQUID_USE_CONST_CRYPTO_EX_DATA_DUP static int @@ -500,124 +506,29 @@ ssl_ex_index_ssl_untrusted_chain = SSL_get_ex_new_index(0, (void *) "ssl_untrusted_chain", NULL, NULL, &ssl_free_CertChain); } -static bool -configureSslContext(Security::ContextPointer &ctx, AnyP::PortCfg &port) -{ - int ssl_error; - SSL_CTX_set_options(ctx.get(), port.secure.parsedOptions); - - if (port.sslContextSessionId) - SSL_CTX_set_session_id_context(ctx.get(), (const unsigned char *)port.sslContextSessionId, strlen(port.sslContextSessionId)); - - if (port.secure.parsedFlags & SSL_FLAG_NO_SESSION_REUSE) { - SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF); - } - - if (Config.SSL.unclean_shutdown) { - debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation)."); - - SSL_CTX_set_quiet_shutdown(ctx.get(), 1); - } - - if (!port.secure.sslCipher.isEmpty()) { - debugs(83, 5, "Using chiper suite " << port.secure.sslCipher << "."); - - if (!SSL_CTX_set_cipher_list(ctx.get(), port.secure.sslCipher.c_str())) { - ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.secure.sslCipher << "': " << Security::ErrorString(ssl_error)); - return false; - } - } - - maybeSetupRsaCallback(ctx); - - port.secure.updateContextEecdh(ctx); - port.secure.updateContextCa(ctx); - - if (port.clientCA.get()) { - ERR_clear_error(); - if (STACK_OF(X509_NAME) *clientca = SSL_dup_CA_list(port.clientCA.get())) { - SSL_CTX_set_client_CA_list(ctx.get(), clientca); - } else { - ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: Failed to dupe the client CA list: " << Security::ErrorString(ssl_error)); - return false; - } - - if (port.secure.parsedFlags & SSL_FLAG_DELAYED_AUTH) { - debugs(83, 9, "Not requesting client certificates until acl processing requires one"); - SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL); - } else { - debugs(83, 9, "Requiring client certificates."); - SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb); - } - - port.secure.updateContextCrl(ctx); - - } else { - debugs(83, 9, "Not requiring any client certificates"); - SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL); - } - - if (port.secure.parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN) - SSL_CTX_set_ex_data(ctx.get(), ssl_ctx_ex_index_dont_verify_domain, (void *) -1); - - Security::SetSessionCacheCallbacks(ctx); - - return true; -} - bool Ssl::InitServerContext(Security::ContextPointer &ctx, AnyP::PortCfg &port) { if (!ctx) return false; - if (!SSL_CTX_use_certificate(ctx.get(), port.signingCert.get())) { + if (!SSL_CTX_use_certificate(ctx.get(), port.secure.signingCert.get())) { const int ssl_error = ERR_get_error(); const auto &keys = port.secure.certs.front(); debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS certificate '" << keys.certFile << "': " << Security::ErrorString(ssl_error)); return false; } - if (!SSL_CTX_use_PrivateKey(ctx.get(), port.signPkey.get())) { + if (!SSL_CTX_use_PrivateKey(ctx.get(), port.secure.signPkey.get())) { const int ssl_error = ERR_get_error(); const auto &keys = port.secure.certs.front(); debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS private key '" << keys.privateKeyFile << "': " << Security::ErrorString(ssl_error)); return false; } - Ssl::addChainToSslContext(ctx, port.certsToChain.get()); - - /* Alternate code; - debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile); - - if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) { - ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << Security::ErrorString(ssl_error)); - return false; - } - - debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile); - ssl_ask_password(ctx.get(), keyfile); - - if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) { - ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << Security::ErrorString(ssl_error)); - return false; - } - - debugs(83, 5, "Comparing private and public SSL keys."); - - if (!SSL_CTX_check_private_key(ctx.get())) { - ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" << - keyfile << "': " << Security::ErrorString(ssl_error)); - return false; - } - */ + Ssl::addChainToSslContext(ctx, port.secure.certsToChain); - if (!configureSslContext(ctx, port)) { + if (!port.secure.updateContextConfig(ctx)) { debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context"); return false; } @@ -675,14 +586,14 @@ } } - maybeSetupRsaCallback(ctx); + MaybeSetupRsaCallback(ctx); if (fl & SSL_FLAG_DONT_VERIFY_PEER) { - debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!"); + debugs(83, 2, "SECURITY WARNING: Peer certificates are not verified for validity!"); SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL); } else { debugs(83, 9, "Setting certificate verification callback."); - SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb); + Ssl::SetupVerifyCallback(ctx); } return true; @@ -877,9 +788,9 @@ /// Create SSL context and apply ssl certificate and private key to it. Security::ContextPointer -Ssl::createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port) +Ssl::createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &options) { - Security::ContextPointer ctx(port.secure.createBlankContext()); + Security::ContextPointer ctx(options.createBlankContext()); if (!SSL_CTX_use_certificate(ctx.get(), x509.get())) return Security::ContextPointer(); @@ -887,40 +798,46 @@ if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get())) return Security::ContextPointer(); - if (!configureSslContext(ctx, port)) + if (!options.updateContextConfig(ctx)) return Security::ContextPointer(); return ctx; } Security::ContextPointer -Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port) +Ssl::GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &options, bool trusted) { Security::CertPointer cert; - Ssl::EVP_PKEY_Pointer pkey; + Security::PrivateKeyPointer pkey; if (!readCertAndPrivateKeyFromMemory(cert, pkey, data) || !cert || !pkey) return Security::ContextPointer(); - return createSSLContext(cert, pkey, port); + Security::ContextPointer ctx(createSSLContext(cert, pkey, options)); + if (ctx && trusted) + Ssl::chainCertificatesToSSLContext(ctx, options); + return ctx; } Security::ContextPointer -Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port) +Ssl::GenerateSslContext(CertificateProperties const &properties, Security::ServerOptions &options, bool trusted) { Security::CertPointer cert; - Ssl::EVP_PKEY_Pointer pkey; + Security::PrivateKeyPointer pkey; if (!generateSslCertificate(cert, pkey, properties) || !cert || !pkey) return Security::ContextPointer(); - return createSSLContext(cert, pkey, port); + Security::ContextPointer ctx(createSSLContext(cert, pkey, options)); + if (ctx && trusted) + Ssl::chainCertificatesToSSLContext(ctx, options); + return ctx; } void -Ssl::chainCertificatesToSSLContext(Security::ContextPointer &ctx, AnyP::PortCfg &port) +Ssl::chainCertificatesToSSLContext(Security::ContextPointer &ctx, Security::ServerOptions &options) { assert(ctx); // Add signing certificate to the certificates chain - X509 *signingCert = port.signingCert.get(); + X509 *signingCert = options.signingCert.get(); if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) { // increase the certificate lock X509_up_ref(signingCert); @@ -928,21 +845,21 @@ const int ssl_error = ERR_get_error(); debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << Security::ErrorString(ssl_error)); } - Ssl::addChainToSslContext(ctx, port.certsToChain.get()); + Ssl::addChainToSslContext(ctx, options.certsToChain); } void Ssl::configureUnconfiguredSslContext(Security::ContextPointer &ctx, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port) { if (ctx && signAlgorithm == Ssl::algSignTrusted) - Ssl::chainCertificatesToSSLContext(ctx, port); + Ssl::chainCertificatesToSSLContext(ctx, port.secure); } bool Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port) { Security::CertPointer cert; - Ssl::EVP_PKEY_Pointer pkey; + Security::PrivateKeyPointer pkey; if (!generateSslCertificate(cert, pkey, properties)) return false; @@ -965,7 +882,7 @@ Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port) { Security::CertPointer cert; - Ssl::EVP_PKEY_Pointer pkey; + Security::PrivateKeyPointer pkey; if (!readCertAndPrivateKeyFromMemory(cert, pkey, data)) return false; @@ -1003,11 +920,7 @@ return false; ASN1_TIME * time_notBefore = X509_get_notBefore(cert); ASN1_TIME * time_notAfter = X509_get_notAfter(cert); - bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0); - if (!ret) - return false; - - return certificateMatchesProperties(cert, properties); + return (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0); } bool @@ -1024,22 +937,21 @@ } return true; #else - debugs(83, 7, "no support for TLS servername extension (SNI)\n"); + debugs(83, 7, "no support for TLS servername extension (SNI)"); return false; #endif } void -Ssl::addChainToSslContext(Security::ContextPointer &ctx, STACK_OF(X509) *chain) +Ssl::addChainToSslContext(Security::ContextPointer &ctx, Security::CertList &chain) { - if (!chain) + if (chain.empty()) return; - for (int i = 0; i < sk_X509_num(chain); ++i) { - X509 *cert = sk_X509_value(chain, i); - if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert)) { + for (auto cert : chain) { + if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert.get())) { // increase the certificate lock - X509_up_ref(cert); + X509_up_ref(cert.get()); } else { const int ssl_error = ERR_get_error(); debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL context chain: " << Security::ErrorString(ssl_error)); @@ -1134,18 +1046,49 @@ return false; } +/// \return true if the cert issuer exist in the certificates stored in connContext +static bool +issuerExistInCaDb(X509 *cert, const Security::ContextPointer &connContext) +{ + if (!connContext) + return false; + + X509_STORE_CTX *storeCtx = X509_STORE_CTX_new(); + if (!storeCtx) { + debugs(83, DBG_IMPORTANT, "Failed to allocate STORE_CTX object"); + return false; + } + + bool gotIssuer = false; + X509_STORE *store = SSL_CTX_get_cert_store(connContext.get()); + if (X509_STORE_CTX_init(storeCtx, store, nullptr, nullptr)) { + X509 *issuer = nullptr; + gotIssuer = (X509_STORE_CTX_get1_issuer(&issuer, storeCtx, cert) > 0); + if (issuer) + X509_free(issuer); + } else { + const int ssl_error = ERR_get_error(); + debugs(83, DBG_IMPORTANT, "Failed to initialize STORE_CTX object: " << Security::ErrorString(ssl_error)); + } + X509_STORE_CTX_free(storeCtx); + + return gotIssuer; +} + const char * -Ssl::uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates) +Ssl::uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates, const Security::ContextPointer &context) { if (!cert || !serverCertificates.size()) return nullptr; if (!findCertIssuer(serverCertificates, cert)) { //if issuer is missing - if (!findCertIssuerFast(SquidUntrustedCerts, cert)) { - // and issuer not found in local untrusted certificates database - if (const char *issuerUri = hasAuthorityInfoAccessCaIssuers(cert)) { - // There is a URI where we can download a certificate. + if (const char *issuerUri = hasAuthorityInfoAccessCaIssuers(cert)) { + // There is a URI where we can download a certificate. + if (!findCertIssuerFast(SquidUntrustedCerts, cert) && + !issuerExistInCaDb(cert, context)) { + // and issuer not found in local databases containing + // untrusted certificates and trusted CA certificates return issuerUri; } } @@ -1154,13 +1097,13 @@ } void -Ssl::missingChainCertificatesUrls(std::queue &URIs, Security::CertList const &serverCertificates) +Ssl::missingChainCertificatesUrls(std::queue &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context) { if (!serverCertificates.size()) return; for (const auto &i : serverCertificates) { - if (const char *issuerUri = uriOfIssuerIfMissing(i.get(), serverCertificates)) + if (const char *issuerUri = uriOfIssuerIfMissing(i.get(), serverCertificates, context)) URIs.push(SBuf(issuerUri)); } } @@ -1233,7 +1176,7 @@ static int untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data) { - debugs(83, 4, "Try to use pre-downloaded intermediate certificates\n"); + debugs(83, 4, "Try to use pre-downloaded intermediate certificates"); SSL *ssl = static_cast(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); STACK_OF(X509) *sslUntrustedStack = static_cast (SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain)); @@ -1297,7 +1240,7 @@ * Read certificate from file. * See also: static readSslX509Certificate function, gadgets.cc file */ -static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF(X509)* chain) +static X509 * readSslX509CertificatesChain(char const * certFilename, Security::CertList &chain) { if (!certFilename) return NULL; @@ -1308,23 +1251,22 @@ return NULL; X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL); - if (certificate && chain) { + if (certificate) { if (X509_check_issued(certificate, certificate) == X509_V_OK) debugs(83, 5, "Certificate is self-signed, will not be chained"); else { // and add to the chain any other certificate exist in the file - while (X509 *ca = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) { - if (!sk_X509_push(chain, ca)) - debugs(83, DBG_IMPORTANT, "WARNING: unable to add CA certificate to cert chain"); - } + while (X509 *ca = PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr)) + chain.emplace_front(Security::CertPointer(ca)); } } return certificate; } -void Ssl::readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) +void +Ssl::readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, Security::CertList &chain, char const * certFilename, char const * keyFilename) { if (keyFilename == NULL) keyFilename = certFilename; @@ -1334,15 +1276,11 @@ debugs(83, DBG_IMPORTANT, "Using certificate in " << certFilename); - if (!chain) - chain.reset(sk_X509_new_null()); - if (!chain) - debugs(83, DBG_IMPORTANT, "WARNING: unable to allocate memory for cert chain"); // XXX: ssl_ask_password_cb needs SSL_CTX_set_default_passwd_cb_userdata() // so this may not fully work iff Config.Program.ssl_password is set. pem_password_cb *cb = ::Config.Program.ssl_password ? &ssl_ask_password_cb : NULL; - pkey.resetWithoutLocking(readSslPrivateKey(keyFilename, cb)); - cert.resetWithoutLocking(readSslX509CertificatesChain(certFilename, chain.get())); + Ssl::ReadPrivateKeyFromFile(keyFilename, pkey, cb); + cert.resetWithoutLocking(readSslX509CertificatesChain(certFilename, chain)); if (!cert) { debugs(83, DBG_IMPORTANT, "WARNING: missing cert in '" << certFilename << "'"); } else if (!pkey) { @@ -1356,7 +1294,7 @@ cert.reset(); } -bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, Security::CertPointer const &cert, EVP_PKEY_Pointer const & pkey) +bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, Security::PrivateKeyPointer &untrustedPkey, Security::CertPointer const &cert, Security::PrivateKeyPointer const & pkey) { // Generate the self-signed certificate, using a hard-coded subject prefix Ssl::CertificateProperties certProperties; @@ -1379,5 +1317,116 @@ return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties); } +void Ssl::InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key) +{ + bool origSignatureAsKey = false; + if (certProperties.mimicCert) { + if (auto *sig = Ssl::X509_get_signature(certProperties.mimicCert)) { + origSignatureAsKey = true; + key.append((const char *)sig->data, sig->length); + } + } + + if (!origSignatureAsKey || certProperties.setCommonName) { + // Use common name instead + key.append(certProperties.commonName.c_str()); + } + key.append(certProperties.setCommonName ? '1' : '0'); + key.append(certProperties.setValidAfter ? '1' : '0'); + key.append(certProperties.setValidBefore ? '1' : '0'); + key.append(certProperties.signAlgorithm != Ssl:: algSignEnd ? certSignAlgorithm(certProperties.signAlgorithm) : "-"); + key.append(certProperties.signHash ? EVP_MD_name(certProperties.signHash) : "-"); + + if (certProperties.mimicCert) { + Ssl::BIO_Pointer bio(BIO_new_SBuf(&key)); + ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bio.get(), (ASN1_VALUE *)certProperties.mimicCert.get()); + } +} + +static int +bio_sbuf_create(BIO* bio) +{ + BIO_set_init(bio, 0); + BIO_set_data(bio, NULL); + return 1; +} + +static int +bio_sbuf_destroy(BIO* bio) +{ + if (!bio) + return 0; + return 1; +} + +int +bio_sbuf_write(BIO* bio, const char* data, int len) +{ + SBuf *buf = static_cast(BIO_get_data(bio)); + // TODO: Convert exceptions into BIO errors + buf->append(data, len); + return len; +} + +int +bio_sbuf_puts(BIO* bio, const char* data) +{ + // TODO: use bio_sbuf_write() instead + SBuf *buf = static_cast(BIO_get_data(bio)); + size_t oldLen = buf->length(); + buf->append(data); + return buf->length() - oldLen; +} + +long +bio_sbuf_ctrl(BIO* bio, int cmd, long num, void* ptr) { + SBuf *buf = static_cast(BIO_get_data(bio)); + switch (cmd) { + case BIO_CTRL_RESET: + // TODO: Convert exceptions into BIO errors + buf->clear(); + return 1; + case BIO_CTRL_FLUSH: + return 1; + default: + return 0; + } +} + +BIO *Ssl::BIO_new_SBuf(SBuf *buf) +{ +#if HAVE_LIBCRYPTO_BIO_METH_NEW + static BIO_METHOD *BioSBufMethods = nullptr; + if (!BioSBufMethods) { + BioSBufMethods = BIO_meth_new(BIO_TYPE_MEM, "Squid-SBuf"); + BIO_meth_set_write(BioSBufMethods, bio_sbuf_write); + BIO_meth_set_read(BioSBufMethods, nullptr); + BIO_meth_set_puts(BioSBufMethods, bio_sbuf_puts); + BIO_meth_set_gets(BioSBufMethods, nullptr); + BIO_meth_set_ctrl(BioSBufMethods, bio_sbuf_ctrl); + BIO_meth_set_create(BioSBufMethods, bio_sbuf_create); + BIO_meth_set_destroy(BioSBufMethods, bio_sbuf_destroy); + } +#else + static BIO_METHOD *BioSBufMethods = new BIO_METHOD({ + BIO_TYPE_MEM, + "Squid SBuf", + bio_sbuf_write, + nullptr, + bio_sbuf_puts, + nullptr, + bio_sbuf_ctrl, + bio_sbuf_create, + bio_sbuf_destroy, + NULL + }); +#endif + BIO *bio = BIO_new(BioSBufMethods); + Must(bio); + BIO_set_data(bio, buf); + BIO_set_init(bio, 1); + return bio; +} + #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.21/src/ssl/support.h squid-4.0.22/src/ssl/support.h --- squid-4.0.21/src/ssl/support.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/ssl/support.h 2017-12-08 04:12:12.000000000 +1300 @@ -79,6 +79,12 @@ /// initialize a TLS client context with OpenSSL specific settings bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, long flags); +/// set the certificate verify callback for a context +void SetupVerifyCallback(Security::ContextPointer &); + +/// if required, setup callback for generating ephemeral RSA keys +void MaybeSetupRsaCallback(Security::ContextPointer &); + } //namespace Ssl /// \ingroup ServerProtocolSSLAPI @@ -167,19 +173,19 @@ * Searches in serverCertificates list for the cert issuer and if not found * and Authority Info Access of cert provides a URI return it. */ -const char *uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates); +const char *uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates, const Security::ContextPointer &context); /** * Fill URIs queue with the uris of missing certificates from serverCertificate chain * if this information provided by Authority Info Access. */ -void missingChainCertificatesUrls(std::queue &URIs, Security::CertList const &serverCertificates); +void missingChainCertificatesUrls(std::queue &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context); /** \ingroup ServerProtocolSSLAPI * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA */ -bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey); +bool generateUntrustedCert(Security::CertPointer & untrustedCert, Security::PrivateKeyPointer & untrustedPkey, Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey); /// certificates indexed by issuer name typedef std::multimap CertsIndexedList; @@ -208,7 +214,7 @@ \ingroup ServerProtocolSSLAPI * Decide on the kind of certificate and generate a CA- or self-signed one */ -Security::ContextPointer generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port); +Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool trusted); /** \ingroup ServerProtocolSSLAPI @@ -224,19 +230,19 @@ * Read private key and certificate from memory and generate SSL context * using their. */ -Security::ContextPointer generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port); +Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &, bool trusted); /** \ingroup ServerProtocolSSLAPI * Create an SSL context using the provided certificate and key */ -Security::ContextPointer createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port); +Security::ContextPointer createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &); /** \ingroup ServerProtocolSSLAPI * Chain signing certificate and chained certificates to an SSL Context */ -void chainCertificatesToSSLContext(Security::ContextPointer &, AnyP::PortCfg &); +void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &); /** \ingroup ServerProtocolSSLAPI @@ -262,7 +268,7 @@ \ingroup ServerProtocolSSLAPI * Adds the certificates in certList to the certificate chain of the SSL context */ -void addChainToSslContext(Security::ContextPointer &, STACK_OF(X509) *certList); +void addChainToSslContext(Security::ContextPointer &, Security::CertList &); /** \ingroup ServerProtocolSSLAPI @@ -278,7 +284,7 @@ * \param certFilename name of file with certificate and certificates which must be chainned. * \param keyFilename name of file with private key. */ -void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename); +void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, Security::CertList &chain, char const * certFilename, char const * keyFilename); /** \ingroup ServerProtocolSSLAPI @@ -318,6 +324,18 @@ */ bool setClientSNI(SSL *ssl, const char *fqdn); +/** + \ingroup ServerProtocolSSLAPI + * Generates a unique key based on CertificateProperties object and store it to key + */ +void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key); + +/** + \ingroup ServerProtocolSSLAPI + Creates and returns an OpenSSL BIO object for writing to `buf` (or throws). + TODO: Add support for reading from `buf`. + */ +BIO *BIO_new_SBuf(SBuf *buf); } //namespace Ssl #if _SQUID_WINDOWS_ diff -u -r -N squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-4.0.22/src/store/id_rewriters/file/storeid_file_rewrite.8 --- squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.8 2017-07-02 20:57:34.000000000 +1200 +++ squid-4.0.22/src/store/id_rewriters/file/storeid_file_rewrite.8 2017-12-08 06:19:01.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 8" -.TH STOREID_FILE_REWRITE 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -196,7 +196,7 @@ .Ve .SH "QUESTIONS" .IX Header "QUESTIONS" -Questions on the usage of this program can be sent to the \fISquid Users mailing list +Questions on the usage of this program can be sent to the \fISquid Users mailing list .SH "REPORTING BUGS" .IX Header "REPORTING BUGS" Bug reports need to be made in English. @@ -204,12 +204,12 @@ .PP Report bugs or bug fixes using http://bugs.squid\-cache.org/ .PP -Report serious security bugs to \fISquid Bugs +Report serious security bugs to \fISquid Bugs .PP -Report ideas for new improvements to the \fISquid Developers mailing list +Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL \\fIs0\fR\|(7), +squid (8), \s-1GPL\s0 (7), .PP The Squid wiki http://wiki.squid\-cache.org/Features/StoreID .PP diff -u -r -N squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.pl.in squid-4.0.22/src/store/id_rewriters/file/storeid_file_rewrite.pl.in --- squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.pl.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/store/id_rewriters/file/storeid_file_rewrite.pl.in 2017-12-08 04:12:12.000000000 +1300 @@ -69,7 +69,7 @@ =head1 QUESTIONS -Questions on the usage of this program can be sent to the I> +Questions on the usage of this program can be sent to the I> =head1 REPORTING BUGS @@ -78,9 +78,9 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ -Report serious security bugs to I> +Report serious security bugs to I> -Report ideas for new improvements to the I> +Report ideas for new improvements to the I> =head1 SEE ALSO diff -u -r -N squid-4.0.21/src/store.cc squid-4.0.22/src/store.cc --- squid-4.0.21/src/store.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/store.cc 2017-12-08 04:12:12.000000000 +1300 @@ -779,8 +779,7 @@ debugs(20, 3, "storeCreateEntry: '" << url << "'"); e = new StoreEntry(); - e->makeMemObject(); - e->mem_obj->setUris(url, log_url, method); + e->createMemObject(url, log_url, method); if (flags.cachable) { EBIT_CLR(e->flags, RELEASE_REQUEST); @@ -1678,18 +1677,25 @@ return mem_obj->storeId(); } -MemObject * -StoreEntry::makeMemObject() +void +StoreEntry::createMemObject() { - if (!mem_obj) - mem_obj = new MemObject(); - return mem_obj; + assert(!mem_obj); + mem_obj = new MemObject(); } void StoreEntry::createMemObject(const char *aUrl, const char *aLogUrl, const HttpRequestMethod &aMethod) { - makeMemObject(); + assert(!mem_obj); + ensureMemObject(aUrl, aLogUrl, aMethod); +} + +void +StoreEntry::ensureMemObject(const char *aUrl, const char *aLogUrl, const HttpRequestMethod &aMethod) +{ + if (!mem_obj) + mem_obj = new MemObject(); mem_obj->setUris(aUrl, aLogUrl, aMethod); } diff -u -r -N squid-4.0.21/src/store_digest.cc squid-4.0.22/src/store_digest.cc --- squid-4.0.21/src/store_digest.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/store_digest.cc 2017-12-08 04:12:12.000000000 +1300 @@ -401,10 +401,6 @@ static void storeDigestRewriteStart(void *datanotused) { - RequestFlags flags; - char *url; - StoreEntry *e; - assert(store_digest); /* prevent overlapping if rewrite schedule is too tight */ @@ -414,19 +410,22 @@ } debugs(71, 2, "storeDigestRewrite: start rewrite #" << sd_state.rewrite_count + 1); - /* make new store entry */ - url = internalLocalUri("/squid-internal-periodic/", SBuf(StoreDigestFileName)); + + const char *url = internalLocalUri("/squid-internal-periodic/", SBuf(StoreDigestFileName)); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest); + auto req = HttpRequest::FromUrl(url, mx); + + RequestFlags flags; flags.cachable = true; - e = storeCreateEntry(url, url, flags, Http::METHOD_GET); + + StoreEntry *e = storeCreateEntry(url, url, flags, Http::METHOD_GET); assert(e); sd_state.rewrite_lock = e; debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text()); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest); - HttpRequest *req = HttpRequest::FromUrl(url, mx); e->mem_obj->request = req; HTTPMSGLOCK(e->mem_obj->request); - /* wait for rebuild (if any) to finish */ + /* wait for rebuild (if any) to finish */ if (sd_state.rebuild_lock) { debugs(71, 2, "storeDigestRewriteStart: waiting for rebuild to finish."); return; diff -u -r -N squid-4.0.21/src/Store.h squid-4.0.22/src/Store.h --- squid-4.0.21/src/Store.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/Store.h 2017-12-08 04:12:12.000000000 +1300 @@ -115,12 +115,16 @@ int validToSend() const; bool memoryCachable(); ///< checkCachable() and can be cached in memory - /// if needed, initialize mem_obj member w/o URI-related information - MemObject *makeMemObject(); + /// initialize mem_obj; assert if mem_obj already exists + /// avoid this method in favor of createMemObject(trio)! + void createMemObject(); - /// initialize mem_obj member (if needed) and supply URI-related info + /// initialize mem_obj with URIs/method; assert if mem_obj already exists void createMemObject(const char *storeId, const char *logUri, const HttpRequestMethod &aMethod); + /// initialize mem_obj (if needed) and set URIs/method (if missing) + void ensureMemObject(const char *storeId, const char *logUri, const HttpRequestMethod &aMethod); + void dump(int debug_lvl) const; void hashDelete(); void hashInsert(const cache_key *); diff -u -r -N squid-4.0.21/src/tests/stub_client_side.cc squid-4.0.22/src/tests/stub_client_side.cc --- squid-4.0.21/src/tests/stub_client_side.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_client_side.cc 2017-12-08 04:12:12.000000000 +1300 @@ -43,7 +43,7 @@ #if USE_OPENSSL void ConnStateData::httpsPeeked(PinnedIdleContext) STUB void ConnStateData::getSslContextStart() STUB -void ConnStateData::getSslContextDone(Security::ContextPointer &, bool) STUB +void ConnStateData::getSslContextDone(Security::ContextPointer &) STUB void ConnStateData::sslCrtdHandleReplyWrapper(void *, const Helper::Reply &) STUB void ConnStateData::sslCrtdHandleReply(const Helper::Reply &) STUB void ConnStateData::switchToHttps(HttpRequest *, Ssl::BumpMode) STUB diff -u -r -N squid-4.0.21/src/tests/stub_debug.cc squid-4.0.22/src/tests/stub_debug.cc --- squid-4.0.21/src/tests/stub_debug.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_debug.cc 2017-12-08 04:12:12.000000000 +1300 @@ -16,7 +16,8 @@ #include "squid.h" #include "Debug.h" -FILE *debug_log = NULL; +#define STUB_API "debug.cc" +#include "tests/STUB.h" char *Debug::debugOptions; char *Debug::cache_log= NULL; @@ -26,6 +27,15 @@ int Debug::log_stderr = 1; bool Debug::log_syslog = false; +void StopUsingDebugLog() STUB +void ResyncDebugLog(FILE *) STUB + +FILE * +DebugStream() +{ + return stderr; +} + Ctx ctx_enter(const char *) { diff -u -r -N squid-4.0.21/src/tests/stub_HttpReply.cc squid-4.0.22/src/tests/stub_HttpReply.cc --- squid-4.0.21/src/tests/stub_HttpReply.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_HttpReply.cc 2017-12-08 04:12:12.000000000 +1300 @@ -13,8 +13,8 @@ #include "tests/STUB.h" HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0), - expires (0), surrogate_control (NULL), content_range (NULL), keep_alive (0), - protoPrefix("HTTP/"), do_clean(false), bodySizeMax(-2) + expires(0), surrogate_control(nullptr), keep_alive(0), + protoPrefix("HTTP/"), do_clean(false), bodySizeMax(-2), content_range(nullptr) STUB_NOP HttpReply::~HttpReply() STUB void HttpReply::setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires_) STUB @@ -30,4 +30,5 @@ bool HttpReply::inheritProperties(const HttpMsg *aMsg) STUB_RETVAL(false) bool HttpReply::updateOnNotModified(HttpReply const*) STUB_RETVAL(false) int64_t HttpReply::bodySize(const HttpRequestMethod&) const STUB_RETVAL(0) + const HttpHdrContRange *HttpReply::contentRange() const STUB_RETVAL(nullptr) diff -u -r -N squid-4.0.21/src/tests/stub_HttpRequest.cc squid-4.0.22/src/tests/stub_HttpRequest.cc --- squid-4.0.21/src/tests/stub_HttpRequest.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_HttpRequest.cc 2017-12-08 04:12:12.000000000 +1300 @@ -47,7 +47,7 @@ void HttpRequest::swapOut(StoreEntry *) STUB void HttpRequest::pack(Packable *) const STUB void HttpRequest::httpRequestPack(void *, Packable *) STUB -HttpRequest * HttpRequest::FromUrl(char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(NULL) +HttpRequest * HttpRequest::FromUrl(const char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(NULL) ConnStateData *HttpRequest::pinnedConnection() STUB_RETVAL(NULL) const SBuf HttpRequest::storeId() STUB_RETVAL(SBuf(".")) void HttpRequest::ignoreRange(const char *) STUB diff -u -r -N squid-4.0.21/src/tests/stub_libsecurity.cc squid-4.0.22/src/tests/stub_libsecurity.cc --- squid-4.0.21/src/tests/stub_libsecurity.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_libsecurity.cc 2017-12-08 04:12:12.000000000 +1300 @@ -87,11 +87,17 @@ #include "security/ServerOptions.h" //Security::ServerOptions::ServerOptions(const Security::ServerOptions &) STUB +Security::ServerOptions &Security::ServerOptions::operator=(Security::ServerOptions const&) STUB_RETVAL(*this); void Security::ServerOptions::parse(const char *) STUB void Security::ServerOptions::dumpCfg(Packable *, const char *) const STUB Security::ContextPointer Security::ServerOptions::createBlankContext() const STUB_RETVAL(Security::ContextPointer()) bool Security::ServerOptions::createStaticServerContext(AnyP::PortCfg &) STUB_RETVAL(false) +void Security::ServerOptions::createSigningContexts(AnyP::PortCfg &) STUB +bool Security::ServerOptions::updateContextConfig(Security::ContextPointer &) STUB_RETVAL(false) void Security::ServerOptions::updateContextEecdh(Security::ContextPointer &) STUB +void Security::ServerOptions::updateContextClientCa(Security::ContextPointer &) STUB +void Security::ServerOptions::syncCaFiles() STUB +void Security::ServerOptions::updateContextSessionId(Security::ContextPointer &) STUB #include "security/Session.h" namespace Security { diff -u -r -N squid-4.0.21/src/tests/stub_libsslsquid.cc squid-4.0.22/src/tests/stub_libsslsquid.cc --- squid-4.0.21/src/tests/stub_libsslsquid.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_libsslsquid.cc 2017-12-08 04:12:12.000000000 +1300 @@ -52,6 +52,8 @@ { bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &) STUB_RETVAL(false) bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, const char *) STUB_RETVAL(false) +void SetupVerifyCallback(Security::ContextPointer &) STUB +void MaybeSetupRsaCallback(Security::ContextPointer &) STUB } // namespace Ssl const char *sslGetUserEmail(SSL *ssl) STUB_RETVAL(NULL) const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name) STUB_RETVAL(NULL) @@ -64,12 +66,12 @@ //GETX509ATTRIBUTE GetX509CAAttribute; //GETX509ATTRIBUTE GetX509Fingerprint; std::vector BumpModeStr = {""}; -bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey) STUB_RETVAL(false) -Security::ContextPointer generateSslContext(CertificateProperties const &, AnyP::PortCfg &) STUB_RETVAL(Security::ContextPointer()) +bool generateUntrustedCert(Security::CertPointer &, Security::PrivateKeyPointer &, Security::CertPointer const &, Security::PrivateKeyPointer const &) STUB_RETVAL(false) +Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool) STUB_RETVAL(Security::ContextPointer()) bool verifySslCertificate(Security::ContextPointer &, CertificateProperties const &) STUB_RETVAL(false) -Security::ContextPointer generateSslContextUsingPkeyAndCertFromMemory(const char *, AnyP::PortCfg &) STUB_RETVAL(Security::ContextPointer()) +Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char *, Security::ServerOptions &, bool) STUB_RETVAL(Security::ContextPointer()) void addChainToSslContext(Security::ContextPointer &, STACK_OF(X509) *) STUB -void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) STUB +void readCertChainAndPrivateKeyFromFiles(Security::CertPointer &, Security::PrivateKeyPointer &, Security::CertList &, char const *, char const *) STUB int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data)) STUB_RETVAL(0) bool checkX509ServerValidity(X509 *cert, const char *server) STUB_RETVAL(false) int asn1timeToString(ASN1_TIME *tm, char *buf, int len) STUB_RETVAL(0) diff -u -r -N squid-4.0.21/src/tests/stub_SBuf.cc squid-4.0.22/src/tests/stub_SBuf.cc --- squid-4.0.21/src/tests/stub_SBuf.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_SBuf.cc 2017-12-08 04:12:12.000000000 +1300 @@ -49,8 +49,8 @@ const SBufStats& SBuf::GetStats() STUB_RETVAL(SBuf::stats) SBuf::size_type SBuf::copy(char *dest, size_type n) const STUB_RETVAL(0) const char* SBuf::rawContent() const STUB_RETVAL(NULL) -char *SBuf::rawSpace(size_type minSize) STUB_RETVAL(NULL) -void SBuf::forceSize(size_type newSize) STUB +char *SBuf::rawAppendStart(size_type) STUB_RETVAL(NULL) +void SBuf::rawAppendFinish(const char *, size_type) STUB const char* SBuf::c_str() STUB_RETVAL("") void SBuf::reserveCapacity(size_type minCapacity) STUB SBuf::size_type SBuf::reserve(const SBufReservationRequirements &) STUB_RETVAL(0) diff -u -r -N squid-4.0.21/src/tests/stub_store.cc squid-4.0.22/src/tests/stub_store.cc --- squid-4.0.21/src/tests/stub_store.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/stub_store.cc 2017-12-08 04:12:12.000000000 +1300 @@ -54,8 +54,9 @@ int StoreEntry::locked() const STUB_RETVAL(0) int StoreEntry::validToSend() const STUB_RETVAL(0) bool StoreEntry::memoryCachable() STUB_RETVAL(false) -MemObject *StoreEntry::makeMemObject() STUB_RETVAL(NULL) +void StoreEntry::createMemObject() STUB void StoreEntry::createMemObject(const char *, const char *, const HttpRequestMethod &aMethod) STUB +void StoreEntry::ensureMemObject(const char *, const char *, const HttpRequestMethod &) STUB void StoreEntry::dump(int debug_lvl) const STUB void StoreEntry::hashDelete() STUB void StoreEntry::hashInsert(const cache_key *) STUB diff -u -r -N squid-4.0.21/src/tests/testSBuf.cc squid-4.0.22/src/tests/testSBuf.cc --- squid-4.0.21/src/tests/testSBuf.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/testSBuf.cc 2017-12-08 04:12:12.000000000 +1300 @@ -418,10 +418,9 @@ { SBuf s1(literal); SBuf s2(fox1); - SBuf::size_type sz=s2.length(); - char *rb=s2.rawSpace(strlen(fox2)+1); + char *rb=s2.rawAppendStart(strlen(fox2)+1); strcpy(rb,fox2); - s2.forceSize(sz+strlen(fox2)); + s2.rawAppendFinish(rb, strlen(fox2)); CPPUNIT_ASSERT_EQUAL(s1,s2); } diff -u -r -N squid-4.0.21/src/tests/testStoreController.cc squid-4.0.22/src/tests/testStoreController.cc --- squid-4.0.21/src/tests/testStoreController.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/testStoreController.cc 2017-12-08 04:12:12.000000000 +1300 @@ -31,8 +31,7 @@ { Store::Init(); StoreEntry *logEntry = new StoreEntry; - logEntry->makeMemObject(); - logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod()); + logEntry->createMemObject("dummy_storeId", NULL, HttpRequestMethod()); logEntry->store_status = STORE_PENDING; TestSwapDirPointer aStore (new TestSwapDir); TestSwapDirPointer aStore2 (new TestSwapDir); @@ -73,8 +72,7 @@ { commonInit(); StoreEntry *logEntry = new StoreEntry; - logEntry->makeMemObject(); - logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod()); + logEntry->createMemObject("dummy_storeId", NULL, HttpRequestMethod()); logEntry->store_status = STORE_PENDING; Store::Init(); TestSwapDirPointer aStore (new TestSwapDir); diff -u -r -N squid-4.0.21/src/tests/testStoreHashIndex.cc squid-4.0.22/src/tests/testStoreHashIndex.cc --- squid-4.0.21/src/tests/testStoreHashIndex.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tests/testStoreHashIndex.cc 2017-12-08 04:12:12.000000000 +1300 @@ -30,8 +30,7 @@ testStoreHashIndex::testStats() { StoreEntry *logEntry = new StoreEntry; - logEntry->makeMemObject(); - logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod()); + logEntry->createMemObject("dummy_storeId", NULL, HttpRequestMethod()); logEntry->store_status = STORE_PENDING; Store::Init(); TestSwapDirPointer aStore (new TestSwapDir); @@ -51,8 +50,7 @@ testStoreHashIndex::testMaxSize() { StoreEntry *logEntry = new StoreEntry; - logEntry->makeMemObject(); - logEntry->mem_obj->setUris("dummy_storeId", NULL, HttpRequestMethod()); + logEntry->createMemObject("dummy_storeId", NULL, HttpRequestMethod()); logEntry->store_status = STORE_PENDING; Store::Init(); TestSwapDirPointer aStore (new TestSwapDir); diff -u -r -N squid-4.0.21/src/tools.cc squid-4.0.22/src/tools.cc --- squid-4.0.21/src/tools.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tools.cc 2017-12-08 04:12:12.000000000 +1300 @@ -56,7 +56,7 @@ You've encountered a fatal error in the Squid Cache version %s.\n\ If a core file was created (possibly in the swap directory),\n\ please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\ -and report the trace back to squid-bugs@squid-cache.org.\n\ +and report the trace back to squid-bugs@lists.squid-cache.org.\n\ \n\ Thanks!\n" diff -u -r -N squid-4.0.21/src/tunnel.cc squid-4.0.22/src/tunnel.cc --- squid-4.0.21/src/tunnel.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/tunnel.cc 2017-12-08 04:12:12.000000000 +1300 @@ -517,17 +517,11 @@ // CONNECT response was successfully parsed *status_ptr = rep.sline.status(); - // we need to relay the 401/407 responses when login=PASS(THRU) - const CachePeer *peer = server.conn->getPeer(); - const char *pwd = (peer ? peer->login : nullptr); - const bool relay = pwd && (strcmp(pwd, "PASS") == 0 || strcmp(pwd, "PASSTHRU") == 0) && - (*status_ptr == Http::scProxyAuthenticationRequired || - *status_ptr == Http::scUnauthorized); - // bail if we did not get an HTTP 200 (Connection Established) response if (rep.sline.status() != Http::scOkay) { // if we ever decide to reuse the peer connection, we must extract the error response first - informUserOfPeerError("unsupported CONNECT response status code", (relay ? rep.hdr_sz : 0)); + *status_ptr = rep.sline.status(); // we are relaying peer response + informUserOfPeerError("unsupported CONNECT response status code", rep.hdr_sz); return; } diff -u -r -N squid-4.0.21/src/url.cc squid-4.0.22/src/url.cc --- squid-4.0.21/src/url.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/url.cc 2017-12-08 04:12:12.000000000 +1300 @@ -188,7 +188,7 @@ * being "end of host with implied path of /". */ bool -URL::parse(const HttpRequestMethod& method, char *url) +URL::parse(const HttpRequestMethod& method, const char *url) { LOCAL_ARRAY(char, proto, MAX_URL); LOCAL_ARRAY(char, login, MAX_URL); @@ -205,8 +205,6 @@ proto[0] = foundHost[0] = urlpath[0] = login[0] = '\0'; if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) { - /* terminate so it doesn't overflow other buffers */ - *(url + (MAX_URL >> 1)) = '\0'; debugs(23, DBG_IMPORTANT, MYNAME << "URL too large (" << l << " bytes)"); return false; } diff -u -r -N squid-4.0.21/src/URL.h squid-4.0.22/src/URL.h --- squid-4.0.21/src/URL.h 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/URL.h 2017-12-08 04:12:12.000000000 +1300 @@ -53,7 +53,7 @@ } void touch(); ///< clear the cached URI display forms - bool parse(const HttpRequestMethod &, char *url); + bool parse(const HttpRequestMethod &, const char *url); AnyP::UriScheme const & getScheme() const {return scheme_;} @@ -170,7 +170,6 @@ class HttpRequestMethod; void urlInitialize(void); -bool urlParse(const HttpRequestMethod&, char *, HttpRequest &request); char *urlCanonicalClean(const HttpRequest *); const char *urlCanonicalFakeHttps(const HttpRequest * request); bool urlIsRelative(const char *); diff -u -r -N squid-4.0.21/src/urn.cc squid-4.0.22/src/urn.cc --- squid-4.0.21/src/urn.cc 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/src/urn.cc 2017-12-08 04:12:12.000000000 +1300 @@ -145,23 +145,23 @@ } SBuf uri = r->url.path(); + // TODO: use class URL instead of generating a string and re-parsing LOCAL_ARRAY(char, local_urlres, 4096); char *host = getHost(uri); snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:" SQUIDSBUFPH, host, SQUIDSBUFPRINT(uri)); safe_free(host); safe_free(urlres); - urlres = xstrdup(local_urlres); - urlres_r = HttpRequest::FromUrl(urlres, r->masterXaction); + urlres_r = HttpRequest::FromUrl(local_urlres, r->masterXaction); - if (urlres_r == NULL) { - debugs(52, 3, "urnStart: Bad uri-res URL " << urlres); + if (!urlres_r) { + debugs(52, 3, "Bad uri-res URL " << local_urlres); ErrorState *err = new ErrorState(ERR_URN_RESOLVE, Http::scNotFound, r); - err->url = urlres; - urlres = NULL; + err->url = xstrdup(local_urlres); errorAppendEntry(entry, err); return; } + urlres = xstrdup(local_urlres); urlres_r->header.putStr(Http::HdrType::ACCEPT, "text/plain"); } @@ -395,7 +395,6 @@ { char *buf = xstrdup(inbuf); char *token; - char *url; char *host; url_entry *list; url_entry *old; @@ -415,8 +414,7 @@ safe_free(old); } - url = xstrdup(token); - host = urlHostname(url); + host = urlHostname(token); if (NULL == host) continue; @@ -432,11 +430,11 @@ list[i].rtt = 0; #endif - list[i].url = url; + list[i].url = xstrdup(token); list[i].host = xstrdup(host); // TODO: Use storeHas() or lock/unlock entry to avoid creating unlocked // ones. - list[i].flags.cached = storeGetPublic(url, m) ? 1 : 0; + list[i].flags.cached = storeGetPublic(list[i].url, m) ? 1 : 0; ++i; } diff -u -r -N squid-4.0.21/test-suite/squidconf/external_acl_type squid-4.0.22/test-suite/squidconf/external_acl_type --- squid-4.0.21/test-suite/squidconf/external_acl_type 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.22/test-suite/squidconf/external_acl_type 2017-12-08 04:12:12.000000000 +1300 @@ -0,0 +1,46 @@ +## Copyright (C) 1996-2017 The Squid Software Foundation and contributors +## +## Squid software is distributed under GPLv2+ license and includes +## contributions from numerous individuals and organizations. +## Please see the COPYING and CONTRIBUTORS files for details. +## + +# Check Backward Compatibility with Squid-3 formats +external_acl_type foo \ + %LOGIN \ + %un \ + %EXT_USER \ + %EXT_LOG \ + %EXT_TAG \ + %IDENT \ + %SRC \ + %SRCPORT \ + %URI \ + %DST \ + %PROTO \ + %PORT \ + %PATH \ + %METHOD \ + %MYADDR \ + %MYPORT \ + %PATH \ + %>{Header} \ + %>{Hdr:member} \ + %>{Hdr:;member} \ + %>{Hdr:Xmember} \ + %<{Header} \ + %<{Hdr:member} \ + %<{Hdr:;member} \ + %<{Hdr:Xmember} \ + %ACL \ + %DATA \ + %% /bin/true + +# TODO: enable when these are no longer requiring OpenSSL +# %USER_CERT +# %USER_CERTCHAIN +# %USER_CERT_xx +# %USER_CA_CERT_xx +# %ssl::>sni +# %ssl:: +.if !'po4a'hide' . .SH REPORTING BUGS See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. @@ -71,11 +71,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/tools/cachemgr.cgi.8.in squid-4.0.22/tools/cachemgr.cgi.8.in --- squid-4.0.21/tools/cachemgr.cgi.8.in 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/tools/cachemgr.cgi.8.in 2017-12-08 04:12:12.000000000 +1300 @@ -63,7 +63,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. @@ -71,11 +71,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/tools/helper-mux/helper-mux.8 squid-4.0.22/tools/helper-mux/helper-mux.8 --- squid-4.0.21/tools/helper-mux/helper-mux.8 2017-07-02 20:57:36.000000000 +1200 +++ squid-4.0.22/tools/helper-mux/helper-mux.8 2017-12-08 06:19:04.000000000 +1300 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "HELPER-MUX 8" -.TH HELPER-MUX 8 "2017-07-02" "perl v5.24.1" "User Contributed Perl Documentation" +.TH HELPER-MUX 8 "2017-12-07" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-4.0.21/tools/purge/purge.1 squid-4.0.22/tools/purge/purge.1 --- squid-4.0.21/tools/purge/purge.1 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/tools/purge/purge.1 2017-12-08 04:12:12.000000000 +1300 @@ -269,7 +269,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. @@ -277,11 +277,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/tools/squidclient/squidclient.1 squid-4.0.22/tools/squidclient/squidclient.1 --- squid-4.0.21/tools/squidclient/squidclient.1 2017-07-02 20:41:18.000000000 +1200 +++ squid-4.0.22/tools/squidclient/squidclient.1 2017-12-08 04:12:12.000000000 +1300 @@ -245,7 +245,7 @@ .SH QUESTIONS Questions on the usage of this program can be sent to the .I Squid Users mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH REPORTING BUGS See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report. @@ -253,11 +253,11 @@ Report bugs or bug fixes using http://bugs.squid-cache.org/ .PP Report serious security bugs to -.I Squid Bugs +.I Squid Bugs .PP Report ideas for new improvements to the .I Squid Developers mailing list -.if !'po4a'hide' +.if !'po4a'hide' . .SH SEE ALSO .if !'po4a'hide' .BR squid "(8), " diff -u -r -N squid-4.0.21/tools/squidclient/stub_debug.cc squid-4.0.22/tools/squidclient/stub_debug.cc --- squid-4.0.21/tools/squidclient/stub_debug.cc 2017-07-02 20:57:36.000000000 +1200 +++ squid-4.0.22/tools/squidclient/stub_debug.cc 2017-12-08 06:19:04.000000000 +1300 @@ -16,7 +16,8 @@ #include "squid.h" #include "Debug.h" -FILE *debug_log = NULL; +#define STUB_API "debug.cc" +#include "tests/STUB.h" char *Debug::debugOptions; char *Debug::cache_log= NULL; @@ -26,6 +27,15 @@ int Debug::log_stderr = 1; bool Debug::log_syslog = false; +void StopUsingDebugLog() STUB +void ResyncDebugLog(FILE *) STUB + +FILE * +DebugStream() +{ + return stderr; +} + Ctx ctx_enter(const char *) { diff -u -r -N squid-4.0.21/tools/stub_debug.cc squid-4.0.22/tools/stub_debug.cc --- squid-4.0.21/tools/stub_debug.cc 2017-07-02 20:57:36.000000000 +1200 +++ squid-4.0.22/tools/stub_debug.cc 2017-12-08 06:19:04.000000000 +1300 @@ -16,7 +16,8 @@ #include "squid.h" #include "Debug.h" -FILE *debug_log = NULL; +#define STUB_API "debug.cc" +#include "tests/STUB.h" char *Debug::debugOptions; char *Debug::cache_log= NULL; @@ -26,6 +27,15 @@ int Debug::log_stderr = 1; bool Debug::log_syslog = false; +void StopUsingDebugLog() STUB +void ResyncDebugLog(FILE *) STUB + +FILE * +DebugStream() +{ + return stderr; +} + Ctx ctx_enter(const char *) {