diff --git a/contrib/apr-util/CHANGES b/contrib/apr-util/CHANGES index a0dc3789a89d..1b2333bed223 100644 --- a/contrib/apr-util/CHANGES +++ b/contrib/apr-util/CHANGES @@ -1,141 +1,62 @@ -*- coding: utf-8 -*- -Changes with APR-util 1.5.4 +Changes with APR-util 1.6.1 - *) MySQL driver: Fix incorrect handling of bad parameter in the - driver support for apr_dbd_transaction_end(). PR 56330. - [Weiqiang Li ] + *) Win32: Add function exports from new apr_crypto API's missing in 1.6.0. - *) apr_crypto_get_driver(): Fix invalid storage reference on error path. - [Philip Martin ] + *) Win32: Introduce XML_PARSER build-time variable to select the expat + library name to be linked to libaprutil-1.dll. See Makefile.win - *) Fix compile failure for Android. PR 56627. [Fredrik Fornwall - , Jeff Trawick] + *) Win32: Removed lingering xml/xml.dsp project forked from the expat + Project in the 1.9x era. Use expat's maintained build schema instead, + prior to building apr-util. - *) Fix to let ODBC driver build with MSVC6, which does not have intptr_t - [Tom Donovan] + *) apr_crypto: Fix compatibility with LibreSSL. PR 61596. + [Bernard Spil , Yann Ylavic] - *) Windows cmake build: Fix incompatiblities with Visual Studio - generators with all cmake versions, and the NMake Makefile generator - with cmake 2.8.12 and later. PR 56616 and other bugs. [Jeff Trawick, - Bert Huijben] + *) sdbm: better database/page validation to fail cleanly when corrupted. + [Yann Ylavic] - *) Fix detection of Berkeley DB 6.0. PR 55277. - [Lars Wendler ] +Changes with APR-util 1.6.0 - *) Improve platform detection for bundled expat by updating - config.guess and config.sub. [Rainer Jung] + *) The expat dependency of apr-util is no longer built with apr-util. + Install expat (including development headers and libraries) first + before building apr-util. [https://libexpat.github.io/] -Changes with APR-util 1.5.3 + *) Mark apr_dbd_freetds as unsupported, and remove it from all builds + [Nick Kew] - *) Cygwin: Use correct file extension when loading APR DSOs. PR 55587. - [Carlo Bramini ] + *) Update MySQL build to stop using libmysqlclient_r. + [Petr Sumbera ] - *) Add experimental cmake-based build system for Windows. Refer to - README.cmake for more information. [Jeff Trawick, Tom Donovan] + *) apr_buckets: Add apr_bucket_file_set_buf_size() which allows to configure + the size of the buffer used to read files. [Yann Ylavic] - *) Fix warnings in odbc driver on 64bit systems. - PR 55197 [Tom Donovan] + *) apr_crypto: avoid excessive iteration in bcrypt hash. + [Hanno Böck ] - *) Add support to apr_memcache for unix domain sockets. PR 54573 [Remi - Gacogne ] + *) apr_siphash: Implement keyed hash function SipHash. [Yann Ylavic] - *) Add support for Berkeley DB 6.0. [Rainer Jung] + *) apr_crypto: Add apr_crypto_key() function which supports keys + generated from a passphrase or a raw secret provided by the caller. + Deprecate apr_crypto_passphrase(). [Graham Leggett] - *) Improve platform detection for bundled expat by updating - config.guess and config.sub. [Rainer Jung] + *) apr_crypto_nss: Ensure the SECItem returned by PK11_ParamFromIV + is properly freed. [Graham Leggett] -Changes with APR-util 1.5.2 + *) apr_crypto: Don't cache the driver if initialisation fails. This + stops the second and subsequent attempt to use the API from failing + claiming the library is not initialised. [Graham Leggett] - *) Windows: Add command line makefiles. [Gregg Smith] + *) apr_crypto: Add a native CommonCrypto implementation for iOS and OSX + where OpenSSL has been deprecated. [Graham Leggett] - *) apr_uri_parse(): Do not accept invalid characters in the scheme. - Per RFC 3986 3.3, enforce that the first segment of a relative path does - not contain a colon. PR 52479. [Stefan Fritsch] + *) apr_xml_to_text: Add style APR_XML_X2T_PARSED to maintain a + consistent namespace prefix. [Jari Urpalainen + ] - *) Fix memory leak in hook sorting function. PR 51256. - [] +Changes with APR-util 1.5.x and later: - *) Speedup md5 calculation by avoiding some copying on little endian - architectures. PR 49011. [Stefan Fritsch, Stefan Fuhrmann - ] - - *) Use heap memory for crypt in apr_password_validate(), to reduce stack - usage. PR 54572. [Stefan Fritsch] - - *) Fix password validation failure for all crypt and crypt_r based - algorithms. PR 54603. [Harvey Eneman ] - - *) Fix syntax error in crypto/apr_passwd.c on non-glibc systems. PR 54275. - [Stefan Fritsch] - - *) Fix potential data corruption in apr_brigade_write() and friends if - the last bucket of the brigade is a heap bucket that has been split, - and there are still references to the next part of the original bucket - in use. [Stefan Fritsch] - - *) Remove duplicated logic in apr_brigade_puts(). PR 53740. [Christophe - Jaillet ] - - *) apr_crypto: If --with-crypto is passed to configure but no crypto - libraries are enabled, autodetect available libraries. [Jeff Trawick] - - *) memcache: Fix dead server retry logic. [Gavin Shelley ] - -Changes with APR-util 1.5.1 - - *) testmemcache: Fix crash. PR 52705. [Peter Poeml ] - - *) MinGW: Support shared builds of apr-util when apr is shared. - PR 46175. [Carlo Bramini , Jeff Trawick] - - *) Add support for Berkeley DB 5.2 and 5.3. Simplify detection script. - PR 53684. [Rainer Jung] - - *) configure: Allow to specify library specific custom linker flags - via the LDADD_XXX variables. [Rainer Jung] - - *) apr_password_validate(): Fix intermittent errors on systems - such as FreeBSD where the crypt() function is used. - (Broken only in 1.5.0) [Jeff Trawick] - - *) Improve platform detection for bundled expat by updating - config.guess and config.sub. [Rainer Jung] - -Changes with APR-util 1.5.0 - - *) dbd_pgsql_escape: Use PQescapeStringConn. [Nick Kew] - - *) apr_password_validate, apr_bcrypt_encode: Add support for bcrypt encoded - passwords. The bcrypt implementation uses code from crypt_blowfish - written by Solar Designer . apr_bcrypt_encode creates - hashes with "$2y$" prefix, but apr_password_validate also accepts the old - prefix "$2a$". PR 49288. [Stefan Fritsch] - - *) APR dbd: Allow to use apr_dbd_get_row() with a different pool than - apr_dbd_select(). PR 53533. [] - - *) APR dbd FreeTDS support: Fix spurious API errors caused by uninitialized - fields. [TROY.LIU 劉春偉 ] - - *) apr_password_validate: Increase maximum hash string length to allow - more than 9999 rounds with sha512-crypt. PR 53410. [Stefan Fritsch] - - *) Fix segfaults in crypt() and crypt_r() failure modes. - PR 47272. [Arkadiusz Miskiewicz ] - - *) apr_crypto: Ensure that the if/else that governs the static - initialisation of each crypto driver works when the first driver - isn't in use. [Graham Leggett] - - *) apr_crypto: Ensure the *driver variable is initialised when a statically - compiled library is initialised for the first time. [Graham Leggett] - - *) apr_crypto: Ensure the *driver variable is initialised when the library - has already been loaded. Fix ported from apr_dbd. [Graham Leggett] - - *) apr_crypto: Move the static initialisation of DRIVER_LOAD from - apr_crypto_init() to apr_crypto_get_driver(), so that we don't lose - the parameters. [Graham Leggett] + *) http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/CHANGES?view=markup Changes with APR-util 1.4.x and later: diff --git a/contrib/apr-util/CMakeLists.txt b/contrib/apr-util/CMakeLists.txt new file mode 100644 index 000000000000..9ae90b19f97e --- /dev/null +++ b/contrib/apr-util/CMakeLists.txt @@ -0,0 +1,355 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Read README.cmake before using this. + +PROJECT(APR-Util C) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +FIND_PACKAGE(OpenSSL) + +FIND_PACKAGE(expat) + +OPTION(APU_HAVE_CRYPTO "Crypto support" OFF) +OPTION(APU_HAVE_ODBC "Build ODBC DBD driver" ON) +OPTION(APR_HAS_LDAP "LDAP support" ON) +OPTION(INSTALL_PDB "Install .pdb files (if generated)" ON) +OPTION(APR_BUILD_TESTAPR "Build the test suite" OFF) +OPTION(TEST_STATIC_LIBS "Test programs use APR static libraries instead of shared libraries?" OFF) +SET(APR_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE STRING "Directory with APR include files") +SET(APR_LIBRARIES "${CMAKE_INSTALL_PREFIX}/lib/libapr-1.lib" CACHE STRING "APR library to link with") + +IF(NOT EXISTS "${APR_INCLUDE_DIR}/apr.h") + MESSAGE(FATAL_ERROR "APR include directory ${APR_INCLUDE_DIR} is not correct.") +ENDIF() +FOREACH(onelib ${APR_LIBRARIES}) + IF(NOT EXISTS ${onelib}) + MESSAGE(FATAL_ERROR "APR library ${onelib} was not found.") + ENDIF() +ENDFOREACH() + +IF(APU_HAVE_CRYPTO) +IF(NOT OPENSSL_FOUND) + MESSAGE(FATAL_ERROR "OpenSSL is the only supported crypto implementation, and it wasn't found!") +ENDIF() +ENDIF() + +# create 1-or-0 representation of feature tests for apu.h + +SET(apu_have_crypto_10 0) +SET(apu_have_apr_iconv_10 0) # not yet implemented +SET(apr_has_ldap_10 0) + +IF(APU_HAVE_CRYPTO) + SET(apu_have_crypto_10 1) +ENDIF() + +IF(APR_HAS_LDAP) + SET(apr_has_ldap_10 1) +ENDIF() + +IF(NOT EXPAT_FOUND) + MESSAGE(FATAL_ERROR "Expat is required, and it wasn't found!") +ENDIF() + +SET(XMLLIB_INCLUDE_DIR ${EXPAT_INCLUDE_DIRS}) +SET(XMLLIB_LIBRARIES ${EXPAT_LIBRARIES}) + +SET(LDAP_LIBRARIES) +IF(APR_HAS_LDAP) + SET(LDAP_LIBRARIES wldap32) +ENDIF() + +CONFIGURE_FILE(include/apu.hwc + ${PROJECT_BINARY_DIR}/apu.h) +CONFIGURE_FILE(include/apr_ldap.hwc + ${PROJECT_BINARY_DIR}/apr_ldap.h) +# "COPYONLY" just because anything else isn't implemented ;) +CONFIGURE_FILE(include/private/apu_config.hw + ${PROJECT_BINARY_DIR}/apu_config.h + COPYONLY) +CONFIGURE_FILE(include/private/apu_select_dbm.hw + ${PROJECT_BINARY_DIR}/apu_select_dbm.h + COPYONLY) +CONFIGURE_FILE(include/apu_want.hw + ${PROJECT_BINARY_DIR}/apu_want.h + COPYONLY) + +# Generated .h files are stored in PROJECT_BINARY_DIR, not the +# source tree. +# +# BROKEN: not searching PROJECT_BINARY_DIR first, so you have to +# manually delete apu.h in PROJECT_SOURCE_DIR/include if +# you've generated apu.h before using a different build + +SET(APR_INCLUDE_DIRECTORIES + ${PROJECT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include/private + ${APR_INCLUDE_DIR} +) + +INCLUDE_DIRECTORIES(${APR_INCLUDE_DIRECTORIES} ${XMLLIB_INCLUDE_DIR}) + +SET(APR_PUBLIC_HEADERS_STATIC + include/apr_anylock.h + include/apr_base64.h + include/apr_buckets.h + include/apr_crypto.h + include/apr_date.h + include/apr_dbd.h + include/apr_dbm.h + include/apr_hooks.h + include/apr_ldap_init.h + include/apr_ldap_option.h + include/apr_ldap_rebind.h + include/apr_ldap_url.h + include/apr_md4.h + include/apr_md5.h + include/apr_memcache.h + include/apr_optional.h + include/apr_optional_hooks.h + include/apr_queue.h + include/apr_redis.h + include/apr_reslist.h + include/apr_rmm.h + include/apr_sdbm.h + include/apr_sha1.h + include/apr_siphash.h + include/apr_strmatch.h + include/apr_thread_pool.h + include/apr_uri.h + include/apr_uuid.h + include/apr_xlate.h + include/apr_xml.h + include/apu_errno.h + include/apu_version.h +) + +# apu_config.h and apu_select_dbm.h are private +SET(APR_PUBLIC_HEADERS_GENERATED + ${PROJECT_BINARY_DIR}/apu.h + ${PROJECT_BINARY_DIR}/apr_ldap.h + ${PROJECT_BINARY_DIR}/apu_want.h +) + +SET(APR_SOURCES + buckets/apr_brigade.c + buckets/apr_buckets.c + buckets/apr_buckets_alloc.c + buckets/apr_buckets_eos.c + buckets/apr_buckets_file.c + buckets/apr_buckets_flush.c + buckets/apr_buckets_heap.c + buckets/apr_buckets_mmap.c + buckets/apr_buckets_pipe.c + buckets/apr_buckets_pool.c + buckets/apr_buckets_refcount.c + buckets/apr_buckets_simple.c + buckets/apr_buckets_socket.c + crypto/apr_crypto.c + crypto/apr_md4.c + crypto/apr_md5.c + crypto/apr_passwd.c + crypto/apr_sha1.c + crypto/apr_siphash.c + crypto/crypt_blowfish.c + crypto/getuuid.c + crypto/uuid.c + dbd/apr_dbd.c + dbm/apr_dbm.c + dbm/apr_dbm_sdbm.c + dbm/sdbm/sdbm.c + dbm/sdbm/sdbm_hash.c + dbm/sdbm/sdbm_lock.c + dbm/sdbm/sdbm_pair.c + encoding/apr_base64.c + hooks/apr_hooks.c + memcache/apr_memcache.c + misc/apr_date.c + misc/apr_queue.c + misc/apr_reslist.c + misc/apr_rmm.c + misc/apr_thread_pool.c + misc/apu_dso.c + misc/apu_version.c + redis/apr_redis.c + strmatch/apr_strmatch.c + uri/apr_uri.c + xlate/xlate.c + xml/apr_xml.c +) + +IF(APR_HAS_LDAP) + SET(APR_SOURCES ${APR_SOURCES} ldap/apr_ldap_stub.c ldap/apr_ldap_url.c) +ENDIF() + +SET(APR_TEST_SOURCES + test/abts.c + test/testbuckets.c + test/testcrypto.c + test/testdate.c + test/testdbd.c + test/testdbm.c + test/testldap.c + test/testmd4.c + test/testmd5.c + test/testmemcache.c + test/testpass.c + test/testqueue.c + test/testredis.c + test/testreslist.c + test/testrmm.c + test/testsiphash.c + test/teststrmatch.c + test/testuri.c + test/testutil.c + test/testuuid.c + test/testxlate.c + test/testxml.c +) + +SET(install_targets) +SET(install_bin_pdb) +SET(dbd_drivers) + +# Note: The WINNT definition on some targets is used only by libaprutil.rc. + +# libaprutil-1 is shared, aprutil-1 is static +ADD_LIBRARY(libaprutil-1 SHARED ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED} libaprutil.rc) +SET(install_targets ${install_targets} libaprutil-1) +SET(install_bin_pdb ${install_bin_pdb} ${PROJECT_BINARY_DIR}/libaprutil-1.pdb) +TARGET_LINK_LIBRARIES(libaprutil-1 ${APR_LIBRARIES} ${XMLLIB_LIBRARIES}) +SET_TARGET_PROPERTIES(libaprutil-1 PROPERTIES COMPILE_DEFINITIONS "APU_DECLARE_EXPORT;APR_DECLARE_EXPORT;XML_STATIC;WINNT") + +ADD_LIBRARY(aprutil-1 STATIC ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED}) +SET(install_targets ${install_targets} aprutil-1) +TARGET_LINK_LIBRARIES(aprutil-1 ${APR_LIBRARIES} ${XMLLIB_LIBRARIES}) +SET_TARGET_PROPERTIES(aprutil-1 PROPERTIES COMPILE_DEFINITIONS "APU_DECLARE_STATIC;APR_DECLARE_STATIC;APU_DSO_MODULE_BUILD;XML_STATIC") + +IF(APU_HAVE_CRYPTO) + IF(NOT OPENSSL_FOUND) + MESSAGE(FATAL_ERROR "Only OpenSSL-based crypto is currently implemented in the cmake build") + ENDIF() + ADD_LIBRARY(apr_crypto_openssl-1 SHARED crypto/apr_crypto_openssl.c libaprutil.rc) + SET(install_targets ${install_targets} apr_crypto_openssl-1) + SET(install_bin_pdb ${install_bin_pdb} ${PROJECT_BINARY_DIR}/apr_crypto_openssl-1.pdb) + SET_TARGET_PROPERTIES(apr_crypto_openssl-1 PROPERTIES INCLUDE_DIRECTORIES "${APR_INCLUDE_DIRECTORIES};${OPENSSL_INCLUDE_DIR}") + SET_TARGET_PROPERTIES(apr_crypto_openssl-1 PROPERTIES COMPILE_DEFINITIONS "WINNT") + SET_TARGET_PROPERTIES(apr_crypto_openssl-1 PROPERTIES COMPILE_FLAGS "-DAPR_DECLARE_EXPORT=1 -DAPU_DECLARE_EXPORT=1 -DDLL_NAME=apr_crypto_openssl") + TARGET_LINK_LIBRARIES(apr_crypto_openssl-1 libaprutil-1 ${APR_LIBRARIES} ${OPENSSL_LIBRARIES}) +ENDIF() + +IF(APU_HAVE_ODBC) + ADD_LIBRARY(apr_dbd_odbc-1 SHARED dbd/apr_dbd_odbc.c libaprutil.rc) + SET(install_targets ${install_targets} apr_dbd_odbc-1) + SET(install_bin_pdb ${install_bin_pdb} ${PROJECT_BINARY_DIR}/apr_dbd_odbc-1.pdb) + SET(dbd_drivers ${dbd_drivers} odbc) + TARGET_LINK_LIBRARIES(apr_dbd_odbc-1 libaprutil-1 ${APR_LIBRARIES} odbc32 odbccp32) + SET_PROPERTY(TARGET apr_dbd_odbc-1 APPEND PROPERTY LINK_FLAGS /export:apr_dbd_odbc_driver) + SET_TARGET_PROPERTIES(apr_dbd_odbc-1 PROPERTIES COMPILE_DEFINITIONS "APU_HAVE_ODBC;HAVE_SQL_H;APU_DECLARE_EXPORT;APR_DECLARE_EXPORT;APU_DSO_MODULE_BUILD;WINNT") + SET_TARGET_PROPERTIES(apr_dbd_odbc-1 PROPERTIES COMPILE_FLAGS "-DAPR_DECLARE_EXPORT=1 -DAPU_DECLARE_EXPORT=1 -DDLL_NAME=apr_dbd_odbc") +ENDIF() + +IF(APR_HAS_LDAP) + ADD_LIBRARY(apr_ldap-1 SHARED ldap/apr_ldap_init.c ldap/apr_ldap_option.c + ldap/apr_ldap_rebind.c libaprutil.rc) + SET(install_targets ${install_targets} apr_ldap-1) + SET(install_bin_pdb ${install_bin_pdb} ${PROJECT_BINARY_DIR}/apr_ldap-1.pdb) + TARGET_LINK_LIBRARIES(apr_ldap-1 libaprutil-1 ${APR_LIBRARIES} ${LDAP_LIBRARIES}) + SET_TARGET_PROPERTIES(apr_ldap-1 PROPERTIES COMPILE_DEFINITIONS "WINNT") + SET_TARGET_PROPERTIES(apr_ldap-1 PROPERTIES COMPILE_FLAGS "-DAPR_DECLARE_EXPORT=1 -DAPU_DECLARE_EXPORT=1 -DDLL_NAME=apr_ldap") + SET(apr_ldap_libraries apr_ldap-1) +ELSE() + SET(apr_ldap_libraries) +ENDIF() + +IF(APR_BUILD_TESTAPR) + ENABLE_TESTING() + # Create a "check" target that displays test program output to the console. + ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND} --verbose) + + # copy data files to build directory so that we can run programs from there + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory + ${PROJECT_BINARY_DIR}/data) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${PROJECT_SOURCE_DIR}/test/data/billion-laughs.xml + ${PROJECT_BINARY_DIR}/data/billion-laughs.xml) + + IF(TEST_STATIC_LIBS) + SET(whichapr aprutil-1) + SET(apiflag "-DAPR_DECLARE_STATIC -DAPU_DECLARE_STATIC") + ELSE() + SET(whichapr libaprutil-1) + SET(apiflag) + ENDIF() + + ADD_EXECUTABLE(testall ${APR_TEST_SOURCES}) + TARGET_LINK_LIBRARIES(testall ${whichapr} ${apr_ldap_libraries} ${XMLLIB_LIBRARIES} ${LDAP_LIBRARIES}) + IF(apiflag) + SET_TARGET_PROPERTIES(testall PROPERTIES COMPILE_FLAGS ${apiflag}) + ENDIF() + ADD_TEST(NAME testall COMMAND testall) + + ADD_EXECUTABLE(dbd test/dbd.c) + TARGET_LINK_LIBRARIES(dbd ${whichapr}) + IF(apiflag) + SET_TARGET_PROPERTIES(dbd PROPERTIES COMPILE_FLAGS ${apiflag}) + ENDIF() + + # dbd is run multiple times with different parameters. + FOREACH(somedbd ${dbd_drivers}) + ADD_TEST(NAME dbd-${somedbd} COMMAND dbd ${somedbd}) + ENDFOREACH() + +ENDIF (APR_BUILD_TESTAPR) + +# Installation + +INSTALL(TARGETS ${install_targets} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + +IF(INSTALL_PDB) + INSTALL(FILES ${install_bin_pdb} + DESTINATION bin + CONFIGURATIONS RelWithDebInfo Debug) +ENDIF() + +INSTALL(FILES ${APR_PUBLIC_HEADERS_STATIC} ${APR_PUBLIC_HEADERS_GENERATED} DESTINATION include) + +STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype) +MESSAGE(STATUS "") +MESSAGE(STATUS "") +MESSAGE(STATUS "APR-Util configuration summary:") +MESSAGE(STATUS "") +MESSAGE(STATUS " Build type ...................... : ${CMAKE_BUILD_TYPE}") +MESSAGE(STATUS " Install .pdb (if available)...... : ${INSTALL_PDB}") +MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}") +MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}") +MESSAGE(STATUS " APR include directory ........... : ${APR_INCLUDE_DIR}") +MESSAGE(STATUS " APR libraries ................... : ${APR_LIBRARIES}") +MESSAGE(STATUS " DBD ODBC driver ................. : ${APU_HAVE_ODBC}") +MESSAGE(STATUS " APU_HAVE_CRYPTO ................. : ${APU_HAVE_CRYPTO}") +MESSAGE(STATUS " APR_HAS_LDAP .................... : ${APR_HAS_LDAP}") +MESSAGE(STATUS " Build test suite ................ : ${APR_BUILD_TESTAPR}") +IF(TEST_STATIC_LIBS) +MESSAGE(STATUS " (testing static libraries)") +ELSE() +MESSAGE(STATUS " (testing dynamic libraries)") +ENDIF() diff --git a/contrib/apr-util/LICENSE b/contrib/apr-util/LICENSE index 7771972d8546..bfe78d537e43 100644 --- a/contrib/apr-util/LICENSE +++ b/contrib/apr-util/LICENSE @@ -312,6 +312,22 @@ For the crypto\apr_md4.c component: * documentation and/or software. */ +For the crypto\crypt_blowfish.c(.h) component: + + * Written by Solar Designer in 1998-2011. + * No copyright is claimed, and the software is hereby placed in the public + * domain. In case this attempt to disclaim copyright and place the software + * in the public domain is deemed null and void, then the software is + * Copyright (c) 1998-2011 Solar Designer and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + + See crypto/crypt_blowfish.c for more information. + For the include\apr_md4.h component: * diff --git a/contrib/apr-util/Makefile.in b/contrib/apr-util/Makefile.in index 963feada79ad..208dd1cc1e65 100644 --- a/contrib/apr-util/Makefile.in +++ b/contrib/apr-util/Makefile.in @@ -15,8 +15,8 @@ APRUTIL_LDFLAGS = @APRUTIL_LDFLAGS@ APRUTIL_LIBS = @APRUTIL_LIBS@ TARGET_LIB = lib@APRUTIL_LIBNAME@.la -INSTALL_SUBDIRS = @APR_ICONV_DIR@ @APR_XML_DIR@ -EXTRA_SOURCE_DIRS = @APR_ICONV_DIR@ @APR_XML_DIR@ +INSTALL_SUBDIRS = @APR_ICONV_DIR@ +EXTRA_SOURCE_DIRS = @APR_ICONV_DIR@ APRUTIL_PCFILE = apr-util-$(APRUTIL_MAJOR_VERSION).pc APU_CONFIG = apu-$(APRUTIL_MAJOR_VERSION)-config INSTALL = @INSTALL@ @@ -35,7 +35,6 @@ LDADD_dbd_oracle = @LDADD_dbd_oracle@ LDADD_dbd_sqlite2 = @LDADD_dbd_sqlite2@ LDADD_dbd_sqlite3 = @LDADD_dbd_sqlite3@ LDADD_dbd_mysql = @LDADD_dbd_mysql@ -LDADD_dbd_freetds = @LDADD_dbd_freetds@ LDADD_dbd_odbc = @LDADD_dbd_odbc@ LDADD_dbm_db = @LDADD_dbm_db@ LDADD_dbm_gdbm = @LDADD_dbm_gdbm@ @@ -43,6 +42,7 @@ LDADD_dbm_ndbm = @LDADD_dbm_ndbm@ LDADD_ldap = @LDADD_ldap@ LDADD_crypto_openssl = @LDADD_crypto_openssl@ LDADD_crypto_nss = @LDADD_crypto_nss@ +LDADD_crypto_commoncrypto = @LDADD_crypto_commoncrypto@ TARGETS = $(TARGET_LIB) aprutil.exp apu-config.out $(APU_MODULES) @@ -50,7 +50,7 @@ TARGETS = $(TARGET_LIB) aprutil.exp apu-config.out $(APU_MODULES) @INCLUDE_RULES@ @INCLUDE_OUTPUTS@ -CLEAN_SUBDIRS = test @APR_ICONV_DIR@ @APR_XML_DIR@ +CLEAN_SUBDIRS = test @APR_ICONV_DIR@ CLEAN_TARGETS = exports.c export_vars.c aprutil.exp .make.dirs apu-config.out DISTCLEAN_TARGETS = config.cache config.log config.status libtool \ diff --git a/contrib/apr-util/Makefile.win b/contrib/apr-util/Makefile.win index b4b420e1c2e6..454b4fecdbf1 100644 --- a/contrib/apr-util/Makefile.win +++ b/contrib/apr-util/Makefile.win @@ -51,6 +51,13 @@ # # CRYPTO_LIST="nss openssl" # +# Provide the XML_PARSER argument after configuring LIB and INCLUDE with +# the expat path of the corresponding xml parser, e.g. libexpatMT to choose +# static, or libexpat (default) to choose the dynamic library for aprutil-1.dll +# (Static libaprutil-1.lib always presumes libexpatMT with XML_STATIC flag.) +# +# XML_PARSER="libexpat" +# # For example; # # nmake -f Makefile.win PREFIX=C:\APR buildall checkall installall clean @@ -73,6 +80,20 @@ USEDSW=1 PREFIX=..\apr-dist +!IF EXIST("..\openssl") +!IF EXIST("..\openssl\libcrypto.lib") +SSLOPT=_HAVE_OSSL110=1 +!ENDIF +!ENDIF + +# Legacy default (and unwise alternative) for libapr-1.dll is libexpatMT +XML_PARSER="libexpat" +!IF "$(XML_PARSER)" == "libexpat" +XMLOPT=XML_PARSER=$(XML_PARSER) +!ELSE +XMLOPT=XML_PARSER=$(XML_PARSER) XML_OPTIONS="/D XML_STATIC" +!ENDIF + !IF [$(COMSPEC) /c cl /nologo /? \ | $(SystemRoot)\System32\find.exe "x64" >NUL ] == 0 ARCH=x64 Release @@ -197,11 +218,9 @@ buildall: BUILD_MODE="$(ARCH)" BIND_MODE=shared cd .. !ENDIF - cd $(APU_PATH)\xml\expat\lib - $(MAKE) $(MAKEOPT) -f xml.mak CFG="xml - $(ARCH)" RECURSE=0 $(CTARGET) - cd ..\..\.. - $(MAKE) $(MAKEOPT) -f aprutil.mak CFG="aprutil - $(ARCH)" RECURSE=0 $(CTARGET) - $(MAKE) $(MAKEOPT) -f libaprutil.mak CFG="libaprutil - $(ARCH)" RECURSE=0 $(CTARGET) + cd $(APU_PATH) + $(MAKE) $(MAKEOPT) $(SSLOPT) $(XMLOPT) -f aprutil.mak CFG="aprutil - $(ARCH)" RECURSE=0 $(CTARGET) + $(MAKE) $(MAKEOPT) $(SSLOPT) $(XMLOPT) -f libaprutil.mak CFG="libaprutil - $(ARCH)" RECURSE=0 $(CTARGET) cd ldap $(MAKE) $(MAKEOPT) -f apr_ldap.mak CFG="apr_ldap - $(ARCH)" RECURSE=0 $(CTARGET) cd .. @@ -215,7 +234,7 @@ buildall: cd .. cd crypto for %d in ($(CRYPTO_LIST) x) do if not %d == x \ - $(MAKE) $(MAKEOPT) -f apr_crypto_%d.mak CFG="apr_crypto_%d - $(ARCH)" RECURSE=0 $(CTARGET) + $(MAKE) $(MAKEOPT) $(SSLOPT) -f apr_crypto_%d.mak CFG="apr_crypto_%d - $(ARCH)" RECURSE=0 $(CTARGET) cd .. !ELSEIF $(USESLN) == 1 @@ -306,7 +325,7 @@ checkapr: checkapu: cd $(APU_PATH) cd test - $(MAKE) $(MAKEOPT) -f Makefile.win MODEL=static \ + $(MAKE) $(MAKEOPT) -f Makefile.win MODEL=static \ OUTDIR=$(LIBSPATH) APROUTDIR=$(LIBSOSPATH) \ APR_PATH=..\$(APR_PATH) API_PATH=..\$(API_PATH) check $(MAKE) $(MAKEOPT) -f Makefile.win MODEL=dynamic \ diff --git a/contrib/apr-util/NOTICE b/contrib/apr-util/NOTICE index a107139ef37e..3ae54e128be8 100644 --- a/contrib/apr-util/NOTICE +++ b/contrib/apr-util/NOTICE @@ -1,5 +1,5 @@ Apache Portable Runtime Utility Library -Copyright (c) 2000-2014 The Apache Software Foundation. +Copyright (c) 2000-2016 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/contrib/apr-util/NWGNUmakefile b/contrib/apr-util/NWGNUmakefile index e089b6fc7f36..cef05ee0dc2e 100644 --- a/contrib/apr-util/NWGNUmakefile +++ b/contrib/apr-util/NWGNUmakefile @@ -261,9 +261,11 @@ FILES_lib_objs = \ $(OBJDIR)/apr_memcache.o \ $(OBJDIR)/apr_passwd.o \ $(OBJDIR)/apr_queue.o \ + $(OBJDIR)/apr_redis.o \ $(OBJDIR)/apr_reslist.o \ $(OBJDIR)/apr_rmm.o \ $(OBJDIR)/apr_sha1.o \ + $(OBJDIR)/apr_siphash.o \ $(OBJDIR)/apu_version.o \ $(OBJDIR)/getuuid.o \ $(OBJDIR)/uuid.o \ @@ -296,7 +298,7 @@ install :: nlms FORCE # Any specialized rules here # -vpath %.c buckets:crypto:dbd:dbm:dbm/sdbm:encoding:hooks:ldap:memcache:misc:strmatch:uri:xlate:xml +vpath %.c buckets:crypto:dbd:dbm:dbm/sdbm:encoding:hooks:ldap:memcache:redis:misc:strmatch:uri:xlate:xml # # Include the 'tail' makefile that has targets that depend on variables defined diff --git a/contrib/apr-util/README b/contrib/apr-util/README index 3a685698bee8..9ea474d8faba 100644 --- a/contrib/apr-util/README +++ b/contrib/apr-util/README @@ -34,7 +34,7 @@ Apache Portable Runtime Utility Library README String filename-style pattern matching URI Parsing Charset translation (iconv based) - XML parsing (expat based) + XML parsing (expat) For a more complete list, please refer to the following URLs: @@ -66,7 +66,7 @@ for your compiled code. Similarly, the bindings for propritary drivers such as Oracle (--with-oracle option) must also be explicitly enabled. On windows, selection of supported drivers is via the environment values -DBD_LIST (for freetds, mysql, oracle, pgsql, sqlite2 and/or sqlite3) +DBD_LIST (for mysql, oracle, pgsql, sqlite2 and/or sqlite3) and DBM_LIST (db and/or gdbm). DBD odbc and DBM sdbm are unconditionally compiled and installed, do not include these in the list. diff --git a/contrib/apr-util/README.FREETDS b/contrib/apr-util/README.FREETDS new file mode 100644 index 000000000000..4066a9c78b38 --- /dev/null +++ b/contrib/apr-util/README.FREETDS @@ -0,0 +1,11 @@ +The APR DBD Driver for FreeTDS has been removed from the build. +It is known to have problems, and we are not able to maintain it. + +The source code is still available. If you want it and are able +to manage maintenance for yourself, you can patch the build and +work through issues that affect you, but you're on your own. + +We expect that for most users, the ODBC driver will serve as +an alternative. + +Sorry. diff --git a/contrib/apr-util/README.cmake b/contrib/apr-util/README.cmake new file mode 100644 index 000000000000..85de33a21e95 --- /dev/null +++ b/contrib/apr-util/README.cmake @@ -0,0 +1,139 @@ +Experimental cmake-based build support for APR-Util on Microsoft Windows + +Status +------ + +This build support is currently intended only for Microsoft Windows. +Only Windows NT-based systems can be targeted. (The traditional +Windows build support for APR can target Windows 9x as well.) + +This build support is experimental. Specifically, + +* It does not support all features of APR-Util. +* Some components may not be built correctly and/or in a manner + compatible with the previous Windows build support. +* Build interfaces, such as the mechanisms which are used to enable + optional functionality or specify prerequisites, may change from + release to release as feedback is received from users and bugs and + limitations are resolved. + +Important: Refer to the "Known Bugs and Limitations" section for further + information. + + It is beyond the scope of this document to document or explain + how to utilize the various cmake features, such as different + build backends or provisions for finding support libraries. + + Please refer to the cmake documentation for additional information + that applies to building any project with cmake. + +Prerequisites +------------- + +The following tools must be in PATH: + +* cmake, version 2.8 or later + cmake version 3.1.3 or later is required to work with current OpenSSL + releases. (OpenSSL is an optional prerequisite of APR-Util.) +* If using a command-line compiler: compiler and linker and related tools + (Refer to the cmake documentation for more information.) + +The following support libraries are mandatory: + +* APR 1.4.x or APR 1.5.x, built with cmake + +Optional support libraries allow optional features of APR to be enabled: + +* OpenSSL +* many others potentially, though the build support isn't currently + implemented + +How to build +------------ + +1. cd to a clean directory for building (i.e., don't build in your + source tree) + +2. Some cmake backends may want your compile tools in PATH. (Hint: "Visual + Studio Command Prompt") + +3. set CMAKE_LIBRARY_PATH=d:\path\to\prereq1\lib;d:\path\to\prereq2\lib;... + +4. set CMAKE_INCLUDE_PATH=d:\path\to\prereq1\include;d:\path\to\prereq2\include;... + +5. cmake -G "some backend, like 'NMake Makefiles'" + -DCMAKE_INSTALL_PREFIX=d:/path/to/aprinst + -DAPR-Util-specific-flags + d:/path/to/aprutilsource + + If APR 1.x was installed to a different directory than APR-Util, + also pass these additional arguments: + + -DAPR_INCLUDE_DIR=d:/path/to/apr1inst/include + -DAPR_LIBRARIES=d:/path/to/apr1inst/lib/libapr-1.lib + + Alternately, use cmake-gui and update settings in the GUI. + + APR-Util feature flags: + + APU_HAVE_CRYPTO Build crypt support (only the OpenSSL + implementation is currently supported) + Default: OFF + APU_HAVE_ODBC Build ODBC DBD driver + Default: ON + APR_BUILD_TESTAPR Build APR-Util test suite + Default: OFF + TEST_STATIC_LIBS Build the test suite to test the APR static + library instead of the APR dynamic library. + Default: OFF + In order to build the test suite against both + static and dynamic libraries, separate builds + will be required, one with TEST_STATIC_LIBS + set to ON. + INSTALL_PDB Install .pdb files if generated. + Default: ON + + CMAKE_C_FLAGS_RELEASE, _DEBUG, _RELWITHDEBINFO, _MINSIZEREL + + CMAKE_BUILD_TYPE + + For NMake Makefiles the choices are at least DEBUG, RELEASE, + RELWITHDEBINFO, and MINSIZEREL + Other backends make have other selections. + +6. build using chosen backend (e.g., "nmake install") + +Known Bugs and Limitations +-------------------------- + +* If include/apu.h or other generated files have been created in the source + directory by another build system, they will be used unexpectedly and + cause the build to fail. +* Options should be provided for remaining features, along with finding any + necessary libraries + + DBM: + . APU_HAVE_GDBM + . APU_HAVE_NDBM + . APU_HAVE_DB + + DBD: + . APU_HAVE_PGSQL + . APU_HAVE_MYSQL + . APU_HAVE_SQLITE3 + . APU_HAVE_SQLITE2 + . APU_HAVE_ORACLE + + CRYPTO: + . APU_HAVE_NSS + + XLATE, APU_HAVE_ICONV (no way to consume an apr-iconv build yet) +* Static builds of APR modules are not supported. +* CHANGES/LICENSE/NOTICE is not installed, unlike Makefile.win. + (But unlike Makefile.win we want to call them APR-Util-CHANGES.txt + and so on.) But perhaps that is a job for a higher-level script. + +Generally: + +* Many APR-Util features have not been tested with this build. +* Developers need to examine the existing Windows build in great detail and see + what is missing from the cmake-based build, whether a feature or some build + nuance. +* Any feedback you can provide on your experiences with this build will be + helpful. diff --git a/contrib/apr-util/apr-util.spec b/contrib/apr-util/apr-util.spec index e9dc24b08da7..18fdea1c529f 100644 --- a/contrib/apr-util/apr-util.spec +++ b/contrib/apr-util/apr-util.spec @@ -3,7 +3,7 @@ Summary: Apache Portable Runtime Utility library Name: apr-util -Version: 1.5.4 +Version: 1.6.1 Release: 1 License: Apache Software License Group: System Environment/Libraries @@ -70,16 +70,6 @@ Requires: apr-util = %{version}-%{release} This package provides the SQLite driver for the apr-util DBD (database abstraction) interface. -%package freetds -Group: Development/Libraries -Summary: APR utility library FreeTDS DBD driver -BuildRequires: freetds-devel -Requires: apr-util = %{version}-%{release} - -%description freetds -This package provides the FreeTDS driver for the apr-util DBD -(database abstraction) interface. - %package odbc Group: Development/Libraries Summary: APR utility library ODBC DBD driver @@ -124,7 +114,7 @@ This package provides crypto support for apr-util based on Mozilla NSS. %configure --with-apr=%{_prefix} \ --includedir=%{_includedir}/apr-%{apuver} \ --with-ldap --without-gdbm \ - --with-sqlite3 --with-pgsql --with-mysql --with-freetds --with-odbc \ + --with-sqlite3 --with-pgsql --with-mysql --with-odbc \ --with-berkeley-db \ --with-crypto --with-openssl --with-nss \ --without-sqlite2 @@ -176,10 +166,6 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root,-) %{_libdir}/apr-util-%{apuver}/apr_dbd_sqlite* -%files freetds -%defattr(-,root,root,-) -%{_libdir}/apr-util-%{apuver}/apr_dbd_freetds* - %files odbc %defattr(-,root,root,-) %{_libdir}/apr-util-%{apuver}/apr_dbd_odbc* @@ -203,7 +189,7 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/libaprutil-%{apuver}.so %{_libdir}/pkgconfig/apr-util-%{apuver}.pc %{_includedir}/apr-%{apuver}/*.h -%doc --parents html +%doc html %changelog * Tue Jun 22 2004 Graham Leggett 1.0.0-1 diff --git a/contrib/apr-util/aprutil.dsw b/contrib/apr-util/aprutil.dsw index 9d60aff83a8e..a2976ccc5989 100644 --- a/contrib/apr-util/aprutil.dsw +++ b/contrib/apr-util/aprutil.dsw @@ -51,24 +51,6 @@ Package=<4> ############################################################################### -Project: "apr_dbd_freetds"=".\dbd\apr_dbd_freetds.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libapr - End Project Dependency - Begin Project Dependency - Project_Dep_Name libaprutil - End Project Dependency -}}} - -############################################################################### - Project: "apr_dbd_mysql"=".\dbd\apr_dbd_mysql.dsp" - Package Owner=<4> Package=<5> @@ -275,9 +257,6 @@ Package=<4> Begin Project Dependency Project_Dep_Name apriconv End Project Dependency - Begin Project Dependency - Project_Dep_Name xml - End Project Dependency }}} ############################################################################### @@ -383,9 +362,6 @@ Package=<4> Begin Project Dependency Project_Dep_Name libapriconv_ces_modules End Project Dependency - Begin Project Dependency - Project_Dep_Name xml - End Project Dependency }}} ############################################################################### @@ -453,18 +429,6 @@ Package=<4> ############################################################################### -Project: "xml"=".\xml\expat\lib\xml.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Global: Package=<5> diff --git a/contrib/apr-util/apu-config.in b/contrib/apr-util/apu-config.in index e181e44ae319..82109e52d065 100644 --- a/contrib/apr-util/apu-config.in +++ b/contrib/apr-util/apu-config.in @@ -85,10 +85,6 @@ fi if test "$location" = "installed"; then LA_FILE="$libdir/lib${APRUTIL_LIBNAME}.la" - - LIBS=`echo "$LIBS" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g" -e "s $prefix/libexpat.la -lexpat g"` - LDFLAGS=`echo "$LDFLAGS" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g"` - INCLUDES=`echo "$INCLUDES" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g" -e "s -I$prefix/lib g"` else LA_FILE="$APU_BUILD_DIR/lib${APRUTIL_LIBNAME}.la" fi diff --git a/contrib/apr-util/buckets/apr_buckets_alloc.c b/contrib/apr-util/buckets/apr_buckets_alloc.c index 15baa3396655..e5838dd016ec 100644 --- a/contrib/apr-util/buckets/apr_buckets_alloc.c +++ b/contrib/apr-util/buckets/apr_buckets_alloc.c @@ -18,6 +18,7 @@ #include "apr_buckets.h" #include "apr_allocator.h" +#include "apr_version.h" #define ALLOC_AMT (8192 - APR_MEMNODE_T_SIZE) @@ -121,6 +122,37 @@ APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list) #endif } +APU_DECLARE_NONSTD(apr_size_t) apr_bucket_alloc_aligned_floor(apr_bucket_alloc_t *list, + apr_size_t size) +{ + if (size <= SMALL_NODE_SIZE) { + size = SMALL_NODE_SIZE; + } + else { +#if APR_VERSION_AT_LEAST(1,6,0) + if (size < APR_MEMNODE_T_SIZE) { + size = apr_allocator_align(list->allocator, 0); + } + else { + size = apr_allocator_align(list->allocator, + size - APR_MEMNODE_T_SIZE); + } +#else + /* Assumes the minimum (default) allocator's boundary of 4K and + * minimum (immutable before APR-1.6.x) allocation size of 8K, + * hence possibly (yet unlikely) under-estimating the floor... + */ + size = APR_ALIGN(size, 4096); + if (size < 8192) { + size = 8192; + } +#endif + size -= APR_MEMNODE_T_SIZE; + } + size -= SIZEOF_NODE_HEADER_T; + return size; +} + APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list) { diff --git a/contrib/apr-util/buckets/apr_buckets_file.c b/contrib/apr-util/buckets/apr_buckets_file.c index 0644cd82ce7a..06b7cf0039f1 100644 --- a/contrib/apr-util/buckets/apr_buckets_file.c +++ b/contrib/apr-util/buckets/apr_buckets_file.c @@ -108,10 +108,8 @@ static apr_status_t file_bucket_read(apr_bucket *e, const char **str, } #endif - *len = (filelength > APR_BUCKET_BUFF_SIZE) - ? APR_BUCKET_BUFF_SIZE - : filelength; *str = NULL; /* in case we die prematurely */ + *len = (filelength > a->read_size) ? a->read_size : filelength; buf = apr_bucket_alloc(*len, e->list); /* Handle offset ... */ @@ -165,6 +163,7 @@ APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd, #if APR_HAS_MMAP f->can_mmap = 1; #endif + f->read_size = APR_BUCKET_BUFF_SIZE; b = apr_bucket_shared_make(b, f, offset, len); b->type = &apr_bucket_type_file; @@ -197,6 +196,21 @@ APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *e, #endif /* APR_HAS_MMAP */ } +APU_DECLARE(apr_status_t) apr_bucket_file_set_buf_size(apr_bucket *e, + apr_size_t size) +{ + apr_bucket_file *a = e->data; + + if (size <= APR_BUCKET_BUFF_SIZE) { + a->read_size = APR_BUCKET_BUFF_SIZE; + } + else { + apr_size_t floor = apr_bucket_alloc_aligned_floor(e->list, size); + a->read_size = (size < floor) ? size : floor; + } + + return APR_SUCCESS; +} static apr_status_t file_bucket_setaside(apr_bucket *data, apr_pool_t *reqpool) { diff --git a/contrib/apr-util/build-outputs.mk b/contrib/apr-util/build-outputs.mk index b624532ebd2b..f6042d6b8ce1 100644 --- a/contrib/apr-util/build-outputs.mk +++ b/contrib/apr-util/build-outputs.mk @@ -18,6 +18,7 @@ crypto/apr_md4.lo: crypto/apr_md4.c .make.dirs include/apr_md4.h include/apr_xla crypto/apr_md5.lo: crypto/apr_md5.c .make.dirs include/apr_md5.h include/apr_xlate.h crypto/apr_passwd.lo: crypto/apr_passwd.c .make.dirs include/apr_md5.h include/apr_sha1.h include/apr_xlate.h crypto/apr_sha1.lo: crypto/apr_sha1.c .make.dirs include/apr_base64.h include/apr_sha1.h include/apr_xlate.h +crypto/apr_siphash.lo: crypto/apr_siphash.c .make.dirs include/apr_siphash.h crypto/crypt_blowfish.lo: crypto/crypt_blowfish.c .make.dirs crypto/getuuid.lo: crypto/getuuid.c .make.dirs include/apr_md5.h include/apr_uuid.h include/apr_xlate.h crypto/uuid.lo: crypto/uuid.c .make.dirs include/apr_uuid.h @@ -40,12 +41,13 @@ misc/apr_rmm.lo: misc/apr_rmm.c .make.dirs include/apr_anylock.h include/apr_rmm misc/apr_thread_pool.lo: misc/apr_thread_pool.c .make.dirs include/apr_thread_pool.h misc/apu_dso.lo: misc/apu_dso.c .make.dirs include/apu_version.h include/private/apu_internal.h misc/apu_version.lo: misc/apu_version.c .make.dirs include/apu_version.h +redis/apr_redis.lo: redis/apr_redis.c .make.dirs include/apr_buckets.h include/apr_redis.h include/apr_reslist.h strmatch/apr_strmatch.lo: strmatch/apr_strmatch.c .make.dirs include/apr_strmatch.h uri/apr_uri.lo: uri/apr_uri.c .make.dirs include/apr_uri.h xlate/xlate.lo: xlate/xlate.c .make.dirs include/apr_xlate.h xml/apr_xml.lo: xml/apr_xml.c .make.dirs include/apr_xlate.h include/apr_xml.h -OBJECTS_all = buckets/apr_brigade.lo buckets/apr_buckets.lo buckets/apr_buckets_alloc.lo buckets/apr_buckets_eos.lo buckets/apr_buckets_file.lo buckets/apr_buckets_flush.lo buckets/apr_buckets_heap.lo buckets/apr_buckets_mmap.lo buckets/apr_buckets_pipe.lo buckets/apr_buckets_pool.lo buckets/apr_buckets_refcount.lo buckets/apr_buckets_simple.lo buckets/apr_buckets_socket.lo crypto/apr_crypto.lo crypto/apr_md4.lo crypto/apr_md5.lo crypto/apr_passwd.lo crypto/apr_sha1.lo crypto/crypt_blowfish.lo crypto/getuuid.lo crypto/uuid.lo dbd/apr_dbd.lo dbm/apr_dbm.lo dbm/apr_dbm_sdbm.lo dbm/sdbm/sdbm.lo dbm/sdbm/sdbm_hash.lo dbm/sdbm/sdbm_lock.lo dbm/sdbm/sdbm_pair.lo encoding/apr_base64.lo hooks/apr_hooks.lo ldap/apr_ldap_stub.lo ldap/apr_ldap_url.lo memcache/apr_memcache.lo misc/apr_date.lo misc/apr_queue.lo misc/apr_reslist.lo misc/apr_rmm.lo misc/apr_thread_pool.lo misc/apu_dso.lo misc/apu_version.lo strmatch/apr_strmatch.lo uri/apr_uri.lo xlate/xlate.lo xml/apr_xml.lo +OBJECTS_all = buckets/apr_brigade.lo buckets/apr_buckets.lo buckets/apr_buckets_alloc.lo buckets/apr_buckets_eos.lo buckets/apr_buckets_file.lo buckets/apr_buckets_flush.lo buckets/apr_buckets_heap.lo buckets/apr_buckets_mmap.lo buckets/apr_buckets_pipe.lo buckets/apr_buckets_pool.lo buckets/apr_buckets_refcount.lo buckets/apr_buckets_simple.lo buckets/apr_buckets_socket.lo crypto/apr_crypto.lo crypto/apr_md4.lo crypto/apr_md5.lo crypto/apr_passwd.lo crypto/apr_sha1.lo crypto/apr_siphash.lo crypto/crypt_blowfish.lo crypto/getuuid.lo crypto/uuid.lo dbd/apr_dbd.lo dbm/apr_dbm.lo dbm/apr_dbm_sdbm.lo dbm/sdbm/sdbm.lo dbm/sdbm/sdbm_hash.lo dbm/sdbm/sdbm_lock.lo dbm/sdbm/sdbm_pair.lo encoding/apr_base64.lo hooks/apr_hooks.lo ldap/apr_ldap_stub.lo ldap/apr_ldap_url.lo memcache/apr_memcache.lo misc/apr_date.lo misc/apr_queue.lo misc/apr_reslist.lo misc/apr_rmm.lo misc/apr_thread_pool.lo misc/apu_dso.lo misc/apu_version.lo redis/apr_redis.lo strmatch/apr_strmatch.lo uri/apr_uri.lo xlate/xlate.lo xml/apr_xml.lo OBJECTS_unix = $(OBJECTS_all) @@ -59,9 +61,9 @@ OBJECTS_os390 = $(OBJECTS_all) OBJECTS_win32 = $(OBJECTS_all) -HEADERS = $(top_srcdir)/include/apr_anylock.h $(top_srcdir)/include/apr_base64.h $(top_srcdir)/include/apr_buckets.h $(top_srcdir)/include/apr_crypto.h $(top_srcdir)/include/apr_date.h $(top_srcdir)/include/apr_dbd.h $(top_srcdir)/include/apr_dbm.h $(top_srcdir)/include/apr_hooks.h $(top_srcdir)/include/apr_ldap_init.h $(top_srcdir)/include/apr_ldap_option.h $(top_srcdir)/include/apr_ldap_rebind.h $(top_srcdir)/include/apr_ldap_url.h $(top_srcdir)/include/apr_md4.h $(top_srcdir)/include/apr_md5.h $(top_srcdir)/include/apr_memcache.h $(top_srcdir)/include/apr_optional.h $(top_srcdir)/include/apr_optional_hooks.h $(top_srcdir)/include/apr_queue.h $(top_srcdir)/include/apr_reslist.h $(top_srcdir)/include/apr_rmm.h $(top_srcdir)/include/apr_sdbm.h $(top_srcdir)/include/apr_sha1.h $(top_srcdir)/include/apr_strmatch.h $(top_srcdir)/include/apr_thread_pool.h $(top_srcdir)/include/apr_uri.h $(top_srcdir)/include/apr_uuid.h $(top_srcdir)/include/apr_xlate.h $(top_srcdir)/include/apr_xml.h $(top_srcdir)/include/apu_errno.h $(top_srcdir)/include/apu_version.h $(top_srcdir)/include/private/apr_crypto_internal.h $(top_srcdir)/include/private/apr_dbd_internal.h $(top_srcdir)/include/private/apr_dbd_odbc_v2.h $(top_srcdir)/include/private/apr_dbm_private.h $(top_srcdir)/include/private/apu_internal.h +HEADERS = $(top_srcdir)/include/apr_anylock.h $(top_srcdir)/include/apr_base64.h $(top_srcdir)/include/apr_buckets.h $(top_srcdir)/include/apr_crypto.h $(top_srcdir)/include/apr_date.h $(top_srcdir)/include/apr_dbd.h $(top_srcdir)/include/apr_dbm.h $(top_srcdir)/include/apr_hooks.h $(top_srcdir)/include/apr_ldap_init.h $(top_srcdir)/include/apr_ldap_option.h $(top_srcdir)/include/apr_ldap_rebind.h $(top_srcdir)/include/apr_ldap_url.h $(top_srcdir)/include/apr_md4.h $(top_srcdir)/include/apr_md5.h $(top_srcdir)/include/apr_memcache.h $(top_srcdir)/include/apr_optional.h $(top_srcdir)/include/apr_optional_hooks.h $(top_srcdir)/include/apr_queue.h $(top_srcdir)/include/apr_redis.h $(top_srcdir)/include/apr_reslist.h $(top_srcdir)/include/apr_rmm.h $(top_srcdir)/include/apr_sdbm.h $(top_srcdir)/include/apr_sha1.h $(top_srcdir)/include/apr_siphash.h $(top_srcdir)/include/apr_strmatch.h $(top_srcdir)/include/apr_thread_pool.h $(top_srcdir)/include/apr_uri.h $(top_srcdir)/include/apr_uuid.h $(top_srcdir)/include/apr_xlate.h $(top_srcdir)/include/apr_xml.h $(top_srcdir)/include/apu_errno.h $(top_srcdir)/include/apu_version.h $(top_srcdir)/include/private/apr_crypto_internal.h $(top_srcdir)/include/private/apr_dbd_internal.h $(top_srcdir)/include/private/apr_dbd_odbc_v2.h $(top_srcdir)/include/private/apr_dbm_private.h $(top_srcdir)/include/private/apu_internal.h -SOURCE_DIRS = xml dbm encoding hooks buckets uri misc crypto dbd strmatch memcache dbm/sdbm ldap xlate $(EXTRA_SOURCE_DIRS) +SOURCE_DIRS = xml redis dbm encoding hooks buckets uri misc crypto dbd strmatch memcache dbm/sdbm ldap xlate $(EXTRA_SOURCE_DIRS) ldap/apr_ldap_init.lo: ldap/apr_ldap_init.c .make.dirs include/private/apu_internal.h ldap/apr_ldap_option.lo: ldap/apr_ldap_option.c .make.dirs @@ -83,6 +85,12 @@ MODULE_crypto_nss = crypto/apr_crypto_nss.la crypto/apr_crypto_nss.la: crypto/apr_crypto_nss.lo $(LINK_MODULE) -o $@ $(OBJECTS_crypto_nss) $(LDADD_crypto_nss) +crypto/apr_crypto_commoncrypto.lo: crypto/apr_crypto_commoncrypto.c .make.dirs include/apr_buckets.h include/apr_crypto.h include/apu_errno.h include/private/apr_crypto_internal.h +OBJECTS_crypto_commoncrypto = crypto/apr_crypto_commoncrypto.lo +MODULE_crypto_commoncrypto = crypto/apr_crypto_commoncrypto.la +crypto/apr_crypto_commoncrypto.la: crypto/apr_crypto_commoncrypto.lo + $(LINK_MODULE) -o $@ $(OBJECTS_crypto_commoncrypto) $(LDADD_crypto_commoncrypto) + dbd/apr_dbd_pgsql.lo: dbd/apr_dbd_pgsql.c .make.dirs include/apr_buckets.h include/apr_dbd.h include/private/apr_dbd_internal.h OBJECTS_dbd_pgsql = dbd/apr_dbd_pgsql.lo MODULE_dbd_pgsql = dbd/apr_dbd_pgsql.la @@ -113,12 +121,6 @@ MODULE_dbd_mysql = dbd/apr_dbd_mysql.la dbd/apr_dbd_mysql.la: dbd/apr_dbd_mysql.lo $(LINK_MODULE) -o $@ $(OBJECTS_dbd_mysql) $(LDADD_dbd_mysql) -dbd/apr_dbd_freetds.lo: dbd/apr_dbd_freetds.c .make.dirs include/apr_dbd.h include/private/apr_dbd_internal.h -OBJECTS_dbd_freetds = dbd/apr_dbd_freetds.lo -MODULE_dbd_freetds = dbd/apr_dbd_freetds.la -dbd/apr_dbd_freetds.la: dbd/apr_dbd_freetds.lo - $(LINK_MODULE) -o $@ $(OBJECTS_dbd_freetds) $(LDADD_dbd_freetds) - dbd/apr_dbd_odbc.lo: dbd/apr_dbd_odbc.c .make.dirs include/apr_buckets.h include/apr_dbd.h include/apu_version.h include/private/apr_dbd_internal.h include/private/apr_dbd_odbc_v2.h OBJECTS_dbd_odbc = dbd/apr_dbd_odbc.lo MODULE_dbd_odbc = dbd/apr_dbd_odbc.la @@ -143,7 +145,7 @@ MODULE_dbm_ndbm = dbm/apr_dbm_ndbm.la dbm/apr_dbm_ndbm.la: dbm/apr_dbm_ndbm.lo $(LINK_MODULE) -o $@ $(OBJECTS_dbm_ndbm) $(LDADD_dbm_ndbm) -BUILD_DIRS = buckets crypto dbd dbm dbm/sdbm encoding hooks ldap memcache misc strmatch uri xlate xml +BUILD_DIRS = buckets crypto dbd dbm dbm/sdbm encoding hooks ldap memcache misc redis strmatch uri xlate xml .make.dirs: $(srcdir)/build-outputs.mk @for d in $(BUILD_DIRS); do test -d $$d || mkdir $$d; done diff --git a/contrib/apr-util/build.conf b/contrib/apr-util/build.conf index d34d004fe33a..86e8c346df47 100644 --- a/contrib/apr-util/build.conf +++ b/contrib/apr-util/build.conf @@ -12,6 +12,7 @@ paths = crypto/apr_md5.c crypto/apr_passwd.c crypto/apr_sha1.c + crypto/apr_siphash.c crypto/getuuid.c crypto/uuid.c crypto/crypt_blowfish.c @@ -24,6 +25,7 @@ paths = ldap/apr_ldap_url.c misc/*.c memcache/*.c + redis/*.c uri/apr_uri.c xml/*.c strmatch/*.c @@ -37,8 +39,8 @@ platform_dirs = headers = include/*.h include/private/*.h modules = - ldap crypto_openssl crypto_nss dbd_pgsql - dbd_sqlite2 dbd_sqlite3 dbd_oracle dbd_mysql dbd_freetds dbd_odbc + ldap crypto_openssl crypto_nss crypto_commoncrypto dbd_pgsql + dbd_sqlite2 dbd_sqlite3 dbd_oracle dbd_mysql dbd_odbc dbm_db dbm_gdbm dbm_ndbm # gen_uri_delim.c @@ -46,6 +48,10 @@ modules = # we have a recursive makefile for the test files (for now) # test/*.c +[crypto_commoncrypto] +paths = crypto/apr_crypto_commoncrypto.c +target = crypto/apr_crypto_commoncrypto.la + [crypto_openssl] paths = crypto/apr_crypto_openssl.c target = crypto/apr_crypto_openssl.la @@ -74,10 +80,6 @@ target = dbd/apr_dbd_oracle.la paths = dbd/apr_dbd_mysql.c target = dbd/apr_dbd_mysql.la -[dbd_freetds] -paths = dbd/apr_dbd_freetds.c -target = dbd/apr_dbd_freetds.la - [dbd_odbc] paths = dbd/apr_dbd_odbc.c target = dbd/apr_dbd_odbc.la diff --git a/contrib/apr-util/buildconf b/contrib/apr-util/buildconf index 5d6536f5cf32..3abfe105f6ee 100755 --- a/contrib/apr-util/buildconf +++ b/contrib/apr-util/buildconf @@ -89,14 +89,6 @@ fi echo "Generating 'make' outputs ..." $apr_src_dir/build/gen-build.py $verbose make -# -# If Expat has been bundled, then go and configure the thing -# -if [ -f xml/expat/buildconf.sh ]; then - echo "Invoking xml/expat/buildconf.sh ..." - (cd xml/expat; ./buildconf.sh $verbose) -fi - # Remove autoconf cache again rm -rf autom4te*.cache @@ -114,3 +106,13 @@ if [ -f `which cut` ]; then ./build/rpm/apr-util.spec.in > apr-util.spec fi +# Verify the tree was clean, notify user if not (normal in development) +# +if [ -f "include/apu.h" -o -f "include/private/apu_config.h" -o \ + -f "include/apu_want.h" -o -f "include/private/apu_select_dbm.h" ]; then + echo "" + echo "Generated include files already exist, the tree is not clean." + echo "The resulting build-outputs.mk file is incorrect" +fi + +exit 0 diff --git a/contrib/apr-util/configure b/contrib/apr-util/configure index 8ddd0e88f058..7a1f02696076 100755 --- a/contrib/apr-util/configure +++ b/contrib/apr-util/configure @@ -637,13 +637,10 @@ lib_target so_ext have_apr_iconv have_iconv -APR_XML_DIR apu_dbd_tests LDADD_dbd_odbc apu_have_odbc ODBC_CONFIG -LDADD_dbd_freetds -apu_have_freetds LDADD_dbd_oracle apu_have_oracle LDADD_dbd_sqlite2 @@ -690,6 +687,8 @@ apu_has_ldapssl_client_init ldap_ssl_h lber_h ldap_h +LDADD_crypto_commoncrypto +apu_have_commoncrypto LDADD_crypto_nss apu_have_nss PKG_CONFIG @@ -781,6 +780,7 @@ with_apr_iconv with_crypto with_openssl with_nss +with_commoncrypto with_lber with_ldap_include with_ldap_lib @@ -795,7 +795,6 @@ with_sqlite3 with_sqlite2 with_oracle_include with_oracle -with_freetds with_odbc with_expat with_iconv @@ -1435,6 +1434,7 @@ Optional Packages: --with-crypto enable crypto support --with-openssl=DIR specify location of OpenSSL --with-nss=DIR specify location of NSS + --with-commoncrypto=DIR specify location of CommonCrypto --with-lber=library lber library to use --with-ldap-include=path path to ldap include files with trailing slash --with-ldap-lib=path path to ldap lib file @@ -1463,9 +1463,8 @@ Optional Packages: --with-oracle-include=DIR path to Oracle include files --with-oracle=DIR enable Oracle DBD driver; giving ORACLE_HOME as DIR - --with-freetds=DIR specify FreeTDS location --with-odbc=DIR specify ODBC location - --with-expat=DIR specify Expat location, or 'builtin' + --with-expat=DIR specify Expat location --with-iconv=DIR path to iconv installation Some influential environment variables: @@ -2507,6 +2506,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + @@ -4739,6 +4740,7 @@ done apu_have_crypto=0 apu_have_openssl=0 apu_have_nss=0 + apu_have_commoncrypto=0 old_libs="$LIBS" old_cppflags="$CPPFLAGS" @@ -4748,7 +4750,7 @@ done # Check whether --with-crypto was given. if test "${with_crypto+set}" = set; then : withval=$with_crypto; - cryptolibs="openssl nss" + cryptolibs="openssl nss commoncrypto" if test "$withval" = "yes"; then @@ -4801,9 +4803,9 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BN_init in -lcrypto" >&5 -$as_echo_n "checking for BN_init in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_BN_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_new in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_new in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -4817,27 +4819,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char BN_init (); +char EVP_CIPHER_CTX_new (); int main () { -return BN_init (); +return EVP_CIPHER_CTX_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_BN_init=yes + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=yes else - ac_cv_lib_crypto_BN_init=no + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=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_BN_init" >&5 -$as_echo "$ac_cv_lib_crypto_BN_init" >&6; } -if test "x$ac_cv_lib_crypto_BN_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_accept in -lssl" >&5 $as_echo_n "checking for SSL_accept in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_accept+:} false; then : @@ -4947,9 +4949,9 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BN_init in -lcrypto" >&5 -$as_echo_n "checking for BN_init in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_BN_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_new in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_new in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -4963,27 +4965,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char BN_init (); +char EVP_CIPHER_CTX_new (); int main () { -return BN_init (); +return EVP_CIPHER_CTX_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_BN_init=yes + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=yes else - ac_cv_lib_crypto_BN_init=no + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=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_BN_init" >&5 -$as_echo "$ac_cv_lib_crypto_BN_init" >&6; } -if test "x$ac_cv_lib_crypto_BN_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_accept in -lssl" >&5 $as_echo_n "checking for SSL_accept in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_accept+:} false; then : @@ -5072,145 +5074,6 @@ fi fi - if test "$apu_have_openssl" != "1"; then - for ac_header in openssl/x509.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "openssl/x509.h" "ac_cv_header_openssl_x509_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_x509_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_X509_H 1 -_ACEOF - openssl_have_headers=1 -fi - -done - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BN_init in -lcrypto" >&5 -$as_echo_n "checking for BN_init in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_BN_init+:} 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 BN_init (); -int -main () -{ -return BN_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_BN_init=yes -else - ac_cv_lib_crypto_BN_init=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_BN_init" >&5 -$as_echo "$ac_cv_lib_crypto_BN_init" >&6; } -if test "x$ac_cv_lib_crypto_BN_init" = xyes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_accept in -lssl" >&5 -$as_echo_n "checking for SSL_accept in -lssl... " >&6; } -if ${ac_cv_lib_ssl_SSL_accept+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl -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 SSL_accept (); -int -main () -{ -return SSL_accept (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_SSL_accept=yes -else - ac_cv_lib_ssl_SSL_accept=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_ssl_SSL_accept" >&5 -$as_echo "$ac_cv_lib_ssl_SSL_accept" >&6; } -if test "x$ac_cv_lib_ssl_SSL_accept" = xyes; then : - openssl_have_libs=1 -fi - -fi - - if test "$openssl_have_headers" != "0" && test "$openssl_have_libs" != "0"; then - apu_have_openssl=1 - - if test "x$APRUTIL_LDFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting APRUTIL_LDFLAGS to \"-L$withval/lib\"" - APRUTIL_LDFLAGS="-L$withval/lib" - else - apr_addto_bugger="-L$withval/lib" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $APRUTIL_LDFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to APRUTIL_LDFLAGS" - APRUTIL_LDFLAGS="$APRUTIL_LDFLAGS $i" - fi - done - fi - - - if test "x$APRUTIL_INCLUDES" = "x"; then - test "x$silent" != "xyes" && echo " setting APRUTIL_INCLUDES to \"-I$withval/include\"" - APRUTIL_INCLUDES="-I$withval/include" - else - apr_addto_bugger="-I$withval/include" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $APRUTIL_INCLUDES; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to APRUTIL_INCLUDES" - APRUTIL_INCLUDES="$APRUTIL_INCLUDES $i" - fi - done - fi - - fi - fi - ac_fn_c_check_decl "$LINENO" "EVP_PKEY_CTX_new" "ac_cv_have_decl_EVP_PKEY_CTX_new" "#include " if test "x$ac_cv_have_decl_EVP_PKEY_CTX_new" = xyes; then : @@ -5820,12 +5683,329 @@ fi + LIBS="$old_libs" + CPPFLAGS="$old_cppflags" + LDFLAGS="$old_ldflags" + + + apu_have_commoncrypto=0 + commoncrypto_have_headers=0 + commoncrypto_have_libs=0 + + old_libs="$LIBS" + old_cppflags="$CPPFLAGS" + old_ldflags="$LDFLAGS" + + +# Check whether --with-commoncrypto was given. +if test "${with_commoncrypto+set}" = set; then : + withval=$with_commoncrypto; + if test "$withval" = "yes"; then + for ac_header in CommonCrypto/CommonKeyDerivation.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "CommonCrypto/CommonKeyDerivation.h" "ac_cv_header_CommonCrypto_CommonKeyDerivation_h" "$ac_includes_default" +if test "x$ac_cv_header_CommonCrypto_CommonKeyDerivation_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COMMONCRYPTO_COMMONKEYDERIVATION_H 1 +_ACEOF + commoncrypto_have_headers=1 +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CCKeyDerivationPBKDF in -lSystem" >&5 +$as_echo_n "checking for CCKeyDerivationPBKDF in -lSystem... " >&6; } +if ${ac_cv_lib_System_CCKeyDerivationPBKDF+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSystem $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 CCKeyDerivationPBKDF (); +int +main () +{ +return CCKeyDerivationPBKDF (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_System_CCKeyDerivationPBKDF=yes +else + ac_cv_lib_System_CCKeyDerivationPBKDF=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_System_CCKeyDerivationPBKDF" >&5 +$as_echo "$ac_cv_lib_System_CCKeyDerivationPBKDF" >&6; } +if test "x$ac_cv_lib_System_CCKeyDerivationPBKDF" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CCCryptorCreate in -lSystem" >&5 +$as_echo_n "checking for CCCryptorCreate in -lSystem... " >&6; } +if ${ac_cv_lib_System_CCCryptorCreate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSystem -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 CCCryptorCreate (); +int +main () +{ +return CCCryptorCreate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_System_CCCryptorCreate=yes +else + ac_cv_lib_System_CCCryptorCreate=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_System_CCCryptorCreate" >&5 +$as_echo "$ac_cv_lib_System_CCCryptorCreate" >&6; } +if test "x$ac_cv_lib_System_CCCryptorCreate" = xyes; then : + commoncrypto_have_libs=1 +fi + +fi + + if test "$commoncrypto_have_headers" != "0" && test "$commoncrypto_have_libs" != "0"; then + apu_have_commoncrypto=1 + fi + elif test "$withval" = "no"; then + apu_have_commoncrypto=0 + else + + commoncrypto_CPPFLAGS="-I$withval/include" + commoncrypto_LDFLAGS="-L$withval/lib " + + + if test "x$CPPFLAGS" = "x"; then + test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"$commoncrypto_CPPFLAGS\"" + CPPFLAGS="$commoncrypto_CPPFLAGS" + else + apr_addto_bugger="$commoncrypto_CPPFLAGS" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $CPPFLAGS; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" + CPPFLAGS="$CPPFLAGS $i" + fi + done + fi + + + if test "x$LDFLAGS" = "x"; then + test "x$silent" != "xyes" && echo " setting LDFLAGS to \"$commoncrypto_LDFLAGS\"" + LDFLAGS="$commoncrypto_LDFLAGS" + else + apr_addto_bugger="$commoncrypto_LDFLAGS" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $LDFLAGS; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to LDFLAGS" + LDFLAGS="$LDFLAGS $i" + fi + done + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for commoncrypto in $withval" >&5 +$as_echo "$as_me: checking for commoncrypto in $withval" >&6;} + for ac_header in CommonCrypto/CommonKeyDerivation.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "CommonCrypto/CommonKeyDerivation.h" "ac_cv_header_CommonCrypto_CommonKeyDerivation_h" "$ac_includes_default" +if test "x$ac_cv_header_CommonCrypto_CommonKeyDerivation_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COMMONCRYPTO_COMMONKEYDERIVATION_H 1 +_ACEOF + commoncrypto_have_headers=1 +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CCKeyDerivationPBKDF in -lSystem" >&5 +$as_echo_n "checking for CCKeyDerivationPBKDF in -lSystem... " >&6; } +if ${ac_cv_lib_System_CCKeyDerivationPBKDF+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSystem $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 CCKeyDerivationPBKDF (); +int +main () +{ +return CCKeyDerivationPBKDF (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_System_CCKeyDerivationPBKDF=yes +else + ac_cv_lib_System_CCKeyDerivationPBKDF=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_System_CCKeyDerivationPBKDF" >&5 +$as_echo "$ac_cv_lib_System_CCKeyDerivationPBKDF" >&6; } +if test "x$ac_cv_lib_System_CCKeyDerivationPBKDF" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CCCryptorCreate in -lSystem" >&5 +$as_echo_n "checking for CCCryptorCreate in -lSystem... " >&6; } +if ${ac_cv_lib_System_CCCryptorCreate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSystem -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 CCCryptorCreate (); +int +main () +{ +return CCCryptorCreate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_System_CCCryptorCreate=yes +else + ac_cv_lib_System_CCCryptorCreate=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_System_CCCryptorCreate" >&5 +$as_echo "$ac_cv_lib_System_CCCryptorCreate" >&6; } +if test "x$ac_cv_lib_System_CCCryptorCreate" = xyes; then : + commoncrypto_have_libs=1 +fi + +fi + + if test "$commoncrypto_have_headers" != "0" && test "$commoncrypto_have_libs" != "0"; then + apu_have_commoncrypto=1 + + if test "x$LDFLAGS" = "x"; then + test "x$silent" != "xyes" && echo " setting LDFLAGS to \"-L$withval/lib\"" + LDFLAGS="-L$withval/lib" + else + apr_addto_bugger="-L$withval/lib" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $LDFLAGS; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to LDFLAGS" + LDFLAGS="$LDFLAGS $i" + fi + done + fi + + + if test "x$INCLUDES" = "x"; then + test "x$silent" != "xyes" && echo " setting INCLUDES to \"-I$withval/include\"" + INCLUDES="-I$withval/include" + else + apr_addto_bugger="-I$withval/include" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $INCLUDES; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to INCLUDES" + INCLUDES="$INCLUDES $i" + fi + done + fi + + fi + + fi + +else + + apu_have_commoncrypto=0 + +fi + + + if test "$apu_have_commoncrypto" = "1"; then + apu_have_crypto=1 + fi + + + + LIBS="$old_libs" CPPFLAGS="$old_cppflags" LDFLAGS="$old_ldflags" if test "$apu_have_crypto" = "0"; then - as_fn_error $? "Crypto was requested but no crypto library could be enabled; specify the location of a crypto library using --with-openssl, --with-nss, etc." "$LINENO" 5 + as_fn_error $? "Crypto was requested but no crypto library could be enabled; specify the location of a crypto library using --with-openssl, --with-nss, and/or --with-commoncrypto." "$LINENO" 5 fi fi @@ -19946,13 +20126,13 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient_r" >&5 -$as_echo_n "checking for mysql_init in -lmysqlclient_r... " >&6; } -if ${ac_cv_lib_mysqlclient_r_mysql_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient" >&5 +$as_echo_n "checking for mysql_init in -lmysqlclient... " >&6; } +if ${ac_cv_lib_mysqlclient_mysql_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lmysqlclient_r $LIBS" +LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -19972,17 +20152,17 @@ return mysql_init (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_mysqlclient_r_mysql_init=yes + ac_cv_lib_mysqlclient_mysql_init=yes else - ac_cv_lib_mysqlclient_r_mysql_init=no + ac_cv_lib_mysqlclient_mysql_init=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_mysqlclient_r_mysql_init" >&5 -$as_echo "$ac_cv_lib_mysqlclient_r_mysql_init" >&6; } -if test "x$ac_cv_lib_mysqlclient_r_mysql_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 +$as_echo "$ac_cv_lib_mysqlclient_mysql_init" >&6; } +if test "x$ac_cv_lib_mysqlclient_mysql_init" = xyes; then : apu_have_mysql=1 fi @@ -20002,13 +20182,13 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient_r" >&5 -$as_echo_n "checking for mysql_init in -lmysqlclient_r... " >&6; } -if ${ac_cv_lib_mysqlclient_r_mysql_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient" >&5 +$as_echo_n "checking for mysql_init in -lmysqlclient... " >&6; } +if ${ac_cv_lib_mysqlclient_mysql_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lmysqlclient_r $LIBS" +LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -20028,17 +20208,17 @@ return mysql_init (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_mysqlclient_r_mysql_init=yes + ac_cv_lib_mysqlclient_mysql_init=yes else - ac_cv_lib_mysqlclient_r_mysql_init=no + ac_cv_lib_mysqlclient_mysql_init=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_mysqlclient_r_mysql_init" >&5 -$as_echo "$ac_cv_lib_mysqlclient_r_mysql_init" >&6; } -if test "x$ac_cv_lib_mysqlclient_r_mysql_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 +$as_echo "$ac_cv_lib_mysqlclient_mysql_init" >&6; } +if test "x$ac_cv_lib_mysqlclient_mysql_init" = xyes; then : apu_have_mysql=1 fi @@ -20199,13 +20379,13 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient_r" >&5 -$as_echo_n "checking for mysql_init in -lmysqlclient_r... " >&6; } -if ${ac_cv_lib_mysqlclient_r_mysql_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient" >&5 +$as_echo_n "checking for mysql_init in -lmysqlclient... " >&6; } +if ${ac_cv_lib_mysqlclient_mysql_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lmysqlclient_r $LIBS" +LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -20225,17 +20405,17 @@ return mysql_init (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_mysqlclient_r_mysql_init=yes + ac_cv_lib_mysqlclient_mysql_init=yes else - ac_cv_lib_mysqlclient_r_mysql_init=no + ac_cv_lib_mysqlclient_mysql_init=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_mysqlclient_r_mysql_init" >&5 -$as_echo "$ac_cv_lib_mysqlclient_r_mysql_init" >&6; } -if test "x$ac_cv_lib_mysqlclient_r_mysql_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 +$as_echo "$ac_cv_lib_mysqlclient_mysql_init" >&6; } +if test "x$ac_cv_lib_mysqlclient_mysql_init" = xyes; then : apu_have_mysql=1 fi @@ -20256,13 +20436,13 @@ if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient_r" >&5 -$as_echo_n "checking for mysql_init in -lmysqlclient_r... " >&6; } -if ${ac_cv_lib_mysqlclient_r_mysql_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_init in -lmysqlclient" >&5 +$as_echo_n "checking for mysql_init in -lmysqlclient... " >&6; } +if ${ac_cv_lib_mysqlclient_mysql_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lmysqlclient_r $LIBS" +LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -20282,17 +20462,17 @@ return mysql_init (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_mysqlclient_r_mysql_init=yes + ac_cv_lib_mysqlclient_mysql_init=yes else - ac_cv_lib_mysqlclient_r_mysql_init=no + ac_cv_lib_mysqlclient_mysql_init=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_mysqlclient_r_mysql_init" >&5 -$as_echo "$ac_cv_lib_mysqlclient_r_mysql_init" >&6; } -if test "x$ac_cv_lib_mysqlclient_r_mysql_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_mysql_init" >&5 +$as_echo "$ac_cv_lib_mysqlclient_mysql_init" >&6; } +if test "x$ac_cv_lib_mysqlclient_mysql_init" = xyes; then : apu_have_mysql=1 fi @@ -20336,10 +20516,10 @@ fi if test "$apu_have_mysql" = "1"; then if test "x$LDADD_dbd_mysql" = "x"; then - test "x$silent" != "xyes" && echo " setting LDADD_dbd_mysql to \"$mysql_LDFLAGS -lmysqlclient_r $mysql_LIBS\"" - LDADD_dbd_mysql="$mysql_LDFLAGS -lmysqlclient_r $mysql_LIBS" + test "x$silent" != "xyes" && echo " setting LDADD_dbd_mysql to \"$mysql_LDFLAGS -lmysqlclient $mysql_LIBS\"" + LDADD_dbd_mysql="$mysql_LDFLAGS -lmysqlclient $mysql_LIBS" else - apr_addto_bugger="$mysql_LDFLAGS -lmysqlclient_r $mysql_LIBS" + apr_addto_bugger="$mysql_LDFLAGS -lmysqlclient $mysql_LIBS" for i in $apr_addto_bugger; do apr_addto_duplicate="0" for j in $LDADD_dbd_mysql; do @@ -21549,443 +21729,6 @@ fi LDFLAGS="$old_ldflags" - apu_have_freetds=0 - - old_libs="$LIBS" - old_cppflags="$CPPFLAGS" - old_ldflags="$LDFLAGS" - - -# Check whether --with-freetds was given. -if test "${with_freetds+set}" = set; then : - withval=$with_freetds; - if test "$withval" = "yes"; then - for ac_header in sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sybdb.h" "ac_cv_header_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - if test "$apu_have_freetds" = "0"; then - for ac_header in freetds/sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "freetds/sybdb.h" "ac_cv_header_freetds_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_freetds_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FREETDS_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - fi - elif test "$withval" = "no"; then - : - else - sybdb_CPPFLAGS="-I$withval/include" - sybdb_LDFLAGS="-L$withval/lib " - - - if test "x$CPPFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"$sybdb_CPPFLAGS\"" - CPPFLAGS="$sybdb_CPPFLAGS" - else - apr_addto_bugger="$sybdb_CPPFLAGS" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $CPPFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" - CPPFLAGS="$CPPFLAGS $i" - fi - done - fi - - - if test "x$LDFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting LDFLAGS to \"$sybdb_LDFLAGS\"" - LDFLAGS="$sybdb_LDFLAGS" - else - apr_addto_bugger="$sybdb_LDFLAGS" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $LDFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to LDFLAGS" - LDFLAGS="$LDFLAGS $i" - fi - done - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetds in $withval" >&5 -$as_echo "$as_me: checking for freetds in $withval" >&6;} - for ac_header in sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sybdb.h" "ac_cv_header_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - if test "$apu_have_freetds" = "0"; then - for ac_header in freetds/sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "freetds/sybdb.h" "ac_cv_header_freetds_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_freetds_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FREETDS_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - fi - if test "$apu_have_freetds" != "0"; then - - if test "x$APRUTIL_PRIV_INCLUDES" = "x"; then - test "x$silent" != "xyes" && echo " setting APRUTIL_PRIV_INCLUDES to \"-I$withval/include\"" - APRUTIL_PRIV_INCLUDES="-I$withval/include" - else - apr_addto_bugger="-I$withval/include" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $APRUTIL_PRIV_INCLUDES; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to APRUTIL_PRIV_INCLUDES" - APRUTIL_PRIV_INCLUDES="$APRUTIL_PRIV_INCLUDES $i" - fi - done - fi - - fi - fi - -else - - for ac_header in sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sybdb.h" "ac_cv_header_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - if test "$apu_have_freetds" = "0"; then - for ac_header in freetds/sybdb.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "freetds/sybdb.h" "ac_cv_header_freetds_sybdb_h" "$ac_includes_default" -if test "x$ac_cv_header_freetds_sybdb_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FREETDS_SYBDB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdsdbopen in -lsybdb" >&5 -$as_echo_n "checking for tdsdbopen in -lsybdb... " >&6; } -if ${ac_cv_lib_sybdb_tdsdbopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsybdb $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 tdsdbopen (); -int -main () -{ -return tdsdbopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sybdb_tdsdbopen=yes -else - ac_cv_lib_sybdb_tdsdbopen=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_sybdb_tdsdbopen" >&5 -$as_echo "$ac_cv_lib_sybdb_tdsdbopen" >&6; } -if test "x$ac_cv_lib_sybdb_tdsdbopen" = xyes; then : - apu_have_freetds=1 -fi - -fi - -done - - fi - -fi - - - - - if test "$apu_have_freetds" = "1"; then - - if test "x$LDADD_dbd_freetds" = "x"; then - test "x$silent" != "xyes" && echo " setting LDADD_dbd_freetds to \"$sybdb_LDFLAGS -lsybdb\"" - LDADD_dbd_freetds="$sybdb_LDFLAGS -lsybdb" - else - apr_addto_bugger="$sybdb_LDFLAGS -lsybdb" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $LDADD_dbd_freetds; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to LDADD_dbd_freetds" - LDADD_dbd_freetds="$LDADD_dbd_freetds $i" - fi - done - fi - - fi - - - LIBS="$old_libs" - CPPFLAGS="$old_cppflags" - LDFLAGS="$old_ldflags" - - apu_have_odbc=0 old_libs="$LIBS" @@ -22765,7 +22508,6 @@ fi test $apu_have_mysql = 1 && apu_dbd_tests="$apu_dbd_tests mysql" test $apu_have_sqlite2 = 1 && apu_dbd_tests="$apu_dbd_tests sqlite2" test $apu_have_sqlite3 = 1 && apu_dbd_tests="$apu_dbd_tests sqlite3" - test $apu_have_freetds = 1 && apu_dbd_tests="$apu_dbd_tests freetds" test $apu_have_odbc = 1 && apu_dbd_tests="$apu_dbd_tests odbc" @@ -22776,9 +22518,7 @@ save_ldflags="$LDFLAGS" apu_has_expat=0 -# Default: will use either external or bundled expat. apu_try_external_expat=1 -apu_try_builtin_expat=1 # Check whether --with-expat was given. @@ -22788,8 +22528,6 @@ if test "${with_expat+set}" = set; then : as_fn_error $? "a directory must be specified for --with-expat" "$LINENO" 5 elif test "$withval" = "no"; then as_fn_error $? "Expat cannot be disabled (at this time)" "$LINENO" 5 - elif test "$withval" = "builtin"; then - apu_try_external_expat=0 else # Add given path to standard search paths if appropriate: if test "$withval" != "/usr"; then @@ -22878,8 +22616,6 @@ if test "${with_expat+set}" = set; then : fi fi - # ...and refuse to fall back on the builtin expat. - apu_try_builtin_expat=0 fi fi @@ -23258,196 +22994,6 @@ fi fi -if test "${apu_has_expat}${apu_try_builtin_expat}" = "01"; then - bundled_subdir="xml/expat" - - # save our work to this point; this allows the sub-package to use it - cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - - echo "configuring package in $bundled_subdir now" - ac_popdir=`pwd` - apr_config_subdirs="$bundled_subdir" - test -d $bundled_subdir || $mkdir_p $bundled_subdir - ac_abs_srcdir=`(cd $srcdir/$bundled_subdir && pwd)` - cd $bundled_subdir - - # A "../" for each directory in /$config_subdirs. - ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` - - # Make the cache file pathname absolute for the subdirs - # required to correctly handle subdirs that might actually - # be symlinks - case "$cache_file" in - /*) # already absolute - ac_sub_cache_file=$cache_file ;; - *) # Was relative path. - ac_sub_cache_file="$ac_popdir/$cache_file" ;; - esac - - apr_configure_args=$ac_configure_args - - test "x$silent" = "xyes" && apr_configure_args="$apr_configure_args --silent" - - apr_configure_args="--disable-option-checking $apr_configure_args" - - if eval $SHELL $ac_abs_srcdir/configure $apr_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir - then : - echo "$bundled_subdir configured properly" - else - echo "configure failed for $bundled_subdir" - exit 1 - fi - - cd $ac_popdir - - # grab any updates from the sub-package - if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - - - - if test "x$APRUTIL_INCLUDES" = "x"; then - test "x$silent" != "xyes" && echo " setting APRUTIL_INCLUDES to \"-I$abs_srcdir/$bundled_subdir/lib\"" - APRUTIL_INCLUDES="-I$abs_srcdir/$bundled_subdir/lib" - else - apr_addto_bugger="-I$abs_srcdir/$bundled_subdir/lib" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $APRUTIL_INCLUDES; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to APRUTIL_INCLUDES" - APRUTIL_INCLUDES="$APRUTIL_INCLUDES $i" - fi - done - fi - - - if test "x$LDFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting LDFLAGS to \"-L$top_builddir/$bundled_subdir/lib\"" - LDFLAGS="-L$top_builddir/$bundled_subdir/lib" - else - apr_addto_bugger="-L$top_builddir/$bundled_subdir/lib" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $LDFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to LDFLAGS" - LDFLAGS="$LDFLAGS $i" - fi - done - fi - - apu_expat_libs="$top_builddir/$bundled_subdir/libexpat.la" -fi - if test "x$APRUTIL_EXPORT_LIBS" = "x"; then test "x$silent" != "xyes" && echo " setting APRUTIL_EXPORT_LIBS to \"$apu_expat_libs\"" @@ -23491,9 +23037,6 @@ fi fi -APR_XML_DIR=$bundled_subdir - - CPPFLAGS=$save_cppflags LDFLAGS=$save_ldflags @@ -24037,12 +23580,12 @@ $as_echo "$apu_cv_aprdso" >&6; } objs= test $apu_have_openssl = 1 && objs="$objs crypto/apr_crypto_openssl.lo" test $apu_have_nss = 1 && objs="$objs crypto/apr_crypto_nss.lo" + test $apu_have_commoncrypto = 1 && objs="$objs crypto/apr_crypto_commoncrypto.lo" test $apu_have_oracle = 1 && objs="$objs dbd/apr_dbd_oracle.lo" test $apu_have_pgsql = 1 && objs="$objs dbd/apr_dbd_pgsql.lo" test $apu_have_mysql = 1 && objs="$objs dbd/apr_dbd_mysql.lo" test $apu_have_sqlite2 = 1 && objs="$objs dbd/apr_dbd_sqlite2.lo" test $apu_have_sqlite3 = 1 && objs="$objs dbd/apr_dbd_sqlite3.lo" - test $apu_have_freetds = 1 && objs="$objs dbd/apr_dbd_freetds.lo" test $apu_have_odbc = 1 && objs="$objs dbd/apr_dbd_odbc.lo" test $apu_have_db = 1 && objs="$objs dbm/apr_dbm_berkeleydb.lo" test $apu_have_gdbm = 1 && objs="$objs dbm/apr_dbm_gdbm.lo" @@ -24066,12 +23609,12 @@ $as_echo "$apu_cv_aprdso" >&6; } done fi - APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss" - APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_freetds $LDADD_dbd_odbc" + APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss $LDADD_crypto_commoncrypto" + APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_odbc" APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_dbm_db $LDADD_dbm_gdbm $LDADD_dbm_ndbm" APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_ldap" - APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss" - APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_freetds $LDADD_dbd_odbc" + APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss $LDADD_crypto_commoncrypto" + APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_odbc" APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_dbm_db $LDADD_dbm_gdbm $LDADD_dbm_ndbm" APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_ldap" @@ -24081,12 +23624,12 @@ $as_echo "$apu_cv_aprdso" >&6; } dsos= test $apu_have_openssl = 1 && dsos="$dsos crypto/apr_crypto_openssl.la" test $apu_have_nss = 1 && dsos="$dsos crypto/apr_crypto_nss.la" + test $apu_have_commoncrypto = 1 && dsos="$dsos crypto/apr_crypto_commoncrypto.la" test $apu_have_oracle = 1 && dsos="$dsos dbd/apr_dbd_oracle.la" test $apu_have_pgsql = 1 && dsos="$dsos dbd/apr_dbd_pgsql.la" test $apu_have_mysql = 1 && dsos="$dsos dbd/apr_dbd_mysql.la" test $apu_have_sqlite2 = 1 && dsos="$dsos dbd/apr_dbd_sqlite2.la" test $apu_have_sqlite3 = 1 && dsos="$dsos dbd/apr_dbd_sqlite3.la" - test $apu_have_freetds = 1 && dsos="$dsos dbd/apr_dbd_freetds.la" test $apu_have_odbc = 1 && dsos="$dsos dbd/apr_dbd_odbc.la" test $apu_have_db = 1 && dsos="$dsos dbm/apr_dbm_db.la" test $apu_have_gdbm = 1 && dsos="$dsos dbm/apr_dbm_gdbm.la" @@ -24247,6 +23790,131 @@ fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler handles weak symbols" >&5 +$as_echo_n "checking whether the compiler handles weak symbols... " >&6; } +if ${apu_cv_weak_symbols+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + apu_cv_weak_symbols=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +__attribute__ ((weak)) +int weak_noop(void) +{ + return 0; +} +int main() +{ + return weak_noop(); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + apu_cv_weak_symbols=yes +else + apu_cv_weak_symbols=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $apu_cv_weak_symbols" >&5 +$as_echo "$apu_cv_weak_symbols" >&6; } + +if test "$apu_cv_weak_symbols" = "yes"; then + +$as_echo "#define HAVE_WEAK_SYMBOLS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memset_s support" >&5 +$as_echo_n "checking for memset_s support... " >&6; } +if ${apu_cv_memset_s+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + apu_cv_memset_s=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_STRING_H +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#endif + +int main(int argc, const char **argv) +{ + char buf[1] = {1}; + return memset_s(buf, sizeof buf, 0, sizeof buf) != 0 || *buf != '\0'; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + apu_cv_memset_s=yes +else + apu_cv_memset_s=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $apu_cv_memset_s" >&5 +$as_echo "$apu_cv_memset_s" >&6; } + +if test "$apu_cv_memset_s" = "yes"; then + +$as_echo "#define HAVE_MEMSET_S 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for explicit_bzero support" >&5 +$as_echo_n "checking for explicit_bzero support... " >&6; } +if ${apu_cv_explicit_bzero+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + apu_cv_explicit_bzero=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif + +int main(int argc, const char **argv) +{ + char buf[1] = {1}; + explicit_bzero(buf, sizeof buf); + return *buf != '\0'; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + apu_cv_explicit_bzero=yes +else + apu_cv_explicit_bzero=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $apu_cv_explicit_bzero" >&5 +$as_echo "$apu_cv_explicit_bzero" >&6; } + +if test "$apu_cv_explicit_bzero" = "yes"; then + +$as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h + +fi + so_ext=$APR_SO_EXT lib_target=$APR_LIB_TARGET diff --git a/contrib/apr-util/configure.in b/contrib/apr-util/configure.in index 30028102e460..6f9755a6f24d 100644 --- a/contrib/apr-util/configure.in +++ b/contrib/apr-util/configure.in @@ -165,7 +165,6 @@ APU_CHECK_DBD_MYSQL APU_CHECK_DBD_SQLITE3 APU_CHECK_DBD_SQLITE2 APU_CHECK_DBD_ORACLE -APU_CHECK_DBD_FREETDS APU_CHECK_DBD_ODBC APU_FIND_EXPAT APU_FIND_ICONV @@ -188,6 +187,59 @@ if test "$crypt_r" = "1"; then APU_CHECK_CRYPT_R_STYLE fi +AC_CACHE_CHECK([whether the compiler handles weak symbols], [apu_cv_weak_symbols], +[AC_TRY_RUN([ +__attribute__ ((weak)) +int weak_noop(void) +{ + return 0; +} +int main() +{ + return weak_noop(); +}], [apu_cv_weak_symbols=yes], [apu_cv_weak_symbols=no], [apu_cv_weak_symbols=no])]) + +if test "$apu_cv_weak_symbols" = "yes"; then + AC_DEFINE(HAVE_WEAK_SYMBOLS, 1, [Define if compiler handles weak symbols]) +fi + +AC_CACHE_CHECK([for memset_s support], [apu_cv_memset_s], +[AC_TRY_RUN([ +#ifdef HAVE_STRING_H +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#endif + +int main(int argc, const char **argv) +{ + char buf[1] = {1}; + return memset_s(buf, sizeof buf, 0, sizeof buf) != 0 || *buf != '\0'; +}], [apu_cv_memset_s=yes], [apu_cv_memset_s=no], [apu_cv_memset_s=no])]) + +if test "$apu_cv_memset_s" = "yes"; then + AC_DEFINE([HAVE_MEMSET_S], 1, [Define if memset_s function is supported]) +fi + +AC_CACHE_CHECK([for explicit_bzero support], [apu_cv_explicit_bzero], +[AC_TRY_RUN([ +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif + +int main(int argc, const char **argv) +{ + char buf[1] = {1}; + explicit_bzero(buf, sizeof buf); + return *buf != '\0'; +}], [apu_cv_explicit_bzero=yes], [apu_cv_explicit_bzero=no], [apu_cv_explicit_bzero=no])]) + +if test "$apu_cv_explicit_bzero" = "yes"; then + AC_DEFINE([HAVE_EXPLICIT_BZERO], 1, [Define if explicit_bzero function is supported]) +fi + so_ext=$APR_SO_EXT lib_target=$APR_LIB_TARGET AC_SUBST(so_ext) diff --git a/contrib/apr-util/crypto/apr_crypto.c b/contrib/apr-util/crypto/apr_crypto.c index fe66582d124f..9e6e0beebec6 100644 --- a/contrib/apr-util/crypto/apr_crypto.c +++ b/contrib/apr-util/crypto/apr_crypto.c @@ -120,7 +120,7 @@ static apr_status_t crypto_clear(void *ptr) { apr_crypto_clear_t *clear = (apr_crypto_clear_t *)ptr; - memset(clear->buffer, 0, clear->size); + apr_crypto_memzero(clear->buffer, clear->size); clear->buffer = NULL; clear->size = 0; @@ -141,6 +141,53 @@ APU_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool, return APR_SUCCESS; } +#if defined(HAVE_WEAK_SYMBOLS) +void apr__memzero_explicit(void *buffer, apr_size_t size); + +__attribute__ ((weak)) +void apr__memzero_explicit(void *buffer, apr_size_t size) +{ + memset(buffer, 0, size); +} +#endif + +APU_DECLARE(apr_status_t) apr_crypto_memzero(void *buffer, apr_size_t size) +{ +#if defined(WIN32) + SecureZeroMemory(buffer, size); +#elif defined(HAVE_MEMSET_S) + if (size) { + return memset_s(buffer, (rsize_t)size, 0, (rsize_t)size); + } +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(buffer, size); +#elif defined(HAVE_WEAK_SYMBOLS) + apr__memzero_explicit(buffer, size); +#else + apr_size_t i; + volatile unsigned char *volatile ptr = buffer; + for (i = 0; i < size; ++i) { + ptr[i] = 0; + } +#endif + return APR_SUCCESS; +} + +APU_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2, + apr_size_t size) +{ + const unsigned char *p1 = buf1; + const unsigned char *p2 = buf2; + unsigned char diff = 0; + apr_size_t i; + + for (i = 0; i < size; ++i) { + diff |= p1[i] ^ p2[i]; + } + + return 1 & ((diff - 1) >> 8); +} + APU_DECLARE(apr_status_t) apr_crypto_get_driver( const apr_crypto_driver_t **driver, const char *name, const char *params, const apu_err_t **result, apr_pool_t *pool) @@ -188,12 +235,15 @@ APU_DECLARE(apr_status_t) apr_crypto_get_driver( apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name); rv = apu_dso_load(&dso, &symbol, modname, symname, pool); if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */ - *driver = symbol; - name = apr_pstrdup(pool, name); - apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver); + apr_crypto_driver_t *d = symbol; rv = APR_SUCCESS; - if ((*driver)->init) { - rv = (*driver)->init(pool, params, result); + if (d->init) { + rv = d->init(pool, params, result); + } + if (APR_SUCCESS == rv) { + *driver = symbol; + name = apr_pstrdup(pool, name); + apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver); } } apu_dso_mutex_unlock(); @@ -223,6 +273,11 @@ APU_DECLARE(apr_status_t) apr_crypto_get_driver( DRIVER_LOAD("nss", apr_crypto_nss_driver, pool, params, rv, result); } #endif +#if APU_HAVE_COMMONCRYPTO + if (name[0] == 'c' && !strcmp(name, "commoncrypto")) { + DRIVER_LOAD("commoncrypto", apr_crypto_commoncrypto_driver, pool, params, rv, result); + } +#endif #if APU_HAVE_MSCAPI if (name[0] == 'm' && !strcmp(name, "mscapi")) { DRIVER_LOAD("mscapi", apr_crypto_mscapi_driver, pool, params, rv, result); @@ -287,7 +342,8 @@ APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f, /** * @brief Get a hash table of key types, keyed by the name of the type against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_type_t, which in turn begins with an + * integer. * * @param types - hashtable of key types keyed to constants. * @param f - encryption context @@ -301,7 +357,8 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types, /** * @brief Get a hash table of key modes, keyed by the name of the mode against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_mode_t, which in turn begins with an + * integer. * * @param modes - hashtable of key modes keyed to constants. * @param f - encryption context @@ -313,6 +370,28 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes, return f->provider->get_block_key_modes(modes, f); } +/** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +APU_DECLARE(apr_status_t) apr_crypto_key(apr_crypto_key_t **key, + const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p) +{ + return f->provider->key(key, rec, f, p); +} + /** * @brief Create a key from the given passphrase. By default, the PBKDF2 * algorithm is used to generate the key from the passphrase. It is expected diff --git a/contrib/apr-util/crypto/apr_crypto_commoncrypto.c b/contrib/apr-util/crypto/apr_crypto_commoncrypto.c new file mode 100644 index 000000000000..81b02995843e --- /dev/null +++ b/contrib/apr-util/crypto/apr_crypto_commoncrypto.c @@ -0,0 +1,906 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apu.h" +#include "apu_errno.h" + +#include +#include +#include + +#include "apr_strings.h" +#include "apr_time.h" +#include "apr_buckets.h" +#include "apr_random.h" + +#include "apr_crypto_internal.h" + +#if APU_HAVE_CRYPTO + +#include + +#define LOG_PREFIX "apr_crypto_commoncrypto: " + +struct apr_crypto_t +{ + apr_pool_t *pool; + const apr_crypto_driver_t *provider; + apu_err_t *result; + apr_hash_t *types; + apr_hash_t *modes; + apr_random_t *rng; +}; + +struct apr_crypto_key_t +{ + apr_pool_t *pool; + const apr_crypto_driver_t *provider; + const apr_crypto_t *f; + CCAlgorithm algorithm; + CCOptions options; + unsigned char *key; + int keyLen; + int ivSize; + apr_size_t blockSize; +}; + +struct apr_crypto_block_t +{ + apr_pool_t *pool; + const apr_crypto_driver_t *provider; + const apr_crypto_t *f; + const apr_crypto_key_t *key; + CCCryptorRef ref; +}; + +static struct apr_crypto_block_key_type_t key_types[] = +{ +{ APR_KEY_3DES_192, 24, 8, 8 }, +{ APR_KEY_AES_128, 16, 16, 16 }, +{ APR_KEY_AES_192, 24, 16, 16 }, +{ APR_KEY_AES_256, 32, 16, 16 } }; + +static struct apr_crypto_block_key_mode_t key_modes[] = +{ +{ APR_MODE_ECB }, +{ APR_MODE_CBC } }; + +/** + * Fetch the most recent error from this driver. + */ +static apr_status_t crypto_error(const apu_err_t **result, + const apr_crypto_t *f) +{ + *result = f->result; + return APR_SUCCESS; +} + +/** + * Shutdown the crypto library and release resources. + */ +static apr_status_t crypto_shutdown(void) +{ + return APR_SUCCESS; +} + +static apr_status_t crypto_shutdown_helper(void *data) +{ + return crypto_shutdown(); +} + +/** + * Initialise the crypto library and perform one time initialisation. + */ +static apr_status_t crypto_init(apr_pool_t *pool, const char *params, + const apu_err_t **result) +{ + + apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper, + apr_pool_cleanup_null); + + return APR_SUCCESS; +} + +/** + * @brief Clean encryption / decryption context. + * @note After cleanup, a context is free to be reused if necessary. + * @param ctx The block context to use. + * @return Returns APR_ENOTIMPL if not supported. + */ +static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx) +{ + + if (ctx->ref) { + CCCryptorRelease(ctx->ref); + ctx->ref = NULL; + } + + return APR_SUCCESS; + +} + +static apr_status_t crypto_block_cleanup_helper(void *data) +{ + apr_crypto_block_t *block = (apr_crypto_block_t *) data; + return crypto_block_cleanup(block); +} + +/** + * @brief Clean encryption / decryption context. + * @note After cleanup, a context is free to be reused if necessary. + * @param f The context to use. + * @return Returns APR_ENOTIMPL if not supported. + */ +static apr_status_t crypto_cleanup(apr_crypto_t *f) +{ + + return APR_SUCCESS; + +} + +static apr_status_t crypto_cleanup_helper(void *data) +{ + apr_crypto_t *f = (apr_crypto_t *) data; + return crypto_cleanup(f); +} + +/** + * @brief Create a context for supporting encryption. Keys, certificates, + * algorithms and other parameters will be set per context. More than + * one context can be created at one time. A cleanup will be automatically + * registered with the given pool to guarantee a graceful shutdown. + * @param f - context pointer will be written here + * @param provider - provider to use + * @param params - array of key parameters + * @param pool - process pool + * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE + * if the engine cannot be initialised. + */ +static apr_status_t crypto_make(apr_crypto_t **ff, + const apr_crypto_driver_t *provider, const char *params, + apr_pool_t *pool) +{ + apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t)); + apr_status_t rv; + + if (!f) { + return APR_ENOMEM; + } + *ff = f; + f->pool = pool; + f->provider = provider; + + /* seed the secure random number generator */ + f->rng = apr_random_standard_new(pool); + if (!f->rng) { + return APR_ENOMEM; + } + do { + unsigned char seed[8]; + rv = apr_generate_random_bytes(seed, sizeof(seed)); + if (rv != APR_SUCCESS) { + return rv; + } + apr_random_add_entropy(f->rng, seed, sizeof(seed)); + rv = apr_random_secure_ready(f->rng); + } while (rv == APR_ENOTENOUGHENTROPY); + + f->result = apr_pcalloc(pool, sizeof(apu_err_t)); + if (!f->result) { + return APR_ENOMEM; + } + + f->types = apr_hash_make(pool); + if (!f->types) { + return APR_ENOMEM; + } + apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_types[0])); + apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_types[1])); + apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_types[2])); + apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_types[3])); + + f->modes = apr_hash_make(pool); + if (!f->modes) { + return APR_ENOMEM; + } + apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(key_modes[0])); + apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(key_modes[1])); + + apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, + apr_pool_cleanup_null); + + return APR_SUCCESS; + +} + +/** + * @brief Get a hash table of key types, keyed by the name of the type against + * a pointer to apr_crypto_block_key_type_t. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_types(apr_hash_t **types, + const apr_crypto_t *f) +{ + *types = f->types; + return APR_SUCCESS; +} + +/** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * a pointer to apr_crypto_block_key_mode_t. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, + const apr_crypto_t *f) +{ + *modes = f->modes; + return APR_SUCCESS; +} + +/* + * Work out which mechanism to use. + */ +static apr_status_t crypto_cipher_mechanism(apr_crypto_key_t *key, + const apr_crypto_block_key_type_e type, + const apr_crypto_block_key_mode_e mode, const int doPad, apr_pool_t *p) +{ + /* handle padding */ + key->options = doPad ? kCCOptionPKCS7Padding : 0; + + /* determine the algorithm to be used */ + switch (type) { + + case (APR_KEY_3DES_192): + + /* A 3DES key */ + if (mode == APR_MODE_CBC) { + key->algorithm = kCCAlgorithm3DES; + key->keyLen = kCCKeySize3DES; + key->ivSize = kCCBlockSize3DES; + key->blockSize = kCCBlockSize3DES; + } + else { + key->algorithm = kCCAlgorithm3DES; + key->options += kCCOptionECBMode; + key->keyLen = kCCKeySize3DES; + key->ivSize = 0; + key->blockSize = kCCBlockSize3DES; + } + break; + + case (APR_KEY_AES_128): + + if (mode == APR_MODE_CBC) { + key->algorithm = kCCAlgorithmAES128; + key->keyLen = kCCKeySizeAES128; + key->ivSize = kCCBlockSizeAES128; + key->blockSize = kCCBlockSizeAES128; + } + else { + key->algorithm = kCCAlgorithmAES128; + key->options += kCCOptionECBMode; + key->keyLen = kCCKeySizeAES128; + key->ivSize = 0; + key->blockSize = kCCBlockSizeAES128; + } + break; + + case (APR_KEY_AES_192): + + if (mode == APR_MODE_CBC) { + key->algorithm = kCCAlgorithmAES128; + key->keyLen = kCCKeySizeAES192; + key->ivSize = kCCBlockSizeAES128; + key->blockSize = kCCBlockSizeAES128; + } + else { + key->algorithm = kCCAlgorithmAES128; + key->options += kCCOptionECBMode; + key->keyLen = kCCKeySizeAES192; + key->ivSize = 0; + key->blockSize = kCCBlockSizeAES128; + } + break; + + case (APR_KEY_AES_256): + + if (mode == APR_MODE_CBC) { + key->algorithm = kCCAlgorithmAES128; + key->keyLen = kCCKeySizeAES256; + key->ivSize = kCCBlockSizeAES128; + key->blockSize = kCCBlockSizeAES128; + } + else { + key->algorithm = kCCAlgorithmAES128; + key->options += kCCOptionECBMode; + key->keyLen = kCCKeySizeAES256; + key->ivSize = 0; + key->blockSize = kCCBlockSizeAES128; + } + break; + + default: + + /* TODO: Support CAST, Blowfish */ + + /* unknown key type, give up */ + return APR_EKEYTYPE; + + } + + /* make space for the key */ + key->key = apr_palloc(p, key->keyLen); + if (!key->key) { + return APR_ENOMEM; + } + apr_crypto_clear(p, key->key, key->keyLen); + + return APR_SUCCESS; +} + +/** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_key(apr_crypto_key_t **k, + const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p) +{ + apr_status_t rv; + apr_crypto_key_t *key = *k; + + if (!key) { + *k = key = apr_pcalloc(p, sizeof *key); + } + if (!key) { + return APR_ENOMEM; + } + + key->f = f; + key->provider = f->provider; + + /* decide on what cipher mechanism we will be using */ + rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p); + if (APR_SUCCESS != rv) { + return rv; + } + + switch (rec->ktype) { + + case APR_CRYPTO_KTYPE_PASSPHRASE: { + + /* generate the key */ + if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2, + rec->k.passphrase.pass, rec->k.passphrase.passLen, + rec->k.passphrase.salt, rec->k.passphrase.saltLen, + kCCPRFHmacAlgSHA1, rec->k.passphrase.iterations, key->key, + key->keyLen)) == kCCParamError) { + return APR_ENOKEY; + } + + break; + } + + case APR_CRYPTO_KTYPE_SECRET: { + + /* sanity check - key correct size? */ + if (rec->k.secret.secretLen != key->keyLen) { + return APR_EKEYLENGTH; + } + + /* copy the key */ + memcpy(key->key, rec->k.secret.secret, rec->k.secret.secretLen); + + break; + } + + default: { + + return APR_ENOKEY; + + } + } + + return APR_SUCCESS; +} + +/** + * @brief Create a key from the given passphrase. By default, the PBKDF2 + * algorithm is used to generate the key from the passphrase. It is expected + * that the same pass phrase will generate the same key, regardless of the + * backend crypto platform used. The key is cleaned up when the context + * is cleaned, and may be reused with multiple encryption or decryption + * operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param ivSize The size of the initialisation vector will be returned, based + * on whether an IV is relevant for this type of crypto. + * @param pass The passphrase to use. + * @param passLen The passphrase length in bytes + * @param salt The salt to use. + * @param saltLen The salt length in bytes + * @param type 3DES_192, AES_128, AES_192, AES_256. + * @param mode Electronic Code Book / Cipher Block Chaining. + * @param doPad Pad if necessary. + * @param iterations Iteration count + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, + const char *pass, apr_size_t passLen, const unsigned char * salt, + apr_size_t saltLen, const apr_crypto_block_key_type_e type, + const apr_crypto_block_key_mode_e mode, const int doPad, + const int iterations, const apr_crypto_t *f, apr_pool_t *p) +{ + apr_status_t rv; + apr_crypto_key_t *key = *k; + + if (!key) { + *k = key = apr_pcalloc(p, sizeof *key); + if (!key) { + return APR_ENOMEM; + } + } + + key->f = f; + key->provider = f->provider; + + /* decide on what cipher mechanism we will be using */ + rv = crypto_cipher_mechanism(key, type, mode, doPad, p); + if (APR_SUCCESS != rv) { + return rv; + } + + /* generate the key */ + if ((f->result->rc = CCKeyDerivationPBKDF(kCCPBKDF2, pass, passLen, salt, + saltLen, kCCPRFHmacAlgSHA1, iterations, key->key, key->keyLen)) + == kCCParamError) { + return APR_ENOKEY; + } + + if (ivSize) { + *ivSize = key->ivSize; + } + + return APR_SUCCESS; +} + +/** + * @brief Initialise a context for encrypting arbitrary data using the given key. + * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If + * *ctx is not NULL, *ctx must point at a previously created structure. + * @param ctx The block context returned, see note. + * @param iv Optional initialisation vector. If the buffer pointed to is NULL, + * an IV will be created at random, in space allocated from the pool. + * If the buffer pointed to is not NULL, the IV in the buffer will be + * used. + * @param key The key structure. + * @param blockSize The block size of the cipher. + * @param p The pool to use. + * @return Returns APR_ENOIV if an initialisation vector is required but not specified. + * Returns APR_EINIT if the backend failed to initialise the context. Returns + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, + const unsigned char **iv, const apr_crypto_key_t *key, + apr_size_t *blockSize, apr_pool_t *p) +{ + unsigned char *usedIv; + apr_crypto_block_t *block = *ctx; + if (!block) { + *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); + } + if (!block) { + return APR_ENOMEM; + } + block->f = key->f; + block->pool = p; + block->provider = key->provider; + block->key = key; + + apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper, + apr_pool_cleanup_null); + + /* generate an IV, if necessary */ + usedIv = NULL; + if (key->ivSize) { + if (iv == NULL) { + return APR_ENOIV; + } + if (*iv == NULL) { + apr_status_t status; + usedIv = apr_pcalloc(p, key->ivSize); + if (!usedIv) { + return APR_ENOMEM; + } + apr_crypto_clear(p, usedIv, key->ivSize); + status = apr_random_secure_bytes(block->f->rng, usedIv, + key->ivSize); + if (APR_SUCCESS != status) { + return status; + } + *iv = usedIv; + } + else { + usedIv = (unsigned char *) *iv; + } + } + + /* create a new context for encryption */ + switch ((block->f->result->rc = CCCryptorCreate(kCCEncrypt, key->algorithm, + key->options, key->key, key->keyLen, usedIv, &block->ref))) { + case kCCSuccess: { + break; + } + case kCCParamError: { + return APR_EINIT; + } + case kCCMemoryFailure: { + return APR_ENOMEM; + } + case kCCAlignmentError: { + return APR_EPADDING; + } + case kCCUnimplemented: { + return APR_ENOTIMPL; + } + default: { + return APR_EINIT; + } + } + + if (blockSize) { + *blockSize = key->blockSize; + } + + return APR_SUCCESS; + +} + +/** + * @brief Encrypt data provided by in, write it to out. + * @note The number of bytes written will be written to outlen. If + * out is NULL, outlen will contain the maximum size of the + * buffer needed to hold the data, including any data + * generated by apr_crypto_block_encrypt_finish below. If *out points + * to NULL, a buffer sufficiently large will be created from + * the pool provided. If *out points to a not-NULL value, this + * value will be used as a buffer instead. + * @param out Address of a buffer to which data will be written, + * see note. + * @param outlen Length of the output will be written here. + * @param in Address of the buffer to read. + * @param inlen Length of the buffer to read. + * @param ctx The block context to use. + * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if + * not implemented. + */ +static apr_status_t crypto_block_encrypt(unsigned char **out, + apr_size_t *outlen, const unsigned char *in, apr_size_t inlen, + apr_crypto_block_t *ctx) +{ + apr_size_t outl = *outlen; + unsigned char *buffer; + + /* are we after the maximum size of the out buffer? */ + if (!out) { + *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1); + return APR_SUCCESS; + } + + /* must we allocate the output buffer from a pool? */ + if (!*out) { + outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1); + buffer = apr_palloc(ctx->pool, outl); + if (!buffer) { + return APR_ENOMEM; + } + apr_crypto_clear(ctx->pool, buffer, outl); + *out = buffer; + } + + switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out), + outl, &outl))) { + case kCCSuccess: { + break; + } + case kCCBufferTooSmall: { + return APR_ENOSPACE; + } + default: { + return APR_ECRYPT; + } + } + *outlen = outl; + + return APR_SUCCESS; + +} + +/** + * @brief Encrypt final data block, write it to out. + * @note If necessary the final block will be written out after being + * padded. Typically the final block will be written to the + * same buffer used by apr_crypto_block_encrypt, offset by the + * number of bytes returned as actually written by the + * apr_crypto_block_encrypt() call. After this call, the context + * is cleaned and can be reused by apr_crypto_block_encrypt_init(). + * @param out Address of a buffer to which data will be written. This + * buffer must already exist, and is usually the same + * buffer used by apr_evp_crypt(). See note. + * @param outlen Length of the output will be written here. + * @param ctx The block context to use. + * @return APR_ECRYPT if an error occurred. + * @return APR_EPADDING if padding was enabled and the block was incorrectly + * formatted. + * @return APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_block_encrypt_finish(unsigned char *out, + apr_size_t *outlen, apr_crypto_block_t *ctx) +{ + apr_size_t len = *outlen; + + ctx->f->result->rc = CCCryptorFinal(ctx->ref, out, + CCCryptorGetOutputLength(ctx->ref, 0, 1), &len); + + /* always clean up */ + crypto_block_cleanup(ctx); + + switch (ctx->f->result->rc) { + case kCCSuccess: { + break; + } + case kCCBufferTooSmall: { + return APR_ENOSPACE; + } + case kCCAlignmentError: { + return APR_EPADDING; + } + case kCCDecodeError: { + return APR_ECRYPT; + } + default: { + return APR_ECRYPT; + } + } + *outlen = len; + + return APR_SUCCESS; + +} + +/** + * @brief Initialise a context for decrypting arbitrary data using the given key. + * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If + * *ctx is not NULL, *ctx must point at a previously created structure. + * @param ctx The block context returned, see note. + * @param blockSize The block size of the cipher. + * @param iv Optional initialisation vector. If the buffer pointed to is NULL, + * an IV will be created at random, in space allocated from the pool. + * If the buffer is not NULL, the IV in the buffer will be used. + * @param key The key structure. + * @param p The pool to use. + * @return Returns APR_ENOIV if an initialisation vector is required but not specified. + * Returns APR_EINIT if the backend failed to initialise the context. Returns + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, + apr_size_t *blockSize, const unsigned char *iv, + const apr_crypto_key_t *key, apr_pool_t *p) +{ + apr_crypto_block_t *block = *ctx; + if (!block) { + *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); + } + if (!block) { + return APR_ENOMEM; + } + block->f = key->f; + block->pool = p; + block->provider = key->provider; + + apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper, + apr_pool_cleanup_null); + + /* generate an IV, if necessary */ + if (key->ivSize) { + if (iv == NULL) { + return APR_ENOIV; + } + } + + /* create a new context for decryption */ + switch ((block->f->result->rc = CCCryptorCreate(kCCDecrypt, key->algorithm, + key->options, key->key, key->keyLen, iv, &block->ref))) { + case kCCSuccess: { + break; + } + case kCCParamError: { + return APR_EINIT; + } + case kCCMemoryFailure: { + return APR_ENOMEM; + } + case kCCAlignmentError: { + return APR_EPADDING; + } + case kCCUnimplemented: { + return APR_ENOTIMPL; + } + default: { + return APR_EINIT; + } + } + + if (blockSize) { + *blockSize = key->blockSize; + } + + return APR_SUCCESS; + +} + +/** + * @brief Decrypt data provided by in, write it to out. + * @note The number of bytes written will be written to outlen. If + * out is NULL, outlen will contain the maximum size of the + * buffer needed to hold the data, including any data + * generated by apr_crypto_block_decrypt_finish below. If *out points + * to NULL, a buffer sufficiently large will be created from + * the pool provided. If *out points to a not-NULL value, this + * value will be used as a buffer instead. + * @param out Address of a buffer to which data will be written, + * see note. + * @param outlen Length of the output will be written here. + * @param in Address of the buffer to read. + * @param inlen Length of the buffer to read. + * @param ctx The block context to use. + * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if + * not implemented. + */ +static apr_status_t crypto_block_decrypt(unsigned char **out, + apr_size_t *outlen, const unsigned char *in, apr_size_t inlen, + apr_crypto_block_t *ctx) +{ + apr_size_t outl = *outlen; + unsigned char *buffer; + + /* are we after the maximum size of the out buffer? */ + if (!out) { + *outlen = CCCryptorGetOutputLength(ctx->ref, inlen, 1); + return APR_SUCCESS; + } + + /* must we allocate the output buffer from a pool? */ + if (!*out) { + outl = CCCryptorGetOutputLength(ctx->ref, inlen, 1); + buffer = apr_palloc(ctx->pool, outl); + if (!buffer) { + return APR_ENOMEM; + } + apr_crypto_clear(ctx->pool, buffer, outl); + *out = buffer; + } + + switch ((ctx->f->result->rc = CCCryptorUpdate(ctx->ref, in, inlen, (*out), + outl, &outl))) { + case kCCSuccess: { + break; + } + case kCCBufferTooSmall: { + return APR_ENOSPACE; + } + default: { + return APR_ECRYPT; + } + } + *outlen = outl; + + return APR_SUCCESS; + +} + +/** + * @brief Decrypt final data block, write it to out. + * @note If necessary the final block will be written out after being + * padded. Typically the final block will be written to the + * same buffer used by apr_crypto_block_decrypt, offset by the + * number of bytes returned as actually written by the + * apr_crypto_block_decrypt() call. After this call, the context + * is cleaned and can be reused by apr_crypto_block_decrypt_init(). + * @param out Address of a buffer to which data will be written. This + * buffer must already exist, and is usually the same + * buffer used by apr_evp_crypt(). See note. + * @param outlen Length of the output will be written here. + * @param ctx The block context to use. + * @return APR_ECRYPT if an error occurred. + * @return APR_EPADDING if padding was enabled and the block was incorrectly + * formatted. + * @return APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_block_decrypt_finish(unsigned char *out, + apr_size_t *outlen, apr_crypto_block_t *ctx) +{ + apr_size_t len = *outlen; + + ctx->f->result->rc = CCCryptorFinal(ctx->ref, out, + CCCryptorGetOutputLength(ctx->ref, 0, 1), &len); + + /* always clean up */ + crypto_block_cleanup(ctx); + + switch (ctx->f->result->rc) { + case kCCSuccess: { + break; + } + case kCCBufferTooSmall: { + return APR_ENOSPACE; + } + case kCCAlignmentError: { + return APR_EPADDING; + } + case kCCDecodeError: { + return APR_ECRYPT; + } + default: { + return APR_ECRYPT; + } + } + *outlen = len; + + return APR_SUCCESS; + +} + +/** + * OSX Common Crypto module. + */ +APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_commoncrypto_driver = +{ + "commoncrypto", crypto_init, crypto_make, crypto_get_block_key_types, + crypto_get_block_key_modes, crypto_passphrase, + crypto_block_encrypt_init, crypto_block_encrypt, + crypto_block_encrypt_finish, crypto_block_decrypt_init, + crypto_block_decrypt, crypto_block_decrypt_finish, crypto_block_cleanup, + crypto_cleanup, crypto_shutdown, crypto_error, crypto_key +}; + +#endif diff --git a/contrib/apr-util/crypto/apr_crypto_nss.c b/contrib/apr-util/crypto/apr_crypto_nss.c index b345953de73d..47d164094614 100644 --- a/contrib/apr-util/crypto/apr_crypto_nss.c +++ b/contrib/apr-util/crypto/apr_crypto_nss.c @@ -50,7 +50,6 @@ struct apr_crypto_t { apr_pool_t *pool; const apr_crypto_driver_t *provider; apu_err_t *result; - apr_array_header_t *keys; apr_crypto_config_t *config; apr_hash_t *types; apr_hash_t *modes; @@ -68,6 +67,7 @@ struct apr_crypto_key_t { SECOidTag cipherOid; PK11SymKey *symKey; int ivSize; + int keyLength; }; struct apr_crypto_block_t { @@ -76,16 +76,24 @@ struct apr_crypto_block_t { const apr_crypto_t *f; PK11Context *ctx; apr_crypto_key_t *key; + SECItem *secParam; int blockSize; }; -static int key_3des_192 = APR_KEY_3DES_192; -static int key_aes_128 = APR_KEY_AES_128; -static int key_aes_192 = APR_KEY_AES_192; -static int key_aes_256 = APR_KEY_AES_256; +static struct apr_crypto_block_key_type_t key_types[] = +{ +{ APR_KEY_3DES_192, 24, 8, 8 }, +{ APR_KEY_AES_128, 16, 16, 16 }, +{ APR_KEY_AES_192, 24, 16, 16 }, +{ APR_KEY_AES_256, 32, 16, 16 } }; -static int mode_ecb = APR_MODE_ECB; -static int mode_cbc = APR_MODE_CBC; +static struct apr_crypto_block_key_mode_t key_modes[] = +{ +{ APR_MODE_ECB }, +{ APR_MODE_CBC } }; + +/* sufficient space to wrap a key */ +#define BUFFER_SIZE 128 /** * Fetch the most recent error from this driver. @@ -107,6 +115,8 @@ static apr_status_t crypto_shutdown(void) if (NSS_IsInitialized()) { SECStatus s = NSS_Shutdown(); if (s != SECSuccess) { + fprintf(stderr, "NSS failed to shutdown, possible leak: %d: %s", + PR_GetError(), PR_ErrorToName(s)); return APR_EINIT; } } @@ -197,9 +207,6 @@ static apr_status_t crypto_init(apr_pool_t *pool, const char *params, return APR_EREINIT; } - apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper, - apr_pool_cleanup_null); - if (keyPrefix || certPrefix || secmod) { s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags); } @@ -211,15 +218,20 @@ static apr_status_t crypto_init(apr_pool_t *pool, const char *params, } if (s != SECSuccess) { if (result) { + /* Note: all memory must be owned by the caller, in case we're unloaded */ apu_err_t *err = apr_pcalloc(pool, sizeof(apu_err_t)); err->rc = PR_GetError(); - err->msg = PR_ErrorToName(s); - err->reason = "Error during 'nss' initialisation"; + err->msg = apr_pstrdup(pool, PR_ErrorToName(s)); + err->reason = apr_pstrdup(pool, "Error during 'nss' initialisation"); *result = err; } + return APR_ECRYPT; } + apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper, + apr_pool_cleanup_null); + return APR_SUCCESS; } @@ -233,6 +245,11 @@ static apr_status_t crypto_init(apr_pool_t *pool, const char *params, static apr_status_t crypto_block_cleanup(apr_crypto_block_t *block) { + if (block->secParam) { + SECITEM_FreeItem(block->secParam, PR_TRUE); + block->secParam = NULL; + } + if (block->ctx) { PK11_DestroyContext(block->ctx, PR_TRUE); block->ctx = NULL; @@ -248,6 +265,15 @@ static apr_status_t crypto_block_cleanup_helper(void *data) return crypto_block_cleanup(block); } +static apr_status_t crypto_key_cleanup(void *data) +{ + apr_crypto_key_t *key = data; + if (key->symKey) { + PK11_FreeSymKey(key->symKey); + key->symKey = NULL; + } + return APR_SUCCESS; +} /** * @brief Clean encryption / decryption context. * @note After cleanup, a context is free to be reused if necessary. @@ -256,15 +282,6 @@ static apr_status_t crypto_block_cleanup_helper(void *data) */ static apr_status_t crypto_cleanup(apr_crypto_t *f) { - apr_crypto_key_t *key; - if (f->keys) { - while ((key = apr_array_pop(f->keys))) { - if (key->symKey) { - PK11_FreeSymKey(key->symKey); - key->symKey = NULL; - } - } - } return APR_SUCCESS; } @@ -308,23 +325,22 @@ static apr_status_t crypto_make(apr_crypto_t **ff, if (!f->result) { return APR_ENOMEM; } - f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t)); f->types = apr_hash_make(pool); if (!f->types) { return APR_ENOMEM; } - apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192)); - apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128)); - apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192)); - apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256)); + apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_types[0])); + apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_types[1])); + apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_types[2])); + apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_types[3])); f->modes = apr_hash_make(pool); if (!f->modes) { return APR_ENOMEM; } - apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb)); - apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc)); + apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(key_modes[0])); + apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(key_modes[1])); apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, apr_pool_cleanup_null); @@ -335,7 +351,7 @@ static apr_status_t crypto_make(apr_crypto_t **ff, /** * @brief Get a hash table of key types, keyed by the name of the type against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_type_t. * * @param types - hashtable of key types keyed to constants. * @param f - encryption context @@ -350,7 +366,7 @@ static apr_status_t crypto_get_block_key_types(apr_hash_t **types, /** * @brief Get a hash table of key modes, keyed by the name of the mode against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_mode_t. * * @param modes - hashtable of key modes keyed to constants. * @param f - encryption context @@ -363,6 +379,267 @@ static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, return APR_SUCCESS; } +/* + * Work out which mechanism to use. + */ +static apr_status_t crypto_cipher_mechanism(apr_crypto_key_t *key, + const apr_crypto_block_key_type_e type, + const apr_crypto_block_key_mode_e mode, const int doPad) +{ + + /* decide on what cipher mechanism we will be using */ + switch (type) { + + case (APR_KEY_3DES_192): + if (APR_MODE_CBC == mode) { + key->cipherOid = SEC_OID_DES_EDE3_CBC; + } + else if (APR_MODE_ECB == mode) { + return APR_ENOCIPHER; + /* No OID for CKM_DES3_ECB; */ + } + key->keyLength = 24; + break; + case (APR_KEY_AES_128): + if (APR_MODE_CBC == mode) { + key->cipherOid = SEC_OID_AES_128_CBC; + } + else { + key->cipherOid = SEC_OID_AES_128_ECB; + } + key->keyLength = 16; + break; + case (APR_KEY_AES_192): + if (APR_MODE_CBC == mode) { + key->cipherOid = SEC_OID_AES_192_CBC; + } + else { + key->cipherOid = SEC_OID_AES_192_ECB; + } + key->keyLength = 24; + break; + case (APR_KEY_AES_256): + if (APR_MODE_CBC == mode) { + key->cipherOid = SEC_OID_AES_256_CBC; + } + else { + key->cipherOid = SEC_OID_AES_256_ECB; + } + key->keyLength = 32; + break; + default: + /* unknown key type, give up */ + return APR_EKEYTYPE; + } + + /* AES_128_CBC --> CKM_AES_CBC --> CKM_AES_CBC_PAD */ + key->cipherMech = PK11_AlgtagToMechanism(key->cipherOid); + if (key->cipherMech == CKM_INVALID_MECHANISM) { + return APR_ENOCIPHER; + } + if (doPad) { + CK_MECHANISM_TYPE paddedMech; + paddedMech = PK11_GetPadMechanism(key->cipherMech); + if (CKM_INVALID_MECHANISM == paddedMech + || key->cipherMech == paddedMech) { + return APR_EPADDING; + } + key->cipherMech = paddedMech; + } + + key->ivSize = PK11_GetIVLength(key->cipherMech); + + return APR_SUCCESS; +} + +/** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_key(apr_crypto_key_t **k, + const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p) +{ + apr_status_t rv = APR_SUCCESS; + PK11SlotInfo *slot, *tslot; + PK11SymKey *tkey; + SECItem secretItem; + SECItem wrappedItem; + SECItem *secParam; + PK11Context *ctx; + SECStatus s; + SECItem passItem; + SECItem saltItem; + SECAlgorithmID *algid; + void *wincx = NULL; /* what is wincx? */ + apr_crypto_key_t *key; + int blockSize; + int remainder; + + key = *k; + if (!key) { + *k = key = apr_pcalloc(p, sizeof *key); + if (!key) { + return APR_ENOMEM; + } + apr_pool_cleanup_register(p, key, crypto_key_cleanup, + apr_pool_cleanup_null); + } + + key->f = f; + key->provider = f->provider; + + /* decide on what cipher mechanism we will be using */ + rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad); + if (APR_SUCCESS != rv) { + return rv; + } + + switch (rec->ktype) { + + case APR_CRYPTO_KTYPE_PASSPHRASE: { + + /* Turn the raw passphrase and salt into SECItems */ + passItem.data = (unsigned char*) rec->k.passphrase.pass; + passItem.len = rec->k.passphrase.passLen; + saltItem.data = (unsigned char*) rec->k.passphrase.salt; + saltItem.len = rec->k.passphrase.saltLen; + + /* generate the key */ + /* pbeAlg and cipherAlg are the same. */ + algid = PK11_CreatePBEV2AlgorithmID(key->cipherOid, key->cipherOid, + SEC_OID_HMAC_SHA1, key->keyLength, + rec->k.passphrase.iterations, &saltItem); + if (algid) { + slot = PK11_GetBestSlot(key->cipherMech, wincx); + if (slot) { + key->symKey = PK11_PBEKeyGen(slot, algid, &passItem, PR_FALSE, + wincx); + PK11_FreeSlot(slot); + } + SECOID_DestroyAlgorithmID(algid, PR_TRUE); + } + + break; + } + + case APR_CRYPTO_KTYPE_SECRET: { + + /* + * NSS is by default in FIPS mode, which disallows the use of unencrypted + * symmetrical keys. As per http://permalink.gmane.org/gmane.comp.mozilla.crypto/7947 + * we do the following: + * + * 1. Generate a (temporary) symmetric key in NSS. + * 2. Use that symmetric key to encrypt your symmetric key as data. + * 3. Unwrap your wrapped symmetric key, using the symmetric key + * you generated in Step 1 as the unwrapping key. + * + * http://permalink.gmane.org/gmane.comp.mozilla.crypto/7947 + */ + + /* generate the key */ + slot = PK11_GetBestSlot(key->cipherMech, NULL); + if (slot) { + unsigned char data[BUFFER_SIZE]; + + /* sanity check - key correct size? */ + if (rec->k.secret.secretLen != key->keyLength) { + PK11_FreeSlot(slot); + return APR_EKEYLENGTH; + } + + tslot = PK11_GetBestSlot(CKM_AES_ECB, NULL); + if (tslot) { + + /* generate a temporary wrapping key */ + tkey = PK11_KeyGen(tslot, CKM_AES_ECB, 0, PK11_GetBestKeyLength(tslot, CKM_AES_ECB), 0); + + /* prepare the key to wrap */ + secretItem.data = (unsigned char *) rec->k.secret.secret; + secretItem.len = rec->k.secret.secretLen; + + /* ensure our key matches the blocksize */ + secParam = PK11_GenerateNewParam(CKM_AES_ECB, tkey); + blockSize = PK11_GetBlockSize(CKM_AES_ECB, secParam); + remainder = rec->k.secret.secretLen % blockSize; + if (remainder) { + secretItem.data = + apr_pcalloc(p, rec->k.secret.secretLen + remainder); + apr_crypto_clear(p, secretItem.data, + rec->k.secret.secretLen); + memcpy(secretItem.data, rec->k.secret.secret, + rec->k.secret.secretLen); + secretItem.len += remainder; + } + + /* prepare a space for the wrapped key */ + wrappedItem.data = data; + + /* wrap the key */ + ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_ENCRYPT, tkey, + secParam); + if (ctx) { + s = PK11_CipherOp(ctx, wrappedItem.data, + (int *) (&wrappedItem.len), BUFFER_SIZE, + secretItem.data, secretItem.len); + if (s == SECSuccess) { + + /* unwrap the key again */ + key->symKey = PK11_UnwrapSymKeyWithFlags(tkey, + CKM_AES_ECB, NULL, &wrappedItem, + key->cipherMech, CKA_ENCRYPT, + rec->k.secret.secretLen, 0); + + } + + PK11_DestroyContext(ctx, PR_TRUE); + } + + /* clean up */ + SECITEM_FreeItem(secParam, PR_TRUE); + PK11_FreeSymKey(tkey); + PK11_FreeSlot(tslot); + + } + + PK11_FreeSlot(slot); + } + + break; + } + + default: { + + return APR_ENOKEY; + + } + } + + /* sanity check? */ + if (!key->symKey) { + PRErrorCode perr = PORT_GetError(); + if (perr) { + f->result->rc = perr; + f->result->msg = PR_ErrorToName(perr); + rv = APR_ENOKEY; + } + } + + return rv; +} + /** * @brief Create a key from the given passphrase. By default, the PBKDF2 * algorithm is used to generate the key from the passphrase. It is expected @@ -406,69 +683,21 @@ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, apr_crypto_key_t *key = *k; if (!key) { - *k = key = apr_array_push(f->keys); - } - if (!key) { - return APR_ENOMEM; + *k = key = apr_pcalloc(p, sizeof *key); + if (!key) { + return APR_ENOMEM; + } + apr_pool_cleanup_register(p, key, crypto_key_cleanup, + apr_pool_cleanup_null); } key->f = f; key->provider = f->provider; /* decide on what cipher mechanism we will be using */ - switch (type) { - - case (APR_KEY_3DES_192): - if (APR_MODE_CBC == mode) { - key->cipherOid = SEC_OID_DES_EDE3_CBC; - } - else if (APR_MODE_ECB == mode) { - return APR_ENOCIPHER; - /* No OID for CKM_DES3_ECB; */ - } - break; - case (APR_KEY_AES_128): - if (APR_MODE_CBC == mode) { - key->cipherOid = SEC_OID_AES_128_CBC; - } - else { - key->cipherOid = SEC_OID_AES_128_ECB; - } - break; - case (APR_KEY_AES_192): - if (APR_MODE_CBC == mode) { - key->cipherOid = SEC_OID_AES_192_CBC; - } - else { - key->cipherOid = SEC_OID_AES_192_ECB; - } - break; - case (APR_KEY_AES_256): - if (APR_MODE_CBC == mode) { - key->cipherOid = SEC_OID_AES_256_CBC; - } - else { - key->cipherOid = SEC_OID_AES_256_ECB; - } - break; - default: - /* unknown key type, give up */ - return APR_EKEYTYPE; - } - - /* AES_128_CBC --> CKM_AES_CBC --> CKM_AES_CBC_PAD */ - key->cipherMech = PK11_AlgtagToMechanism(key->cipherOid); - if (key->cipherMech == CKM_INVALID_MECHANISM) { - return APR_ENOCIPHER; - } - if (doPad) { - CK_MECHANISM_TYPE paddedMech; - paddedMech = PK11_GetPadMechanism(key->cipherMech); - if (CKM_INVALID_MECHANISM == paddedMech || key->cipherMech - == paddedMech) { - return APR_EPADDING; - } - key->cipherMech = paddedMech; + rv = crypto_cipher_mechanism(key, type, mode, doPad); + if (APR_SUCCESS != rv) { + return rv; } /* Turn the raw passphrase and salt into SECItems */ @@ -478,9 +707,9 @@ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, saltItem.len = saltLen; /* generate the key */ - /* pbeAlg and cipherAlg are the same. NSS decides the keylength. */ + /* pbeAlg and cipherAlg are the same. */ algid = PK11_CreatePBEV2AlgorithmID(key->cipherOid, key->cipherOid, - SEC_OID_HMAC_SHA1, 0, iterations, &saltItem); + SEC_OID_HMAC_SHA1, key->keyLength, iterations, &saltItem); if (algid) { slot = PK11_GetBestSlot(key->cipherMech, wincx); if (slot) { @@ -501,7 +730,6 @@ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, } } - key->ivSize = PK11_GetIVLength(key->cipherMech); if (ivSize) { *ivSize = key->ivSize; } @@ -530,7 +758,6 @@ static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, apr_size_t *blockSize, apr_pool_t *p) { PRErrorCode perr; - SECItem * secParam; SECItem ivItem; unsigned char * usedIv; apr_crypto_block_t *block = *ctx; @@ -569,14 +796,14 @@ static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, } ivItem.data = usedIv; ivItem.len = key->ivSize; - secParam = PK11_ParamFromIV(key->cipherMech, &ivItem); + block->secParam = PK11_ParamFromIV(key->cipherMech, &ivItem); } else { - secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey); + block->secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey); } - block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam); + block->blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam); block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_ENCRYPT, - key->symKey, secParam); + key->symKey, block->secParam); /* did an error occur? */ perr = PORT_GetError(); @@ -587,7 +814,7 @@ static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, } if (blockSize) { - *blockSize = PK11_GetBlockSize(key->cipherMech, secParam); + *blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam); } return APR_SUCCESS; @@ -711,7 +938,6 @@ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, const apr_crypto_key_t *key, apr_pool_t *p) { PRErrorCode perr; - SECItem * secParam; apr_crypto_block_t *block = *ctx; if (!block) { *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); @@ -733,14 +959,14 @@ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, } ivItem.data = (unsigned char*) iv; ivItem.len = key->ivSize; - secParam = PK11_ParamFromIV(key->cipherMech, &ivItem); + block->secParam = PK11_ParamFromIV(key->cipherMech, &ivItem); } else { - secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey); + block->secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey); } - block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam); + block->blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam); block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_DECRYPT, - key->symKey, secParam); + key->symKey, block->secParam); /* did an error occur? */ perr = PORT_GetError(); @@ -751,7 +977,7 @@ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, } if (blockSize) { - *blockSize = PK11_GetBlockSize(key->cipherMech, secParam); + *blockSize = PK11_GetBlockSize(key->cipherMech, block->secParam); } return APR_SUCCESS; @@ -864,7 +1090,8 @@ APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_nss_driver = { crypto_block_encrypt_init, crypto_block_encrypt, crypto_block_encrypt_finish, crypto_block_decrypt_init, crypto_block_decrypt, crypto_block_decrypt_finish, - crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error + crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error, + crypto_key }; #endif diff --git a/contrib/apr-util/crypto/apr_crypto_openssl.c b/contrib/apr-util/crypto/apr_crypto_openssl.c index 0740f93f6349..310bb2c762b1 100644 --- a/contrib/apr-util/crypto/apr_crypto_openssl.c +++ b/contrib/apr-util/crypto/apr_crypto_openssl.c @@ -31,15 +31,27 @@ #if APU_HAVE_CRYPTO #include +#include #include #define LOG_PREFIX "apr_crypto_openssl: " +#ifndef APR_USE_OPENSSL_PRE_1_1_API +#if defined(LIBRESSL_VERSION_NUMBER) +/* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not include most + * changes from OpenSSL >= 1.1 (new functions, macros, deprecations, ...), so + * we have to work around this... + */ +#define APR_USE_OPENSSL_PRE_1_1_API (1) +#else +#define APR_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L) +#endif +#endif + struct apr_crypto_t { apr_pool_t *pool; const apr_crypto_driver_t *provider; apu_err_t *result; - apr_array_header_t *keys; apr_crypto_config_t *config; apr_hash_t *types; apr_hash_t *modes; @@ -64,20 +76,27 @@ struct apr_crypto_block_t { apr_pool_t *pool; const apr_crypto_driver_t *provider; const apr_crypto_t *f; - EVP_CIPHER_CTX cipherCtx; + EVP_CIPHER_CTX *cipherCtx; int initialised; int ivSize; int blockSize; int doPad; }; -static int key_3des_192 = APR_KEY_3DES_192; -static int key_aes_128 = APR_KEY_AES_128; -static int key_aes_192 = APR_KEY_AES_192; -static int key_aes_256 = APR_KEY_AES_256; +static struct apr_crypto_block_key_type_t key_types[] = +{ +{ APR_KEY_3DES_192, 24, 8, 8 }, +{ APR_KEY_AES_128, 16, 16, 16 }, +{ APR_KEY_AES_192, 24, 16, 16 }, +{ APR_KEY_AES_256, 32, 16, 16 } }; -static int mode_ecb = APR_MODE_ECB; -static int mode_cbc = APR_MODE_CBC; +static struct apr_crypto_block_key_mode_t key_modes[] = +{ +{ APR_MODE_ECB }, +{ APR_MODE_CBC } }; + +/* sufficient space to wrap a key */ +#define BUFFER_SIZE 128 /** * Fetch the most recent error from this driver. @@ -111,7 +130,11 @@ static apr_status_t crypto_shutdown_helper(void *data) static apr_status_t crypto_init(apr_pool_t *pool, const char *params, const apu_err_t **result) { - CRYPTO_malloc_init(); +#if APR_USE_OPENSSL_PRE_1_1_API + (void)CRYPTO_malloc_init(); +#else + OPENSSL_malloc_init(); +#endif ERR_load_crypto_strings(); /* SSL_load_error_strings(); */ OpenSSL_add_all_algorithms(); @@ -124,6 +147,30 @@ static apr_status_t crypto_init(apr_pool_t *pool, const char *params, return APR_SUCCESS; } +#if OPENSSL_VERSION_NUMBER < 0x0090802fL + +/* Code taken from OpenSSL 0.9.8b, see + * https://github.com/openssl/openssl/commit/cf6bc84148cb15af09b292394aaf2b45f0d5af0d + */ + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + if (ctx) + EVP_CIPHER_CTX_init(ctx); + return ctx; +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + if (ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +#endif + /** * @brief Clean encryption / decryption context. * @note After cleanup, a context is free to be reused if necessary. @@ -134,7 +181,7 @@ static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx) { if (ctx->initialised) { - EVP_CIPHER_CTX_cleanup(&ctx->cipherCtx); + EVP_CIPHER_CTX_free(ctx->cipherCtx); ctx->initialised = 0; } @@ -256,26 +303,21 @@ static apr_status_t crypto_make(apr_crypto_t **ff, return APR_ENOMEM; } - f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t)); - if (!f->keys) { - return APR_ENOMEM; - } - f->types = apr_hash_make(pool); if (!f->types) { return APR_ENOMEM; } - apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192)); - apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128)); - apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192)); - apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256)); + apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_types[0])); + apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_types[1])); + apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_types[2])); + apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_types[3])); f->modes = apr_hash_make(pool); if (!f->modes) { return APR_ENOMEM; } - apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb)); - apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc)); + apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(key_modes[0])); + apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(key_modes[1])); apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, apr_pool_cleanup_null); @@ -298,7 +340,7 @@ static apr_status_t crypto_make(apr_crypto_t **ff, /** * @brief Get a hash table of key types, keyed by the name of the type against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_type_t. * * @param types - hashtable of key types keyed to constants. * @param f - encryption context @@ -313,7 +355,7 @@ static apr_status_t crypto_get_block_key_types(apr_hash_t **types, /** * @brief Get a hash table of key modes, keyed by the name of the mode against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_mode_t. * * @param modes - hashtable of key modes keyed to constants. * @param f - encryption context @@ -326,52 +368,13 @@ static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, return APR_SUCCESS; } -/** - * @brief Create a key from the given passphrase. By default, the PBKDF2 - * algorithm is used to generate the key from the passphrase. It is expected - * that the same pass phrase will generate the same key, regardless of the - * backend crypto platform used. The key is cleaned up when the context - * is cleaned, and may be reused with multiple encryption or decryption - * operations. - * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If - * *key is not NULL, *key must point at a previously created structure. - * @param key The key returned, see note. - * @param ivSize The size of the initialisation vector will be returned, based - * on whether an IV is relevant for this type of crypto. - * @param pass The passphrase to use. - * @param passLen The passphrase length in bytes - * @param salt The salt to use. - * @param saltLen The salt length in bytes - * @param type 3DES_192, AES_128, AES_192, AES_256. - * @param mode Electronic Code Book / Cipher Block Chaining. - * @param doPad Pad if necessary. - * @param iterations Iteration count - * @param f The context to use. - * @param p The pool to use. - * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend - * error occurred while generating the key. APR_ENOCIPHER if the type or mode - * is not supported by the particular backend. APR_EKEYTYPE if the key type is - * not known. APR_EPADDING if padding was requested but is not supported. - * APR_ENOTIMPL if not implemented. +/* + * Work out which mechanism to use. */ -static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, - const char *pass, apr_size_t passLen, const unsigned char * salt, - apr_size_t saltLen, const apr_crypto_block_key_type_e type, - const apr_crypto_block_key_mode_e mode, const int doPad, - const int iterations, const apr_crypto_t *f, apr_pool_t *p) +static apr_status_t crypto_cipher_mechanism(apr_crypto_key_t *key, + const apr_crypto_block_key_type_e type, + const apr_crypto_block_key_mode_e mode, const int doPad, apr_pool_t *p) { - apr_crypto_key_t *key = *k; - - if (!key) { - *k = key = apr_array_push(f->keys); - } - if (!key) { - return APR_ENOMEM; - } - - key->f = f; - key->provider = f->provider; - /* determine the cipher to be used */ switch (type) { @@ -433,6 +436,148 @@ static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, } apr_crypto_clear(p, key->key, key->keyLen); + return APR_SUCCESS; +} + +/** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_key(apr_crypto_key_t **k, + const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p) +{ + apr_crypto_key_t *key = *k; + apr_status_t rv; + + if (!key) { + *k = key = apr_pcalloc(p, sizeof *key); + if (!key) { + return APR_ENOMEM; + } + } + + key->f = f; + key->provider = f->provider; + + /* decide on what cipher mechanism we will be using */ + rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p); + if (APR_SUCCESS != rv) { + return rv; + } + + switch (rec->ktype) { + + case APR_CRYPTO_KTYPE_PASSPHRASE: { + + /* generate the key */ + if (PKCS5_PBKDF2_HMAC_SHA1(rec->k.passphrase.pass, + rec->k.passphrase.passLen, + (unsigned char *) rec->k.passphrase.salt, + rec->k.passphrase.saltLen, rec->k.passphrase.iterations, + key->keyLen, key->key) == 0) { + return APR_ENOKEY; + } + + break; + } + + case APR_CRYPTO_KTYPE_SECRET: { + + /* sanity check - key correct size? */ + if (rec->k.secret.secretLen != key->keyLen) { + return APR_EKEYLENGTH; + } + + /* copy the key */ + memcpy(key->key, rec->k.secret.secret, rec->k.secret.secretLen); + + break; + } + + default: { + + return APR_ENOKEY; + + } + } + + key->doPad = rec->pad; + + /* note: openssl incorrectly returns non zero IV size values for ECB + * algorithms, so work around this by ignoring the IV size. + */ + if (APR_MODE_ECB != rec->mode) { + key->ivSize = EVP_CIPHER_iv_length(key->cipher); + } + + return APR_SUCCESS; +} + +/** + * @brief Create a key from the given passphrase. By default, the PBKDF2 + * algorithm is used to generate the key from the passphrase. It is expected + * that the same pass phrase will generate the same key, regardless of the + * backend crypto platform used. The key is cleaned up when the context + * is cleaned, and may be reused with multiple encryption or decryption + * operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param ivSize The size of the initialisation vector will be returned, based + * on whether an IV is relevant for this type of crypto. + * @param pass The passphrase to use. + * @param passLen The passphrase length in bytes + * @param salt The salt to use. + * @param saltLen The salt length in bytes + * @param type 3DES_192, AES_128, AES_192, AES_256. + * @param mode Electronic Code Book / Cipher Block Chaining. + * @param doPad Pad if necessary. + * @param iterations Iteration count + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize, + const char *pass, apr_size_t passLen, const unsigned char * salt, + apr_size_t saltLen, const apr_crypto_block_key_type_e type, + const apr_crypto_block_key_mode_e mode, const int doPad, + const int iterations, const apr_crypto_t *f, apr_pool_t *p) +{ + apr_crypto_key_t *key = *k; + apr_status_t rv; + + if (!key) { + *k = key = apr_pcalloc(p, sizeof *key); + if (!key) { + return APR_ENOMEM; + } + } + + key->f = f; + key->provider = f->provider; + + /* decide on what cipher mechanism we will be using */ + rv = crypto_cipher_mechanism(key, type, mode, doPad, p); + if (APR_SUCCESS != rv) { + return rv; + } + /* generate the key */ if (PKCS5_PBKDF2_HMAC_SHA1(pass, passLen, (unsigned char *) salt, saltLen, iterations, key->keyLen, key->key) == 0) { @@ -491,8 +636,10 @@ static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, apr_pool_cleanup_null); /* create a new context for encryption */ - EVP_CIPHER_CTX_init(&block->cipherCtx); - block->initialised = 1; + if (!block->initialised) { + block->cipherCtx = EVP_CIPHER_CTX_new(); + block->initialised = 1; + } /* generate an IV, if necessary */ usedIv = NULL; @@ -519,16 +666,16 @@ static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx, /* set up our encryption context */ #if CRYPTO_OPENSSL_CONST_BUFFERS - if (!EVP_EncryptInit_ex(&block->cipherCtx, key->cipher, config->engine, + if (!EVP_EncryptInit_ex(block->cipherCtx, key->cipher, config->engine, key->key, usedIv)) { #else - if (!EVP_EncryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) usedIv)) { + if (!EVP_EncryptInit_ex(block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) usedIv)) { #endif return APR_EINIT; } /* Clear up any read padding */ - if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) { + if (!EVP_CIPHER_CTX_set_padding(block->cipherCtx, key->doPad)) { return APR_EPADDING; } @@ -582,10 +729,15 @@ static apr_status_t crypto_block_encrypt(unsigned char **out, } #if CRYPT_OPENSSL_CONST_BUFFERS - if (!EVP_EncryptUpdate(&ctx->cipherCtx, (*out), &outl, in, inlen)) { + if (!EVP_EncryptUpdate(ctx->cipherCtx, (*out), &outl, in, inlen)) { #else - if (!EVP_EncryptUpdate(&ctx->cipherCtx, (*out), &outl, + if (!EVP_EncryptUpdate(ctx->cipherCtx, (*out), &outl, (unsigned char *) in, inlen)) { +#endif +#if APR_USE_OPENSSL_PRE_1_1_API + EVP_CIPHER_CTX_cleanup(ctx->cipherCtx); +#else + EVP_CIPHER_CTX_reset(ctx->cipherCtx); #endif return APR_ECRYPT; } @@ -616,14 +768,22 @@ static apr_status_t crypto_block_encrypt(unsigned char **out, static apr_status_t crypto_block_encrypt_finish(unsigned char *out, apr_size_t *outlen, apr_crypto_block_t *ctx) { + apr_status_t rc = APR_SUCCESS; int len = *outlen; - if (EVP_EncryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) { - return APR_EPADDING; + if (EVP_EncryptFinal_ex(ctx->cipherCtx, out, &len) == 0) { + rc = APR_EPADDING; } - *outlen = len; + else { + *outlen = len; + } +#if APR_USE_OPENSSL_PRE_1_1_API + EVP_CIPHER_CTX_cleanup(ctx->cipherCtx); +#else + EVP_CIPHER_CTX_reset(ctx->cipherCtx); +#endif - return APR_SUCCESS; + return rc; } @@ -662,8 +822,10 @@ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, apr_pool_cleanup_null); /* create a new context for encryption */ - EVP_CIPHER_CTX_init(&block->cipherCtx); - block->initialised = 1; + if (!block->initialised) { + block->cipherCtx = EVP_CIPHER_CTX_new(); + block->initialised = 1; + } /* generate an IV, if necessary */ if (key->ivSize) { @@ -674,16 +836,16 @@ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, /* set up our encryption context */ #if CRYPTO_OPENSSL_CONST_BUFFERS - if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, + if (!EVP_DecryptInit_ex(block->cipherCtx, key->cipher, config->engine, key->key, iv)) { #else - if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) { + if (!EVP_DecryptInit_ex(block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) { #endif return APR_EINIT; } /* Clear up any read padding */ - if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) { + if (!EVP_CIPHER_CTX_set_padding(block->cipherCtx, key->doPad)) { return APR_EPADDING; } @@ -737,10 +899,15 @@ static apr_status_t crypto_block_decrypt(unsigned char **out, } #if CRYPT_OPENSSL_CONST_BUFFERS - if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, in, inlen)) { + if (!EVP_DecryptUpdate(ctx->cipherCtx, *out, &outl, in, inlen)) { #else - if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, (unsigned char *) in, + if (!EVP_DecryptUpdate(ctx->cipherCtx, *out, &outl, (unsigned char *) in, inlen)) { +#endif +#if APR_USE_OPENSSL_PRE_1_1_API + EVP_CIPHER_CTX_cleanup(ctx->cipherCtx); +#else + EVP_CIPHER_CTX_reset(ctx->cipherCtx); #endif return APR_ECRYPT; } @@ -771,15 +938,22 @@ static apr_status_t crypto_block_decrypt(unsigned char **out, static apr_status_t crypto_block_decrypt_finish(unsigned char *out, apr_size_t *outlen, apr_crypto_block_t *ctx) { - + apr_status_t rc = APR_SUCCESS; int len = *outlen; - if (EVP_DecryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) { - return APR_EPADDING; + if (EVP_DecryptFinal_ex(ctx->cipherCtx, out, &len) == 0) { + rc = APR_EPADDING; } - *outlen = len; + else { + *outlen = len; + } +#if APR_USE_OPENSSL_PRE_1_1_API + EVP_CIPHER_CTX_cleanup(ctx->cipherCtx); +#else + EVP_CIPHER_CTX_reset(ctx->cipherCtx); +#endif - return APR_SUCCESS; + return rc; } @@ -792,7 +966,8 @@ APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_openssl_driver = { crypto_block_encrypt_init, crypto_block_encrypt, crypto_block_encrypt_finish, crypto_block_decrypt_init, crypto_block_decrypt, crypto_block_decrypt_finish, - crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error + crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error, + crypto_key }; #endif diff --git a/contrib/apr-util/crypto/apr_siphash.c b/contrib/apr-util/crypto/apr_siphash.c new file mode 100644 index 000000000000..c9cabe2d2d4c --- /dev/null +++ b/contrib/apr-util/crypto/apr_siphash.c @@ -0,0 +1,196 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * SipHash (C reference implementation, APR-ized), originating from: + * https://131002.net/siphash/siphash24.c. + */ + +#include "apr_siphash.h" + +#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) + +#define U8TO64_LE(p) \ + (((apr_uint64_t)((p)[0]) ) | \ + ((apr_uint64_t)((p)[1]) << 8) | \ + ((apr_uint64_t)((p)[2]) << 16) | \ + ((apr_uint64_t)((p)[3]) << 24) | \ + ((apr_uint64_t)((p)[4]) << 32) | \ + ((apr_uint64_t)((p)[5]) << 40) | \ + ((apr_uint64_t)((p)[6]) << 48) | \ + ((apr_uint64_t)((p)[7]) << 56)) + +#define U64TO8_LE(p, v) \ +do { \ + (p)[0] = (unsigned char)((v) ); \ + (p)[1] = (unsigned char)((v) >> 8); \ + (p)[2] = (unsigned char)((v) >> 16); \ + (p)[3] = (unsigned char)((v) >> 24); \ + (p)[4] = (unsigned char)((v) >> 32); \ + (p)[5] = (unsigned char)((v) >> 40); \ + (p)[6] = (unsigned char)((v) >> 48); \ + (p)[7] = (unsigned char)((v) >> 56); \ +} while (0) + +#define SIPROUND() \ +do { \ + v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \ + v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \ + v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \ + v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \ +} while(0) + +#define SIPHASH(r, s, n, k) \ +do { \ + const unsigned char *ptr, *end; \ + apr_uint64_t v0, v1, v2, v3, m; \ + apr_uint64_t k0, k1; \ + unsigned int rem; \ + \ + k0 = U8TO64_LE(k + 0); \ + k1 = U8TO64_LE(k + 8); \ + v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL; \ + v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL; \ + v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL; \ + v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL; \ + \ + rem = (unsigned int)(n & 0x7); \ + for (ptr = s, end = ptr + n - rem; ptr < end; ptr += 8) { \ + m = U8TO64_LE(ptr); \ + v3 ^= m; \ + cROUNDS \ + v0 ^= m; \ + } \ + m = (apr_uint64_t)(n & 0xff) << 56; \ + switch (rem) { \ + case 7: m |= (apr_uint64_t)ptr[6] << 48; \ + case 6: m |= (apr_uint64_t)ptr[5] << 40; \ + case 5: m |= (apr_uint64_t)ptr[4] << 32; \ + case 4: m |= (apr_uint64_t)ptr[3] << 24; \ + case 3: m |= (apr_uint64_t)ptr[2] << 16; \ + case 2: m |= (apr_uint64_t)ptr[1] << 8; \ + case 1: m |= (apr_uint64_t)ptr[0]; \ + case 0: break; \ + } \ + v3 ^= m; \ + cROUNDS \ + v0 ^= m; \ + \ + v2 ^= 0xff; \ + dROUNDS \ + \ + r = v0 ^ v1 ^ v2 ^ v3; \ +} while (0) + +APU_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE], + unsigned int c, unsigned int d) +{ + apr_uint64_t h; + unsigned int i; + +#undef cROUNDS +#define cROUNDS \ + for (i = 0; i < c; ++i) { \ + SIPROUND(); \ + } + +#undef dROUNDS +#define dROUNDS \ + for (i = 0; i < d; ++i) { \ + SIPROUND(); \ + } + + SIPHASH(h, src, len, key); + return h; +} + +APU_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE], + unsigned int c, unsigned int d) +{ + apr_uint64_t h; + h = apr_siphash(src, len, key, c, d); + U64TO8_LE(out, h); +} + +APU_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]) +{ + apr_uint64_t h; + +#undef cROUNDS +#define cROUNDS \ + SIPROUND(); \ + SIPROUND(); + +#undef dROUNDS +#define dROUNDS \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); + + SIPHASH(h, src, len, key); + return h; +} + +APU_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]) +{ + apr_uint64_t h; + h = apr_siphash24(src, len, key); + U64TO8_LE(out, h); +} + +APU_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]) +{ + apr_uint64_t h; + +#undef cROUNDS +#define cROUNDS \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); + +#undef dROUNDS +#define dROUNDS \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); \ + SIPROUND(); + + SIPHASH(h, src, len, key); + return h; +} + +APU_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]) +{ + apr_uint64_t h; + h = apr_siphash48(src, len, key); + U64TO8_LE(out, h); +} + diff --git a/contrib/apr-util/crypto/crypt_blowfish.c b/contrib/apr-util/crypto/crypt_blowfish.c index ec9a188b3a28..3d306cf8d3f4 100644 --- a/contrib/apr-util/crypto/crypt_blowfish.c +++ b/contrib/apr-util/crypto/crypt_blowfish.c @@ -675,9 +675,9 @@ static char *BF_crypt(const char *key, const char *setting, setting[2] < 'a' || setting[2] > 'z' || !flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] || setting[3] != '$' || - setting[4] < '0' || setting[4] > '3' || + setting[4] < '0' || setting[4] > '1' || setting[5] < '0' || setting[5] > '9' || - (setting[4] == '3' && setting[5] > '1') || + (setting[4] == '1' && setting[5] > '7') || setting[6] != '$') { __set_errno(EINVAL); return NULL; @@ -877,7 +877,7 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size) { if (size < 16 || output_size < 7 + 22 + 1 || - (count && (count < 4 || count > 31)) || + (count && (count < 4 || count > 17)) || prefix[0] != '$' || prefix[1] != '2' || (prefix[2] != 'a' && prefix[2] != 'y')) { if (output_size > 0) output[0] = '\0'; diff --git a/contrib/apr-util/dbd/NWGNUmakefile b/contrib/apr-util/dbd/NWGNUmakefile index b1e3e532678a..a96d7f6fca0c 100644 --- a/contrib/apr-util/dbd/NWGNUmakefile +++ b/contrib/apr-util/dbd/NWGNUmakefile @@ -168,9 +168,6 @@ endif ifeq "$(APU_HAVE_SQLITE3)" "1" TARGET_nlm += $(OBJDIR)/dbdsqli3.nlm $(OBJDIR)/dbdsqli3.nlm $(EOLIST) endif -ifeq "$(APU_HAVE_FREETDS)" "1" -TARGET_nlm += $(OBJDIR)/dbdfreetds.nlm $(OBJDIR)/dbdfreetds.nlm $(EOLIST) -endif # # If there is an LIB target, put it here diff --git a/contrib/apr-util/dbd/apr_dbd.c b/contrib/apr-util/dbd/apr_dbd.c index bfa97d9e380a..abf858c95e5b 100644 --- a/contrib/apr-util/dbd/apr_dbd.c +++ b/contrib/apr-util/dbd/apr_dbd.c @@ -136,9 +136,6 @@ APU_DECLARE(apr_status_t) apr_dbd_init(apr_pool_t *pool) #if APU_HAVE_ORACLE DRIVER_LOAD("oracle", apr_dbd_oracle_driver, pool); #endif -#if APU_HAVE_FREETDS - DRIVER_LOAD("freetds", apr_dbd_freetds_driver, pool); -#endif #if APU_HAVE_ODBC DRIVER_LOAD("odbc", apr_dbd_odbc_driver, pool); #endif diff --git a/contrib/apr-util/dbd/NWGNUdbdfreetds b/contrib/apr-util/dbd/unsupported/NWGNUdbdfreetds similarity index 100% rename from contrib/apr-util/dbd/NWGNUdbdfreetds rename to contrib/apr-util/dbd/unsupported/NWGNUdbdfreetds diff --git a/contrib/apr-util/dbd/apr_dbd_freetds.c b/contrib/apr-util/dbd/unsupported/apr_dbd_freetds.c similarity index 99% rename from contrib/apr-util/dbd/apr_dbd_freetds.c rename to contrib/apr-util/dbd/unsupported/apr_dbd_freetds.c index d0b4b20025ec..2c34ede73bf2 100644 --- a/contrib/apr-util/dbd/apr_dbd_freetds.c +++ b/contrib/apr-util/dbd/unsupported/apr_dbd_freetds.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef I_CAN_DEAL_WITH_THIS_PARTIAL_DRIVER_AND_UNMAINTAINED_CODE_FOR_FREETDS + #include "apu.h" #include "apu_config.h" @@ -803,3 +805,5 @@ APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_freetds_driver = { #endif }; #endif + +#endif diff --git a/contrib/apr-util/dbm/sdbm/sdbm.c b/contrib/apr-util/dbm/sdbm/sdbm.c index a1ce69531315..a62b009e5cb7 100644 --- a/contrib/apr-util/dbm/sdbm/sdbm.c +++ b/contrib/apr-util/dbm/sdbm/sdbm.c @@ -40,7 +40,7 @@ */ static int getdbit (apr_sdbm_t *, long); static apr_status_t setdbit(apr_sdbm_t *, long); -static apr_status_t getpage(apr_sdbm_t *db, long); +static apr_status_t getpage(apr_sdbm_t *db, long, int, int); static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db); static apr_status_t makroom(apr_sdbm_t *, long, int); @@ -93,6 +93,7 @@ static apr_status_t prep(apr_sdbm_t **pdb, const char *dirname, const char *pagn db = malloc(sizeof(*db)); memset(db, 0, sizeof(*db)); + db->pagbno = -1L; db->pool = p; @@ -193,7 +194,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db, apr_sdbm_datum_t *val, if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS) return status; - if ((status = getpage(db, exhash(key))) == APR_SUCCESS) { + if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) { *val = getpair(db->pagbuf, key); /* ### do we want a not-found result? */ } @@ -227,7 +228,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db, if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS) return status; - if ((status = getpage(db, exhash(key))) == APR_SUCCESS) { + if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) { if (!delpair(db->pagbuf, key)) /* ### should we define some APRUTIL codes? */ status = APR_EGENERAL; @@ -261,7 +262,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key, if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS) return status; - if ((status = getpage(db, (hash = exhash(key)))) == APR_SUCCESS) { + if ((status = getpage(db, (hash = exhash(key)), 0, 1)) == APR_SUCCESS) { /* * if we need to replace, delete the key/data pair @@ -376,17 +377,19 @@ static apr_status_t makroom(apr_sdbm_t *db, long hash, int need) /* Reads 'len' bytes from file 'f' at offset 'off' into buf. * 'off' is given relative to the start of the file. - * If EOF is returned while reading, this is taken as success. + * If 'create' is asked and EOF is returned while reading, this is taken + * as success (i.e. a cleared buffer is returned). */ static apr_status_t read_from(apr_file_t *f, void *buf, - apr_off_t off, apr_size_t len) + apr_off_t off, apr_size_t len, + int create) { apr_status_t status; if ((status = apr_file_seek(f, APR_SET, &off)) != APR_SUCCESS || ((status = apr_file_read_full(f, buf, len, NULL)) != APR_SUCCESS)) { /* if EOF is reached, pretend we read all zero's */ - if (status == APR_EOF) { + if (status == APR_EOF && create) { memset(buf, 0, len); status = APR_SUCCESS; } @@ -410,9 +413,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db, /* * start at page 0 */ - if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(0), PBLKSIZ)) - == APR_SUCCESS) { - db->pagbno = 0; + if ((status = getpage(db, 0, 1, 1)) == APR_SUCCESS) { db->blkptr = 0; db->keyptr = 0; status = getnext(key, db); @@ -441,24 +442,28 @@ APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db, /* * all important binary tree traversal */ -static apr_status_t getpage(apr_sdbm_t *db, long hash) +static apr_status_t getpage(apr_sdbm_t *db, long hash, int by_num, int create) { - register int hbit; - register long dbit; - register long pagb; apr_status_t status; + register long pagb; - dbit = 0; - hbit = 0; - while (dbit < db->maxbno && getdbit(db, dbit)) - dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1); + if (by_num) { + pagb = hash; + } + else { + register int hbit = 0; + register long dbit = 0; - debug(("dbit: %d...", dbit)); + while (dbit < db->maxbno && getdbit(db, dbit)) + dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1); + debug(("dbit: %d...", dbit)); - db->curbit = dbit; - db->hmask = masks[hbit]; + db->curbit = dbit; + db->hmask = masks[hbit]; + + pagb = hash & db->hmask; + } - pagb = hash & db->hmask; /* * see if the block we need is already in memory. * note: this lookaside cache has about 10% hit rate. @@ -470,12 +475,14 @@ static apr_status_t getpage(apr_sdbm_t *db, long hash) * ### joe: this assumption was surely never correct? but * ### we make it so in read_from anyway. */ - if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(pagb), PBLKSIZ)) - != APR_SUCCESS) + if ((status = read_from(db->pagf, db->pagbuf, + OFF_PAG(pagb), PBLKSIZ, + create)) != APR_SUCCESS) return status; if (!chkpage(db->pagbuf)) return APR_ENOSPC; /* ### better error? */ + db->pagbno = pagb; debug(("pag read: %d\n", pagb)); @@ -492,8 +499,9 @@ static int getdbit(apr_sdbm_t *db, long dbit) dirb = c / DBLKSIZ; if (dirb != db->dirbno) { - if (read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ) - != APR_SUCCESS) + if (read_from(db->dirf, db->dirbuf, + OFF_DIR(dirb), DBLKSIZ, + 1) != APR_SUCCESS) return 0; db->dirbno = dirb; @@ -515,8 +523,9 @@ static apr_status_t setdbit(apr_sdbm_t *db, long dbit) dirb = c / DBLKSIZ; if (dirb != db->dirbno) { - if ((status = read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ)) - != APR_SUCCESS) + if ((status = read_from(db->dirf, db->dirbuf, + OFF_DIR(dirb), DBLKSIZ, + 1)) != APR_SUCCESS) return status; db->dirbno = dirb; @@ -553,21 +562,12 @@ static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db) * try the next one... If we lost our position on the * file, we will have to seek. */ + db->blkptr++; db->keyptr = 0; - if (db->pagbno != db->blkptr++) { - apr_off_t off = OFF_PAG(db->blkptr); - if ((status = apr_file_seek(db->pagf, APR_SET, &off)) - != APR_SUCCESS) - return status; - } - db->pagbno = db->blkptr; /* ### EOF acceptable here too? */ - if ((status = apr_file_read_full(db->pagf, db->pagbuf, PBLKSIZ, NULL)) - != APR_SUCCESS) + if ((status = getpage(db, db->blkptr, 1, 0)) != APR_SUCCESS) return status; - if (!chkpage(db->pagbuf)) - return APR_EGENERAL; /* ### need better error */ } /* NOTREACHED */ diff --git a/contrib/apr-util/dbm/sdbm/sdbm_pair.c b/contrib/apr-util/dbm/sdbm/sdbm_pair.c index 2130200734e8..50d7965b1415 100644 --- a/contrib/apr-util/dbm/sdbm/sdbm_pair.c +++ b/contrib/apr-util/dbm/sdbm/sdbm_pair.c @@ -308,7 +308,8 @@ char *pag; if (n > 0) { off = PBLKSIZ; for (ino++; n > 0; ino += 2) { - if (ino[0] > off || ino[1] > off || + if (ino[0] < 0 || ino[0] > off || + ino[1] < 0 || ino[1] > off || ino[1] > ino[0]) return 0; off = ino[1]; diff --git a/contrib/apr-util/include/apr_buckets.h b/contrib/apr-util/include/apr_buckets.h index 025292b98658..ce64b78da116 100644 --- a/contrib/apr-util/include/apr_buckets.h +++ b/contrib/apr-util/include/apr_buckets.h @@ -622,6 +622,8 @@ struct apr_bucket_file { * a caller tries to read from it */ int can_mmap; #endif /* APR_HAS_MMAP */ + /** File read block size */ + apr_size_t read_size; }; /** @see apr_bucket_structs */ @@ -961,6 +963,18 @@ APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(apr_allocato */ APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list); +/** + * Get the aligned size corresponding to the requested size, but minus the + * allocator(s) overhead such that the allocation would remain in the + * same boundary. + * @param list The allocator from which to the memory would be allocated. + * @param size The requested size. + * @return The corresponding aligned/floored size. + */ +APU_DECLARE_NONSTD(apr_size_t) apr_bucket_alloc_aligned_floor(apr_bucket_alloc_t *list, + apr_size_t size) + __attribute__((nonnull(1))); + /** * Allocate memory for use by the buckets. * @param size The amount to allocate. @@ -1563,6 +1577,19 @@ APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd, APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *b, int enabled); +/** + * Set the size of the read buffer allocated by a FILE bucket (default + * is @a APR_BUCKET_BUFF_SIZE) + * memory-mapping is disabled only) + * @param b The bucket + * @param size Size of the allocated buffers + * @return APR_SUCCESS normally, or an error code if the operation fails + * @remark Relevant/used only when memory-mapping is disabled (@see + * apr_bucket_file_enable_mmap) + */ +APU_DECLARE(apr_status_t) apr_bucket_file_set_buf_size(apr_bucket *e, + apr_size_t size); + /** @} */ #ifdef __cplusplus } diff --git a/contrib/apr-util/include/apr_crypto.h b/contrib/apr-util/include/apr_crypto.h index ed0982dbdd91..b90f3fec5ec7 100644 --- a/contrib/apr-util/include/apr_crypto.h +++ b/contrib/apr-util/include/apr_crypto.h @@ -40,6 +40,9 @@ extern "C" { #if APU_HAVE_CRYPTO #ifndef APU_CRYPTO_RECOMMENDED_DRIVER +#if APU_HAVE_COMMONCRYPTO +#define APU_CRYPTO_RECOMMENDED_DRIVER "commoncrypto" +#else #if APU_HAVE_OPENSSL #define APU_CRYPTO_RECOMMENDED_DRIVER "openssl" #else @@ -57,6 +60,7 @@ extern "C" { #endif #endif #endif +#endif /** * Symmetric Key types understood by the library. @@ -84,16 +88,16 @@ extern "C" { * the chosen cipher. Padded data is data that is not aligned by block * size and must be padded by the crypto library. * - * OpenSSL NSS Interop - * Align Pad Align Pad Align Pad - * 3DES_192/CBC X X X X X X - * 3DES_192/ECB X X - * AES_256/CBC X X X X X X - * AES_256/ECB X X X X - * AES_192/CBC X X X X - * AES_192/ECB X X X - * AES_128/CBC X X X X - * AES_128/ECB X X X + * OpenSSL CommonCrypto NSS Interop + * Align Pad Align Pad Align Pad Align Pad + * 3DES_192/CBC X X X X X X X X + * 3DES_192/ECB X X X X + * AES_256/CBC X X X X X X X X + * AES_256/ECB X X X X X X + * AES_192/CBC X X X X X X + * AES_192/ECB X X X X X + * AES_128/CBC X X X X X X + * AES_128/ECB X X X X X * * Conclusion: for padded data, use 3DES_192/CBC or AES_256/CBC. For * aligned data, use 3DES_192/CBC, AES_256/CBC or AES_256/ECB. @@ -123,6 +127,48 @@ typedef struct apr_crypto_config_t apr_crypto_config_t; typedef struct apr_crypto_key_t apr_crypto_key_t; typedef struct apr_crypto_block_t apr_crypto_block_t; +typedef struct apr_crypto_block_key_type_t { + apr_crypto_block_key_type_e type; + int keysize; + int blocksize; + int ivsize; +} apr_crypto_block_key_type_t; + +typedef struct apr_crypto_block_key_mode_t { + apr_crypto_block_key_mode_e mode; +} apr_crypto_block_key_mode_t; + +typedef struct apr_crypto_passphrase_t { + const char *pass; + apr_size_t passLen; + const unsigned char * salt; + apr_size_t saltLen; + int iterations; +} apr_crypto_passphrase_t; + +typedef struct apr_crypto_secret_t { + const unsigned char *secret; + apr_size_t secretLen; +} apr_crypto_secret_t; + +typedef enum { + /** Key is derived from a passphrase */ + APR_CRYPTO_KTYPE_PASSPHRASE = 1, + /** Key is derived from a raw key */ + APR_CRYPTO_KTYPE_SECRET = 2, +} apr_crypto_key_type; + +typedef struct apr_crypto_key_rec_t { + apr_crypto_key_type ktype; + apr_crypto_block_key_type_e type; + apr_crypto_block_key_mode_e mode; + int pad; + union { + apr_crypto_passphrase_t passphrase; + apr_crypto_secret_t secret; + } k; +} apr_crypto_key_rec_t; + /** * @brief Perform once-only initialisation. Call once only. * @@ -132,8 +178,7 @@ typedef struct apr_crypto_block_t apr_crypto_block_t; APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool); /** - * @brief Register a cleanup to zero out the buffer provided - * when the pool is cleaned up. + * @brief Zero out the buffer provided when the pool is cleaned up. * * @param pool - pool to register the cleanup * @param buffer - buffer to zero out @@ -142,6 +187,27 @@ APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool); APU_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool, void *buffer, apr_size_t size); +/** + * @brief Always zero out the buffer provided, without being optimized out by + * the compiler. + * + * @param buffer - buffer to zero out + * @param size - size of the buffer to zero out + */ +APU_DECLARE(apr_status_t) apr_crypto_memzero(void *buffer, apr_size_t size); + +/** + * @brief Timing attacks safe buffers comparison, where the executing time does + * not depend on the bytes compared but solely on the number of bytes. + * + * @param buf1 - first buffer to compare + * @param buf2 - second buffer to compare + * @param size - size of the buffers to compare + * @return 1 if the buffers are equals, 0 otherwise. + */ +APU_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2, + apr_size_t size); + /** * @brief Get the driver struct for a name * @@ -205,7 +271,8 @@ APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f, /** * @brief Get a hash table of key types, keyed by the name of the type against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_type_t, which in turn begins with an + * integer. * * @param types - hashtable of key types keyed to constants. * @param f - encryption context @@ -216,7 +283,8 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types, /** * @brief Get a hash table of key modes, keyed by the name of the mode against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_mode_t, which in turn begins with an + * integer. * * @param modes - hashtable of key modes keyed to constants. * @param f - encryption context @@ -225,6 +293,25 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types, APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes, const apr_crypto_t *f); +/** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ +APU_DECLARE(apr_status_t) apr_crypto_key(apr_crypto_key_t **key, + const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p); + /** * @brief Create a key from the given passphrase. By default, the PBKDF2 * algorithm is used to generate the key from the passphrase. It is expected @@ -252,6 +339,7 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes, * is not supported by the particular backend. APR_EKEYTYPE if the key type is * not known. APR_EPADDING if padding was requested but is not supported. * APR_ENOTIMPL if not implemented. + * @deprecated Replaced by apr_crypto_key(). */ APU_DECLARE(apr_status_t) apr_crypto_passphrase(apr_crypto_key_t **key, apr_size_t *ivSize, const char *pass, apr_size_t passLen, diff --git a/contrib/apr-util/include/apr_dbd.h b/contrib/apr-util/include/apr_dbd.h index 3a334b73e2b3..9912612b9aff 100644 --- a/contrib/apr-util/include/apr_dbd.h +++ b/contrib/apr-util/include/apr_dbd.h @@ -136,9 +136,6 @@ APU_DECLARE(apr_status_t) apr_dbd_get_driver(apr_pool_t *pool, const char *name, * "group" determines which group from configuration file to use (see * MYSQL_READ_DEFAULT_GROUP option of mysql_options() in MySQL manual). * Reconnect is set to 1 by default (i.e. true). - * @remarks FreeTDS: the params can have "username", "password", "appname", - * "dbname", "host", "charset", "lang" and "server" keys, each followed by an - * equal sign and a value. */ APU_DECLARE(apr_status_t) apr_dbd_open_ex(const apr_dbd_driver_t *driver, apr_pool_t *pool, const char *params, diff --git a/contrib/apr-util/include/apr_ldap.hwc b/contrib/apr-util/include/apr_ldap.hwc new file mode 100644 index 000000000000..7922515edaa8 --- /dev/null +++ b/contrib/apr-util/include/apr_ldap.hwc @@ -0,0 +1,197 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * apr_ldap.h is generated from apr_ldap.h.in by configure -- do not edit apr_ldap.h + */ +/** + * @file apr_ldap.h + * @brief APR-UTIL LDAP + */ +#ifndef APU_LDAP_H +#define APU_LDAP_H + +/** + * @defgroup APR_Util_LDAP LDAP + * @ingroup APR_Util + * @{ + */ + +/* this will be defined if LDAP support was compiled into apr-util */ +#define APR_HAS_LDAP @apr_has_ldap_10@ + +/* identify the LDAP toolkit used */ +#define APR_HAS_NETSCAPE_LDAPSDK 0 +#define APR_HAS_SOLARIS_LDAPSDK 0 +#define APR_HAS_NOVELL_LDAPSDK 0 +#define APR_HAS_MOZILLA_LDAPSDK 0 +#define APR_HAS_OPENLDAP_LDAPSDK 0 +#define APR_HAS_MICROSOFT_LDAPSDK 1 +#define APR_HAS_TIVOLI_LDAPSDK 0 +#define APR_HAS_ZOS_LDAPSDK 0 +#define APR_HAS_OTHER_LDAPSDK 0 + + +/* + * Handle the case when LDAP is enabled + */ +#if APR_HAS_LDAP + +/* + * The following #defines are DEPRECATED and should not be used for + * anything. They remain to maintain binary compatibility. + * The original code defined the OPENLDAP SDK as present regardless + * of what really was there, which was way bogus. In addition, the + * apr_ldap_url_parse*() functions have been rewritten specifically for + * APR, so the APR_HAS_LDAP_URL_PARSE macro is forced to zero. + */ +#if APR_HAS_TIVOLI_LDAPSDK +#define APR_HAS_LDAP_SSL 0 +#else +#define APR_HAS_LDAP_SSL 1 +#endif +#define APR_HAS_LDAP_URL_PARSE 0 + +#if APR_HAS_OPENLDAP_LDAPSDK && !defined(LDAP_DEPRECATED) +/* Ensure that the "deprecated" interfaces are still exposed + * with OpenLDAP >= 2.3; these were exposed by default in earlier + * releases. */ +#define LDAP_DEPRECATED 1 +#endif + +/* + * Include the standard LDAP header files. + */ + +#include + + +/* + * Detected standard functions + */ +#define APR_HAS_LDAPSSL_CLIENT_INIT 0 +#define APR_HAS_LDAPSSL_CLIENT_DEINIT 0 +#define APR_HAS_LDAPSSL_ADD_TRUSTED_CERT 0 +#define APR_HAS_LDAP_START_TLS_S 0 +#define APR_HAS_LDAP_SSLINIT 1 +#define APR_HAS_LDAPSSL_INIT 0 +#define APR_HAS_LDAPSSL_INSTALL_ROUTINES 0 + + +/* + * Make sure the secure LDAP port is defined + */ +#ifndef LDAPS_PORT +#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */ +#endif + + +/* + * For ldap function calls that input a size limit on the number of returned elements + * Some SDKs do not have the define for LDAP_DEFAULT_LIMIT (-1) or LDAP_NO_LIMIT (0) + * LDAP_DEFAULT_LIMIT is preferred as it allows inheritance from whatever the SDK + * or process is configured for. + */ +#ifdef LDAP_DEFAULT_LIMIT +#define APR_LDAP_SIZELIMIT LDAP_DEFAULT_LIMIT +#else +#ifdef LDAP_NO_LIMIT +#define APR_LDAP_SIZELIMIT LDAP_NO_LIMIT +#endif +#endif + +#ifndef APR_LDAP_SIZELIMIT +#define APR_LDAP_SIZELIMIT 0 /* equivalent to LDAP_NO_LIMIT, and what goes on the wire */ +#endif + +/* + * z/OS is missing some defines + */ +#ifndef LDAP_VERSION_MAX +#define LDAP_VERSION_MAX LDAP_VERSION +#endif +#if APR_HAS_ZOS_LDAPSDK +#define LDAP_VENDOR_NAME "IBM z/OS" +#endif + +/* Note: Macros defining const casting has been removed in APR v1.0, + * pending real support for LDAP v2.0 toolkits. + * + * In the mean time, please use an LDAP v3.0 toolkit. + */ +#if LDAP_VERSION_MAX <= 2 +#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit. +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * This structure allows the C LDAP API error codes to be returned + * along with plain text error messages that explain to us mere mortals + * what really happened. + */ +typedef struct apr_ldap_err_t { + const char *reason; + const char *msg; + int rc; +} apr_ldap_err_t; + +#ifdef __cplusplus +} +#endif + +/* The MS SDK returns LDAP_UNAVAILABLE when the backend has closed the connection + * between LDAP calls. Protect with APR_HAS_MICROSOFT_LDAPSDK in case someone + * manually chooses another SDK on Windows + */ +#if APR_HAS_MICROSOFT_LDAPSDK +#define APR_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \ + || (s) == LDAP_UNAVAILABLE) +#else +#define APR_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN) +#endif + +/* These symbols are not actually exported in a DSO build, but mapped into + * a private exported function array for apr_ldap_stub to bind dynamically. + * Rename them appropriately to protect the global namespace. + */ +#ifdef APU_DSO_LDAP_BUILD + +#define apr_ldap_info apr__ldap_info +#define apr_ldap_init apr__ldap_init +#define apr_ldap_ssl_init apr__ldap_ssl_init +#define apr_ldap_ssl_deinit apr__ldap_ssl_deinit +#define apr_ldap_get_option apr__ldap_get_option +#define apr_ldap_set_option apr__ldap_set_option +#define apr_ldap_rebind_init apr__ldap_rebind_init +#define apr_ldap_rebind_add apr__ldap_rebind_add +#define apr_ldap_rebind_remove apr__ldap_rebind_remove + +#define APU_DECLARE_LDAP(type) type +#else +#define APU_DECLARE_LDAP(type) APU_DECLARE(type) +#endif + +#include "apr_ldap_url.h" +#include "apr_ldap_init.h" +#include "apr_ldap_option.h" +#include "apr_ldap_rebind.h" + +/** @} */ +#endif /* APR_HAS_LDAP */ +#endif /* APU_LDAP_H */ diff --git a/contrib/apr-util/include/apr_redis.h b/contrib/apr-util/include/apr_redis.h new file mode 100644 index 000000000000..66a828b0a901 --- /dev/null +++ b/contrib/apr-util/include/apr_redis.h @@ -0,0 +1,459 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file apr_redis.h + * @brief Client interface for redis + * @remark To use this interface you must have a separate redis + * for more information. + */ + +#ifndef APR_REDIS_H +#define APR_REDIS_H + +#include "apr.h" +#include "apr_pools.h" +#include "apr_time.h" +#include "apr_strings.h" +#include "apr_network_io.h" +#include "apr_ring.h" +#include "apr_buckets.h" +#include "apr_reslist.h" +#include "apr_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef RC_DEFAULT_SERVER_PORT +#define RC_DEFAULT_SERVER_PORT 6379 +#endif + +#ifndef RC_DEFAULT_SERVER_MIN +#define RC_DEFAULT_SERVER_MIN 0 +#endif + +#ifndef RC_DEFAULT_SERVER_SMAX +#define RC_DEFAULT_SERVER_SMAX 1 +#endif + +#ifndef RC_DEFAULT_SERVER_TTL +#define RC_DEFAULT_SERVER_TTL 600 +#endif + +/** + * @defgroup APR_Util_RC Redis Client Routines + * @ingroup APR_Util + * @{ + */ + +/** Specifies the status of a redis server */ +typedef enum +{ + APR_RC_SERVER_LIVE, /**< Server is alive and responding to requests */ + APR_RC_SERVER_DEAD /**< Server is not responding to requests */ +} apr_redis_server_status_t; + +/** Opaque redis client connection object */ +typedef struct apr_redis_conn_t apr_redis_conn_t; + +/** Redis Server Info Object */ +typedef struct apr_redis_server_t apr_redis_server_t; +struct apr_redis_server_t +{ + const char *host; /**< Hostname of this Server */ + apr_port_t port; /**< Port of this Server */ + apr_redis_server_status_t status; /**< @see apr_redis_server_status_t */ +#if APR_HAS_THREADS || defined(DOXYGEN) + apr_reslist_t *conns; /**< Resource list of actual client connections */ +#else + apr_redis_conn_t *conn; +#endif + apr_pool_t *p; /** Pool to use for private allocations */ +#if APR_HAS_THREADS + apr_thread_mutex_t *lock; +#endif + apr_time_t btime; + apr_uint32_t rwto; + struct + { + int major; + int minor; + int patch; + char *number; + } version; +}; + +typedef struct apr_redis_t apr_redis_t; + +/* Custom hash callback function prototype, user for server selection. +* @param baton user selected baton +* @param data data to hash +* @param data_len length of data +*/ +typedef apr_uint32_t (*apr_redis_hash_func)(void *baton, + const char *data, + const apr_size_t data_len); +/* Custom Server Select callback function prototype. +* @param baton user selected baton +* @param rc redis instance, use rc->live_servers to select a node +* @param hash hash of the selected key. +*/ +typedef apr_redis_server_t* (*apr_redis_server_func)(void *baton, + apr_redis_t *rc, + const apr_uint32_t hash); + +/** Container for a set of redis servers */ +struct apr_redis_t +{ + apr_uint32_t flags; /**< Flags, Not currently used */ + apr_uint16_t nalloc; /**< Number of Servers Allocated */ + apr_uint16_t ntotal; /**< Number of Servers Added */ + apr_redis_server_t **live_servers; /**< Array of Servers */ + apr_pool_t *p; /** Pool to use for allocations */ + void *hash_baton; + apr_redis_hash_func hash_func; + void *server_baton; + apr_redis_server_func server_func; +}; + +/** + * Creates a crc32 hash used to split keys between servers + * @param rc The redis client object to use + * @param data Data to be hashed + * @param data_len Length of the data to use + * @return crc32 hash of data + * @remark The crc32 hash is not compatible with old redisd clients. + */ +APU_DECLARE(apr_uint32_t) apr_redis_hash(apr_redis_t *rc, + const char *data, + const apr_size_t data_len); + +/** + * Pure CRC32 Hash. Used by some clients. + */ +APU_DECLARE(apr_uint32_t) apr_redis_hash_crc32(void *baton, + const char *data, + const apr_size_t data_len); + +/** + * hash compatible with the standard Perl Client. + */ +APU_DECLARE(apr_uint32_t) apr_redis_hash_default(void *baton, + const char *data, + const apr_size_t data_len); + +/** + * Picks a server based on a hash + * @param rc The redis client object to use + * @param hash Hashed value of a Key + * @return server that controls specified hash + * @see apr_redis_hash + */ +APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash(apr_redis_t *rc, + const apr_uint32_t hash); + +/** + * server selection compatible with the standard Perl Client. + */ +APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash_default(void *baton, + apr_redis_t *rc, + const apr_uint32_t hash); + +/** + * Adds a server to a client object + * @param rc The redis client object to use + * @param server Server to add + * @remark Adding servers is not thread safe, and should be done once at startup. + * @warning Changing servers after startup may cause keys to go to + * different servers. + */ +APU_DECLARE(apr_status_t) apr_redis_add_server(apr_redis_t *rc, + apr_redis_server_t *server); + + +/** + * Finds a Server object based on a hostname/port pair + * @param rc The redis client object to use + * @param host Hostname of the server + * @param port Port of the server + * @return Server with matching Hostname and Port, or NULL if none was found. + */ +APU_DECLARE(apr_redis_server_t *) apr_redis_find_server(apr_redis_t *rc, + const char *host, + apr_port_t port); + +/** + * Enables a Server for use again + * @param rc The redis client object to use + * @param rs Server to Activate + */ +APU_DECLARE(apr_status_t) apr_redis_enable_server(apr_redis_t *rc, + apr_redis_server_t *rs); + + +/** + * Disable a Server + * @param rc The redis client object to use + * @param rs Server to Disable + */ +APU_DECLARE(apr_status_t) apr_redis_disable_server(apr_redis_t *rc, + apr_redis_server_t *rs); + +/** + * Creates a new Server Object + * @param p Pool to use + * @param host hostname of the server + * @param port port of the server + * @param min minimum number of client sockets to open + * @param smax soft maximum number of client connections to open + * @param max hard maximum number of client connections + * @param ttl time to live in microseconds of a client connection + * @param rwto r/w timeout value in seconds of a client connection + * @param ns location of the new server object + * @see apr_reslist_create + * @remark min, smax, and max are only used when APR_HAS_THREADS + */ +APU_DECLARE(apr_status_t) apr_redis_server_create(apr_pool_t *p, + const char *host, + apr_port_t port, + apr_uint32_t min, + apr_uint32_t smax, + apr_uint32_t max, + apr_uint32_t ttl, + apr_uint32_t rwto, + apr_redis_server_t **ns); +/** + * Creates a new redisd client object + * @param p Pool to use + * @param max_servers maximum number of servers + * @param flags Not currently used + * @param rc location of the new redis client object + */ +APU_DECLARE(apr_status_t) apr_redis_create(apr_pool_t *p, + apr_uint16_t max_servers, + apr_uint32_t flags, + apr_redis_t **rc); + +/** + * Gets a value from the server, allocating the value out of p + * @param rc client to use + * @param p Pool to use + * @param key null terminated string containing the key + * @param baton location of the allocated value + * @param len length of data at baton + * @param flags any flags set by the client for this key + * @return + */ +APU_DECLARE(apr_status_t) apr_redis_getp(apr_redis_t *rc, + apr_pool_t *p, + const char* key, + char **baton, + apr_size_t *len, + apr_uint16_t *flags); + +/** + * Sets a value by key on the server + * @param rc client to use + * @param key null terminated string containing the key + * @param baton data to store on the server + * @param data_size length of data at baton + * @param flags any flags set by the client for this key + */ +APU_DECLARE(apr_status_t) apr_redis_set(apr_redis_t *rc, + const char *key, + char *baton, + const apr_size_t data_size, + apr_uint16_t flags); + +/** + * Sets a value by key on the server + * @param rc client to use + * @param key null terminated string containing the key + * @param baton data to store on the server + * @param data_size length of data at baton + * @param timeout time in seconds for the data to live on the server + * @param flags any flags set by the client for this key + */ +APU_DECLARE(apr_status_t) apr_redis_setex(apr_redis_t *rc, + const char *key, + char *baton, + const apr_size_t data_size, + apr_uint32_t timeout, + apr_uint16_t flags); + +/** + * Deletes a key from a server + * @param rc client to use + * @param key null terminated string containing the key + * @param timeout time for the delete to stop other clients from adding + */ +APU_DECLARE(apr_status_t) apr_redis_delete(apr_redis_t *rc, + const char *key, + apr_uint32_t timeout); + +/** + * Query a server's version + * @param rs server to query + * @param p Pool to allocate answer from + * @param baton location to store server version string + */ +APU_DECLARE(apr_status_t) apr_redis_version(apr_redis_server_t *rs, + apr_pool_t *p, + char **baton); + +/** + * Query a server's INFO + * @param rs server to query + * @param p Pool to allocate answer from + * @param baton location to store server INFO response string + */ +APU_DECLARE(apr_status_t) apr_redis_info(apr_redis_server_t *rs, + apr_pool_t *p, + char **baton); + +/** + * Increments a value + * @param rc client to use + * @param key null terminated string containing the key + * @param inc number to increment by + * @param new_value new value after incrementing + */ +APU_DECLARE(apr_status_t) apr_redis_incr(apr_redis_t *rc, + const char *key, + apr_int32_t inc, + apr_uint32_t *new_value); +/** + * Decrements a value + * @param rc client to use + * @param key null terminated string containing the key + * @param inc number to decrement by + * @param new_value new value after decrementing + */ +APU_DECLARE(apr_status_t) apr_redis_decr(apr_redis_t *rc, + const char *key, + apr_int32_t inc, + apr_uint32_t *new_value); + + +/** + * Pings the server + * @param rs Server to ping + */ +APU_DECLARE(apr_status_t) apr_redis_ping(apr_redis_server_t *rs); + +/** + * Gets multiple values from the server, allocating the values out of p + * @param rc client to use + * @param temp_pool Pool used for temporary allocations. May be cleared inside this + * call. + * @param data_pool Pool used to allocate data for the returned values. + * @param values hash of apr_redis_value_t keyed by strings, contains the + * result of the multiget call. + * @return + */ +APU_DECLARE(apr_status_t) apr_redis_multgetp(apr_redis_t *rc, + apr_pool_t *temp_pool, + apr_pool_t *data_pool, + apr_hash_t *values); + +typedef enum +{ + APR_RS_SERVER_MASTER, /**< Server is a master */ + APR_RS_SERVER_SLAVE, /**< Server is a slave */ + APR_RS_SERVER_UNKNOWN /**< Server role is unknown */ +} apr_redis_server_role_t; + +typedef struct +{ +/* # Server */ + /** Major version number of this server */ + apr_uint32_t major; + /** Minor version number of this server */ + apr_uint32_t minor; + /** Patch version number of this server */ + apr_uint32_t patch; + /** Process id of this server process */ + apr_uint32_t process_id; + /** Number of seconds this server has been running */ + apr_uint32_t uptime_in_seconds; + /** Bitsize of the arch on the current machine */ + apr_uint32_t arch_bits; + +/* # Clients */ + /** Number of connected clients */ + apr_uint32_t connected_clients; + /** Number of blocked clients */ + apr_uint32_t blocked_clients; + +/* # Memory */ + /** Max memory of this server */ + apr_uint64_t maxmemory; + /** Amount of used memory */ + apr_uint64_t used_memory; + /** Total memory available on this server */ + apr_uint64_t total_system_memory; + +/* # Stats */ + /** Total connections received */ + apr_uint64_t total_connections_received; + /** Total commands processed */ + apr_uint64_t total_commands_processed; + /** Total commands rejected */ + apr_uint64_t rejected_connections; + /** Total net input bytes */ + apr_uint64_t total_net_input_bytes; + /** Total net output bytes */ + apr_uint64_t total_net_output_bytes; + /** Keyspace hits */ + apr_uint64_t keyspace_hits; + /** Keyspace misses */ + apr_uint64_t keyspace_misses; + +/* # Replication */ + /** Role */ + apr_redis_server_role_t role; + /** Number of connected slave */ + apr_uint32_t connected_slaves; + +/* # CPU */ + /** Accumulated CPU user time for this process */ + apr_uint32_t used_cpu_sys; + /** Accumulated CPU system time for this process */ + apr_uint32_t used_cpu_user; + +/* # Cluster */ + /** Is cluster enabled */ + apr_uint32_t cluster_enabled; +} apr_redis_stats_t; + +/** + * Query a server for statistics + * @param rs server to query + * @param p Pool to allocate answer from + * @param stats location of the new statistics structure + */ +APU_DECLARE(apr_status_t) apr_redis_stats(apr_redis_server_t *rs, + apr_pool_t *p, + apr_redis_stats_t **stats); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APR_REDIS_H */ diff --git a/contrib/apr-util/include/apr_siphash.h b/contrib/apr-util/include/apr_siphash.h new file mode 100644 index 000000000000..42aa8874b0be --- /dev/null +++ b/contrib/apr-util/include/apr_siphash.h @@ -0,0 +1,148 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + SipHash reference C implementation + Copyright (c) 2012-2014 Jean-Philippe Aumasson + + Copyright (c) 2012-2014 Daniel J. Bernstein + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + You should have received a copy of the CC0 Public Domain Dedication along + with this software. If not, see + . + */ + +#ifndef APR_SIPHASH_H +#define APR_SIPHASH_H + +#include "apr.h" +#include "apu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file apr_siphash.h + * @brief APR-UTIL siphash library + * "SipHash-c-d is a family of pseudorandom functions (a.k.a. keyed + * hash functions) optimized for speed on short messages", designed by + * Jean-Philippe Aumasson and Daniel J. Bernstein. It generates a 64bit + * hash (or MAC) from the message and a 128bit key. + * See http://cr.yp.to/siphash/siphash-20120620.pdf for the details, + * c is the number of compression rounds, d the number of finalization + * rounds; we also define fast implementations for c = 2 with d = 4 (aka + * siphash-2-4), and c = 4 with d = 8 (aka siphash-4-8), as recommended + * parameters per the authors. + */ + +/** size of the siphash digest */ +#define APR_SIPHASH_DSIZE 8 + +/** size of the siphash key */ +#define APR_SIPHASH_KSIZE 16 + + +/** + * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key. + * @param src The message + * @param len The length of the message + * @param key The secret key + * @param c The number of compression rounds + * @param d The number of finalization rounds + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE], + unsigned int c, unsigned int d); + +/** + * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly + * unaligned buffer (using the little endian representation as defined by the + * authors for interoperabilty) usable as a MAC. + * @param out The output buffer (or MAC) + * @param src The message + * @param len The length of the message + * @param key The secret key + * @param c The number of compression rounds + * @param d The number of finalization rounds + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE], + unsigned int c, unsigned int d); + +/** + * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key. + * @param src The message to hash + * @param len The length of the message + * @param key The secret key + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]); + +/** + * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly + * unaligned buffer (using the little endian representation as defined by the + * authors for interoperabilty) usable as a MAC. + * @param out The output buffer (or MAC) + * @param src The message + * @param len The length of the message + * @param key The secret key + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]); + +/** + * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key. + * @param src The message + * @param len The length of the message + * @param key The secret key + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]); + +/** + * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash + * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly + * unaligned buffer (using the little endian representation as defined by the + * authors for interoperabilty) usable as a MAC. + * @param out The output buffer (or MAC) + * @param src The message + * @param len The length of the message + * @param key The secret key + * @return The hash value as a 64bit unsigned integer + */ +APU_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE], + const void *src, apr_size_t len, + const unsigned char key[APR_SIPHASH_KSIZE]); + +#ifdef __cplusplus +} +#endif + +#endif /* APR_SIPHASH_H */ diff --git a/contrib/apr-util/include/apr_xml.h b/contrib/apr-util/include/apr_xml.h index ac7f003b42df..87a696cca739 100644 --- a/contrib/apr-util/include/apr_xml.h +++ b/contrib/apr-util/include/apr_xml.h @@ -276,6 +276,7 @@ APU_DECLARE(char *) apr_xml_parser_geterror(apr_xml_parser *parser, * APR_XML_X2T_INNER contents only * APR_XML_X2T_LANG_INNER xml:lang + inner contents * APR_XML_X2T_FULL_NS_LANG FULL + ns defns + xml:lang + * APR_XML_X2T_PARSED original prefixes * * @param namespaces The namespace of the current XML element * @param ns_map Namespace mapping @@ -292,6 +293,7 @@ APU_DECLARE(void) apr_xml_to_text(apr_pool_t *p, const apr_xml_elem *elem, #define APR_XML_X2T_INNER 1 /**< contents only */ #define APR_XML_X2T_LANG_INNER 2 /**< xml:lang + inner contents */ #define APR_XML_X2T_FULL_NS_LANG 3 /**< FULL + ns defns + xml:lang */ +#define APR_XML_X2T_PARSED 4 /**< original prefixes */ /** * empty XML element diff --git a/contrib/apr-util/include/apu.h.in b/contrib/apr-util/include/apu.h.in index 82380cc21bd5..184682d31c15 100644 --- a/contrib/apr-util/include/apu.h.in +++ b/contrib/apr-util/include/apu.h.in @@ -113,12 +113,12 @@ #define APU_HAVE_SQLITE3 @apu_have_sqlite3@ #define APU_HAVE_SQLITE2 @apu_have_sqlite2@ #define APU_HAVE_ORACLE @apu_have_oracle@ -#define APU_HAVE_FREETDS @apu_have_freetds@ #define APU_HAVE_ODBC @apu_have_odbc@ #define APU_HAVE_CRYPTO @apu_have_crypto@ #define APU_HAVE_OPENSSL @apu_have_openssl@ #define APU_HAVE_NSS @apu_have_nss@ +#define APU_HAVE_COMMONCRYPTO @apu_have_commoncrypto@ #define APU_HAVE_APR_ICONV @have_apr_iconv@ #define APU_HAVE_ICONV @have_iconv@ diff --git a/contrib/apr-util/include/apu.hnw b/contrib/apr-util/include/apu.hnw index 31c0dfb41553..0bc3a2cb9b04 100644 --- a/contrib/apr-util/include/apu.hnw +++ b/contrib/apr-util/include/apu.hnw @@ -104,7 +104,6 @@ #define APU_HAVE_SQLITE3 0 #define APU_HAVE_SQLITE2 0 #define APU_HAVE_ORACLE 0 -#define APU_HAVE_FREETDS 0 #define APU_HAVE_ODBC 0 #endif @@ -113,6 +112,7 @@ #ifndef APU_DSO_MODULE_BUILD #define APU_HAVE_OPENSSL 0 #define APU_HAVE_NSS 0 +#define APU_HAVE_COMMONCRYPTO 0 #endif #define APU_HAVE_APR_ICONV 0 diff --git a/contrib/apr-util/include/apu.hw b/contrib/apr-util/include/apu.hw index a6cde01a3a84..21fbedff1aa1 100644 --- a/contrib/apr-util/include/apu.hw +++ b/contrib/apr-util/include/apu.hw @@ -127,7 +127,6 @@ #define APU_HAVE_SQLITE3 0 #define APU_HAVE_SQLITE2 0 #define APU_HAVE_ORACLE 0 -#define APU_HAVE_FREETDS 0 #define APU_HAVE_ODBC 1 #endif @@ -136,6 +135,7 @@ #ifndef APU_DSO_MODULE_BUILD #define APU_HAVE_OPENSSL 0 #define APU_HAVE_NSS 0 +#define APU_HAVE_COMMONCRYPTO 0 #endif #define APU_HAVE_APR_ICONV 1 diff --git a/contrib/apr-util/include/apu.hwc b/contrib/apr-util/include/apu.hwc new file mode 100644 index 000000000000..2c3fa00a59ba --- /dev/null +++ b/contrib/apr-util/include/apu.hwc @@ -0,0 +1,145 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * apu.h is duplicated from apu.hwc at build time -- do not edit apu.h + */ +/* @file apu.h + * @brief APR-Utility main file + */ +/** + * @defgroup APR_Util APR Utility Functions + * @{ + */ + + +#ifndef APU_H +#define APU_H + +/** + * APU_DECLARE_EXPORT is defined when building the APR-UTIL dynamic library, + * so that all public symbols are exported. + * + * APU_DECLARE_STATIC is defined when including the APR-UTIL public headers, + * to provide static linkage when the dynamic library may be unavailable. + * + * APU_DECLARE_STATIC and APU_DECLARE_EXPORT are left undefined when + * including the APR-UTIL public headers, to import and link the symbols from + * the dynamic APR-UTIL library and assure appropriate indirection and calling + * conventions at compile time. + */ + +/* Make sure we have our platform identifier macro defined we ask for later. + */ +#if defined(_WIN32) && !defined(WIN32) +#define WIN32 1 +#endif + +#if defined(DOXYGEN) || !defined(WIN32) +/** + * The public APR-UTIL functions are declared with APU_DECLARE(), so they may + * use the most appropriate calling convention. Public APR functions with + * variable arguments must use APU_DECLARE_NONSTD(). + * + * @fn APU_DECLARE(rettype) apr_func(args); + */ +#define APU_DECLARE(type) type +/** + * The public APR-UTIL functions using variable arguments are declared with + * APU_DECLARE_NONSTD(), as they must use the C language calling convention. + * + * @fn APU_DECLARE_NONSTD(rettype) apr_func(args, ...); + */ +#define APU_DECLARE_NONSTD(type) type +/** + * The public APR-UTIL variables are declared with APU_DECLARE_DATA. + * This assures the appropriate indirection is invoked at compile time. + * + * @fn APU_DECLARE_DATA type apr_variable; + * @note extern APU_DECLARE_DATA type apr_variable; syntax is required for + * declarations within headers to properly import the variable. + */ +#define APU_DECLARE_DATA +#elif defined(APU_DECLARE_STATIC) +#define APU_DECLARE(type) type __stdcall +#define APU_DECLARE_NONSTD(type) type __cdecl +#define APU_DECLARE_DATA +#elif defined(APU_DECLARE_EXPORT) +#define APU_DECLARE(type) __declspec(dllexport) type __stdcall +#define APU_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl +#define APU_DECLARE_DATA __declspec(dllexport) +#else +#define APU_DECLARE(type) __declspec(dllimport) type __stdcall +#define APU_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl +#define APU_DECLARE_DATA __declspec(dllimport) +#endif + +#if !defined(WIN32) || defined(APU_MODULE_DECLARE_STATIC) +/** + * Declare a dso module's exported module structure as APU_MODULE_DECLARE_DATA. + * + * Unless APU_MODULE_DECLARE_STATIC is defined at compile time, symbols + * declared with APU_MODULE_DECLARE_DATA are always exported. + * @code + * module APU_MODULE_DECLARE_DATA mod_tag + * @endcode + */ +#define APU_MODULE_DECLARE_DATA +#else +#define APU_MODULE_DECLARE_DATA __declspec(dllexport) +#endif + +/* + * we always have SDBM (it's in our codebase) + */ +#define APU_HAVE_SDBM 1 + +#ifndef APU_DSO_MODULE_BUILD +#define APU_HAVE_GDBM 0 +#define APU_HAVE_NDBM 0 +#define APU_HAVE_DB 0 + +#if APU_HAVE_DB +#define APU_HAVE_DB_VERSION 0 +#endif +#endif + +/* + * we always enable dynamic driver loads within apr_dbd + * Win32 always has odbc (it's always installed) + */ +#ifndef APU_DSO_MODULE_BUILD +#define APU_HAVE_PGSQL 0 +#define APU_HAVE_MYSQL 0 +#define APU_HAVE_SQLITE3 0 +#define APU_HAVE_SQLITE2 0 +#define APU_HAVE_ORACLE 0 +#define APU_HAVE_ODBC 1 +#endif + +#define APU_HAVE_CRYPTO @apu_have_crypto_10@ + +#ifndef APU_DSO_MODULE_BUILD +#define APU_HAVE_OPENSSL 0 +#define APU_HAVE_NSS 0 +#endif + +#define APU_HAVE_APR_ICONV @apu_have_apr_iconv_10@ +#define APU_HAVE_ICONV 0 +#define APR_HAS_XLATE (APU_HAVE_APR_ICONV || APU_HAVE_ICONV) + +#endif /* APU_H */ +/** @} */ diff --git a/contrib/apr-util/include/apu_version.h b/contrib/apr-util/include/apu_version.h index 8d976291ff6d..e4fb2e64e9ec 100644 --- a/contrib/apr-util/include/apu_version.h +++ b/contrib/apr-util/include/apu_version.h @@ -38,7 +38,7 @@ */ -#define APU_COPYRIGHT "Copyright (c) 2000-2014 The Apache Software " \ +#define APU_COPYRIGHT "Copyright (c) 2000-2016 The Apache Software " \ "Foundation or its licensors, as applicable." /* The numeric compile-time version constants. These constants are the @@ -56,20 +56,20 @@ * Minor API changes that do not cause binary compatibility problems. * Reset to 0 when upgrading APU_MAJOR_VERSION */ -#define APU_MINOR_VERSION 5 +#define APU_MINOR_VERSION 6 /** patch level * The Patch Level never includes API changes, simply bug fixes. * Reset to 0 when upgrading APR_MINOR_VERSION */ -#define APU_PATCH_VERSION 4 +#define APU_PATCH_VERSION 1 /** * The symbol APU_IS_DEV_VERSION is only defined for internal, * "development" copies of APU. It is undefined for released versions * of APU. */ -/* #define APU_IS_DEV_VERSION */ +/* #undef APU_IS_DEV_VERSION */ #if defined(APU_IS_DEV_VERSION) || defined(DOXYGEN) diff --git a/contrib/apr-util/include/private/apr_crypto_internal.h b/contrib/apr-util/include/private/apr_crypto_internal.h index 5da92e558879..1ea838bfb7d1 100644 --- a/contrib/apr-util/include/private/apr_crypto_internal.h +++ b/contrib/apr-util/include/private/apr_crypto_internal.h @@ -59,7 +59,7 @@ struct apr_crypto_driver_t { /** * @brief Get a hash table of key types, keyed by the name of the type against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_type_t. * * @param types - hashtable of key types keyed to constants. * @param f - encryption context @@ -70,7 +70,7 @@ struct apr_crypto_driver_t { /** * @brief Get a hash table of key modes, keyed by the name of the mode against - * an integer pointer constant. + * a pointer to apr_crypto_block_key_mode_t. * * @param modes - hashtable of key modes keyed to constants. * @param f - encryption context @@ -267,6 +267,25 @@ struct apr_crypto_driver_t { */ apr_status_t (*error)(const apu_err_t **result, const apr_crypto_t *f); + /** + * @brief Create a key from the provided secret or passphrase. The key is cleaned + * up when the context is cleaned, and may be reused with multiple encryption + * or decryption operations. + * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If + * *key is not NULL, *key must point at a previously created structure. + * @param key The key returned, see note. + * @param rec The key record, from which the key will be derived. + * @param f The context to use. + * @param p The pool to use. + * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend + * error occurred while generating the key. APR_ENOCIPHER if the type or mode + * is not supported by the particular backend. APR_EKEYTYPE if the key type is + * not known. APR_EPADDING if padding was requested but is not supported. + * APR_ENOTIMPL if not implemented. + */ + apr_status_t (*key)(apr_crypto_key_t **key, const apr_crypto_key_rec_t *rec, + const apr_crypto_t *f, apr_pool_t *p); + }; #endif diff --git a/contrib/apr-util/include/private/apu_config.h.in b/contrib/apr-util/include/private/apu_config.h.in index 4d39f8a09475..0e008d04941f 100644 --- a/contrib/apr-util/include/private/apu_config.h.in +++ b/contrib/apr-util/include/private/apu_config.h.in @@ -24,6 +24,10 @@ /* Define if CODESET is defined in langinfo.h */ #undef HAVE_CODESET +/* Define to 1 if you have the header + file. */ +#undef HAVE_COMMONCRYPTO_COMMONKEYDERIVATION_H + /* Define to 1 if you have the `crypt_r' function. */ #undef HAVE_CRYPT_R @@ -34,8 +38,8 @@ /* Define if expat.h is available */ #undef HAVE_EXPAT_H -/* Define to 1 if you have the header file. */ -#undef HAVE_FREETDS_SYBDB_H +/* Define if explicit_bzero function is supported */ +#undef HAVE_EXPLICIT_BZERO /* Define to 1 if you have the header file. */ #undef HAVE_ICONV_H @@ -61,6 +65,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define if memset_s function is supported */ +#undef HAVE_MEMSET_S + /* Define to 1 if you have the header file. */ #undef HAVE_MYSQL_H @@ -130,9 +137,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the header file. */ -#undef HAVE_SYBDB_H - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H @@ -142,6 +146,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define if compiler handles weak symbols */ +#undef HAVE_WEAK_SYMBOLS + /* Define if xmlparse/xmlparse.h is available */ #undef HAVE_XMLPARSE_XMLPARSE_H diff --git a/contrib/apr-util/memcache/apr_memcache.c b/contrib/apr-util/memcache/apr_memcache.c index b9922fb767a0..ae41b2efd41a 100644 --- a/contrib/apr-util/memcache/apr_memcache.c +++ b/contrib/apr-util/memcache/apr_memcache.c @@ -356,7 +356,7 @@ mc_conn_construct(void **conn_, void *params, apr_pool_t *pool) return rv; } - conn->buffer = apr_palloc(conn->p, BUFFER_SIZE); + conn->buffer = apr_palloc(conn->p, BUFFER_SIZE + 1); conn->blen = 0; conn->ms = ms; @@ -728,6 +728,26 @@ apr_memcache_replace(apr_memcache_t *mc, } +/* + * Parses a decimal size from size_str, returning the value in *size. + * Returns 1 if parsing was successful, 0 if parsing failed. + */ +static int parse_size(const char *size_str, apr_size_t *size) +{ + char *endptr; + long size_as_long; + + errno = 0; + size_as_long = strtol(size_str, &endptr, 10); + if ((size_as_long < 0) || (errno != 0) || (endptr == size_str) || + (endptr[0] != ' ' && (endptr[0] != '\r' || endptr[1] != '\n'))) { + return 0; + } + + *size = (unsigned long)size_as_long; + return 1; +} + APU_DECLARE(apr_status_t) apr_memcache_getp(apr_memcache_t *mc, apr_pool_t *p, @@ -796,13 +816,10 @@ apr_memcache_getp(apr_memcache_t *mc, } length = apr_strtok(NULL, " ", &last); - if (length) { - len = strtol(length, (char **)NULL, 10); - } - - if (len == 0 ) { - *new_length = 0; - *baton = NULL; + if (!length || !parse_size(length, &len)) { + ms_bad_conn(ms, conn); + apr_memcache_disable_server(mc, ms); + return APR_EGENERAL; } else { apr_bucket_brigade *bbb; @@ -810,7 +827,6 @@ apr_memcache_getp(apr_memcache_t *mc, /* eat the trailing \r\n */ rv = apr_brigade_partition(conn->bb, len+2, &e); - if (rv != APR_SUCCESS) { ms_bad_conn(ms, conn); apr_memcache_disable_server(mc, ms); @@ -820,17 +836,14 @@ apr_memcache_getp(apr_memcache_t *mc, bbb = apr_brigade_split(conn->bb, e); rv = apr_brigade_pflatten(conn->bb, baton, &len, p); - if (rv != APR_SUCCESS) { ms_bad_conn(ms, conn); - apr_memcache_disable_server(mc, ms); return rv; } rv = apr_brigade_destroy(conn->bb); if (rv != APR_SUCCESS) { ms_bad_conn(ms, conn); - apr_memcache_disable_server(mc, ms); return rv; } @@ -848,14 +861,18 @@ apr_memcache_getp(apr_memcache_t *mc, } if (strncmp(MS_END, conn->buffer, MS_END_LEN) != 0) { - rv = APR_EGENERAL; + ms_bad_conn(ms, conn); + apr_memcache_disable_server(mc, ms); + return APR_EGENERAL; } } else if (strncmp(MS_END, conn->buffer, MS_END_LEN) == 0) { rv = APR_NOTFOUND; } else { - rv = APR_EGENERAL; + ms_bad_conn(ms, conn); + apr_memcache_disable_server(mc, ms); + return APR_EGENERAL; } ms_release_conn(ms, conn); @@ -1358,74 +1375,68 @@ apr_memcache_multgetp(apr_memcache_t *mc, char *last; char *data; apr_size_t len = 0; + apr_bucket *e = NULL; key = apr_strtok(conn->buffer, " ", &last); /* just the VALUE, ignore */ key = apr_strtok(NULL, " ", &last); flags = apr_strtok(NULL, " ", &last); - - length = apr_strtok(NULL, " ", &last); - if (length) { - len = strtol(length, (char **) NULL, 10); + + if (!length || !parse_size(length, &len)) { + rv = APR_EGENERAL; + } + else { + /* eat the trailing \r\n */ + rv = apr_brigade_partition(conn->bb, len+2, &e); + } + if (rv != APR_SUCCESS) { + apr_pollset_remove (pollset, &activefds[i]); + mget_conn_result(TRUE, FALSE, rv, mc, ms, conn, + server_query, values, server_queries); + queries_sent--; + continue; } value = apr_hash_get(values, key, strlen(key)); - - if (value) { - if (len != 0) { - apr_bucket_brigade *bbb; - apr_bucket *e; - - /* eat the trailing \r\n */ - rv = apr_brigade_partition(conn->bb, len+2, &e); - - if (rv != APR_SUCCESS) { - apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, - server_query, values, server_queries); - queries_sent--; - continue; - } - - bbb = apr_brigade_split(conn->bb, e); - - rv = apr_brigade_pflatten(conn->bb, &data, &len, data_pool); - - if (rv != APR_SUCCESS) { - apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, - server_query, values, server_queries); - queries_sent--; - continue; - } - - rv = apr_brigade_destroy(conn->bb); - if (rv != APR_SUCCESS) { - apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, - server_query, values, server_queries); - queries_sent--; - continue; - } - - conn->bb = bbb; - - value->len = len - 2; - data[value->len] = '\0'; - value->data = data; + apr_bucket_brigade *bbb; + + bbb = apr_brigade_split(conn->bb, e); + + rv = apr_brigade_pflatten(conn->bb, &data, &len, data_pool); + if (rv != APR_SUCCESS) { + apr_pollset_remove (pollset, &activefds[i]); + mget_conn_result(TRUE, FALSE, rv, mc, ms, conn, + server_query, values, server_queries); + queries_sent--; + continue; } - + + rv = apr_brigade_destroy(conn->bb); + if (rv != APR_SUCCESS) { + apr_pollset_remove (pollset, &activefds[i]); + mget_conn_result(TRUE, FALSE, rv, mc, ms, conn, + server_query, values, server_queries); + queries_sent--; + continue; + } + + conn->bb = bbb; + + value->len = len - 2; + data[value->len] = '\0'; + value->data = data; + value->status = rv; value->flags = atoi(flags); - + /* stay on the server */ i--; - } else { - /* TODO: Server Sent back a key I didn't ask for or my - * hash is corrupt */ + /* Server Sent back a key I didn't ask for or my + * hash is corrupt */ + rv = APR_EGENERAL; } } else if (strncmp(MS_END, conn->buffer, MS_END_LEN) == 0) { @@ -1433,14 +1444,18 @@ apr_memcache_multgetp(apr_memcache_t *mc, apr_pollset_remove (pollset, &activefds[i]); ms_release_conn(ms, conn); apr_hash_set(server_queries, &ms, sizeof(ms), NULL); - queries_sent--; } else { /* unknown reply? */ rv = APR_EGENERAL; } - + if (rv != APR_SUCCESS) { + apr_pollset_remove (pollset, &activefds[i]); + mget_conn_result(TRUE, FALSE, rv, mc, ms, conn, + server_query, values, server_queries); + queries_sent--; + } } /* /for */ } /* /while */ diff --git a/contrib/apr-util/redis/apr_redis.c b/contrib/apr-util/redis/apr_redis.c new file mode 100644 index 000000000000..8d01fdd67cdc --- /dev/null +++ b/contrib/apr-util/redis/apr_redis.c @@ -0,0 +1,1548 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_redis.h" +#include "apr_poll.h" +#include "apr_version.h" +#include +#include + +#define BUFFER_SIZE 512 +#define LILBUFF_SIZE 64 +struct apr_redis_conn_t +{ + char *buffer; + apr_size_t blen; + apr_pool_t *p; + apr_pool_t *tp; + apr_socket_t *sock; + apr_bucket_brigade *bb; + apr_bucket_brigade *tb; + apr_redis_server_t *rs; +}; + +/* Strings for Client Commands */ + +#define RC_EOL "\r\n" +#define RC_EOL_LEN (sizeof(RC_EOL)-1) + +#define RC_WS " " +#define RC_WS_LEN (sizeof(RC_WS)-1) + +#define RC_RESP_1 "*1\r\n" +#define RC_RESP_1_LEN (sizeof(RC_RESP_1)-1) + +#define RC_RESP_2 "*2\r\n" +#define RC_RESP_2_LEN (sizeof(RC_RESP_2)-1) + +#define RC_RESP_3 "*3\r\n" +#define RC_RESP_3_LEN (sizeof(RC_RESP_3)-1) + +#define RC_RESP_4 "*4\r\n" +#define RC_RESP_4_LEN (sizeof(RC_RESP_4)-1) + +#define RC_GET "GET\r\n" +#define RC_GET_LEN (sizeof(RC_GET)-1) + +#define RC_GET_SIZE "$3\r\n" +#define RC_GET_SIZE_LEN (sizeof(RC_GET_SIZE)-1) + +#define RC_SET "SET\r\n" +#define RC_SET_LEN (sizeof(RC_SET)-1) + +#define RC_SET_SIZE "$3\r\n" +#define RC_SET_SIZE_LEN (sizeof(RC_SET_SIZE)-1) + +#define RC_SETEX "SETEX\r\n" +#define RC_SETEX_LEN (sizeof(RC_SETEX)-1) + +#define RC_SETEX_SIZE "$5\r\n" +#define RC_SETEX_SIZE_LEN (sizeof(RC_SETEX_SIZE)-1) + +#define RC_DEL "DEL\r\n" +#define RC_DEL_LEN (sizeof(RC_DEL)-1) + +#define RC_DEL_SIZE "$3\r\n" +#define RC_DEL_SIZE_LEN (sizeof(RC_DEL_SIZE)-1) + +#define RC_QUIT "QUIT\r\n" +#define RC_QUIT_LEN (sizeof(RC_QUIT)-1) + +#define RC_QUIT_SIZE "$4\r\n" +#define RC_QUIT_SIZE_LEN (sizeof(RC_QUIT_SIZE)-1) + +#define RC_PING "PING\r\n" +#define RC_PING_LEN (sizeof(RC_PING)-1) + +#define RC_PING_SIZE "$4\r\n" +#define RC_PING_SIZE_LEN (sizeof(RC_PING_SIZE)-1) + +#define RC_INFO "INFO\r\n" +#define RC_INFO_LEN (sizeof(RC_INFO)-1) + +#define RC_INFO_SIZE "$4\r\n" +#define RC_INFO_SIZE_LEN (sizeof(RC_INFO_SIZE)-1) + +/* Strings for Server Replies */ + +#define RS_STORED "+OK" +#define RS_STORED_LEN (sizeof(RS_STORED)-1) + +#define RS_NOT_STORED "$-1" +#define RS_NOT_STORED_LEN (sizeof(RS_NOT_STORED)-1) + +#define RS_DELETED ":1" +#define RS_DELETED_LEN (sizeof(RS_DELETED)-1) + +#define RS_NOT_FOUND_GET "$-1" +#define RS_NOT_FOUND_GET_LEN (sizeof(RS_NOT_FOUND_GET)-1) + +#define RS_NOT_FOUND_DEL ":0" +#define RS_NOT_FOUND_DEL_LEN (sizeof(RS_NOT_FOUND_DEL)-1) + +#define RS_TYPE_STRING "$" +#define RS_TYPE_STRING_LEN (sizeof(RS_TYPE_STRING)-1) + +#define RS_END "\r\n" +#define RS_END_LEN (sizeof(RS_END)-1) + +static apr_status_t make_server_dead(apr_redis_t *rc, + apr_redis_server_t *rs) +{ +#if APR_HAS_THREADS + apr_thread_mutex_lock(rs->lock); +#endif + rs->status = APR_RC_SERVER_DEAD; + rs->btime = apr_time_now(); +#if APR_HAS_THREADS + apr_thread_mutex_unlock(rs->lock); +#endif + return APR_SUCCESS; +} + +static apr_status_t make_server_live(apr_redis_t *rc, + apr_redis_server_t *rs) +{ + rs->status = APR_RC_SERVER_LIVE; + return APR_SUCCESS; +} + +APU_DECLARE(apr_status_t) apr_redis_add_server(apr_redis_t *rc, + apr_redis_server_t *rs) +{ + apr_status_t rv = APR_SUCCESS; + + if (rc->ntotal >= rc->nalloc) { + return APR_ENOMEM; + } + rc->live_servers[rc->ntotal] = rs; + rc->ntotal++; + make_server_live(rc, rs); + return rv; +} + +APU_DECLARE(apr_redis_server_t *) +apr_redis_find_server_hash(apr_redis_t *rc, const apr_uint32_t hash) +{ + if (rc->server_func) { + return rc->server_func(rc->server_baton, rc, hash); + } + else { + return apr_redis_find_server_hash_default(NULL, rc, hash); + } +} + +APU_DECLARE(apr_redis_server_t *) +apr_redis_find_server_hash_default(void *baton, apr_redis_t *rc, + const apr_uint32_t hash) +{ + apr_redis_server_t *rs = NULL; + apr_uint32_t h = hash ? hash : 1; + apr_uint32_t i = 0; + apr_time_t curtime = 0; + + if (rc->ntotal == 0) { + return NULL; + } + + do { + rs = rc->live_servers[h % rc->ntotal]; + if (rs->status == APR_RC_SERVER_LIVE) { + break; + } + else { + if (curtime == 0) { + curtime = apr_time_now(); + } +#if APR_HAS_THREADS + apr_thread_mutex_lock(rs->lock); +#endif + /* Try the dead server, every 5 seconds */ + if (curtime - rs->btime > apr_time_from_sec(5)) { + rs->btime = curtime; + if (apr_redis_ping(rs) == APR_SUCCESS) { + make_server_live(rc, rs); +#if APR_HAS_THREADS + apr_thread_mutex_unlock(rs->lock); +#endif + break; + } + } +#if APR_HAS_THREADS + apr_thread_mutex_unlock(rs->lock); +#endif + } + h++; + i++; + } while (i < rc->ntotal); + + if (i == rc->ntotal) { + rs = NULL; + } + + return rs; +} + +APU_DECLARE(apr_redis_server_t *) apr_redis_find_server(apr_redis_t *rc, + const char *host, + apr_port_t port) +{ + int i; + + for (i = 0; i < rc->ntotal; i++) { + if (strcmp(rc->live_servers[i]->host, host) == 0 + && rc->live_servers[i]->port == port) { + + return rc->live_servers[i]; + } + } + + return NULL; +} + +static apr_status_t rs_find_conn(apr_redis_server_t *rs, + apr_redis_conn_t ** conn) +{ + apr_status_t rv; + apr_bucket_alloc_t *balloc; + apr_bucket *e; + +#if APR_HAS_THREADS + rv = apr_reslist_acquire(rs->conns, (void **) conn); +#else + *conn = rs->conn; + rv = APR_SUCCESS; +#endif + + if (rv != APR_SUCCESS) { + return rv; + } + + balloc = apr_bucket_alloc_create((*conn)->tp); + (*conn)->bb = apr_brigade_create((*conn)->tp, balloc); + (*conn)->tb = apr_brigade_create((*conn)->tp, balloc); + + e = apr_bucket_socket_create((*conn)->sock, balloc); + APR_BRIGADE_INSERT_TAIL((*conn)->bb, e); + + return rv; +} + +static apr_status_t rs_bad_conn(apr_redis_server_t *rs, + apr_redis_conn_t *conn) +{ +#if APR_HAS_THREADS + return apr_reslist_invalidate(rs->conns, conn); +#else + return APR_SUCCESS; +#endif +} + +static apr_status_t rs_release_conn(apr_redis_server_t *rs, + apr_redis_conn_t *conn) +{ + apr_pool_clear(conn->tp); +#if APR_HAS_THREADS + return apr_reslist_release(rs->conns, conn); +#else + return APR_SUCCESS; +#endif +} + +APU_DECLARE(apr_status_t) apr_redis_enable_server(apr_redis_t *rc, + apr_redis_server_t *rs) +{ + apr_status_t rv = APR_SUCCESS; + + if (rs->status == APR_RC_SERVER_LIVE) { + return rv; + } + rv = make_server_live(rc, rs); + return rv; +} + +APU_DECLARE(apr_status_t) apr_redis_disable_server(apr_redis_t *rc, + apr_redis_server_t *rs) +{ + return make_server_dead(rc, rs); +} + +static apr_status_t conn_connect(apr_redis_conn_t *conn) +{ + apr_status_t rv = APR_SUCCESS; + apr_sockaddr_t *sa; +#if APR_HAVE_SOCKADDR_UN + apr_int32_t family = conn->rs->host[0] != '/' ? APR_INET : APR_UNIX; +#else + apr_int32_t family = APR_INET; +#endif + + rv = apr_sockaddr_info_get(&sa, conn->rs->host, family, conn->rs->port, 0, + conn->p); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(conn->sock, 1 * APR_USEC_PER_SEC); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_connect(conn->sock, sa); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(conn->sock, + conn->rs->rwto * APR_USEC_PER_SEC); + if (rv != APR_SUCCESS) { + return rv; + } + + return rv; +} + +static apr_status_t +rc_conn_construct(void **conn_, void *params, apr_pool_t *pool) +{ + apr_status_t rv = APR_SUCCESS; + apr_redis_conn_t *conn; + apr_pool_t *np; + apr_pool_t *tp; + apr_redis_server_t *rs = params; +#if APR_HAVE_SOCKADDR_UN + apr_int32_t family = rs->host[0] != '/' ? APR_INET : APR_UNIX; +#else + apr_int32_t family = APR_INET; +#endif + + rv = apr_pool_create(&np, pool); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_pool_create(&tp, np); + if (rv != APR_SUCCESS) { + apr_pool_destroy(np); + return rv; + } + + conn = apr_palloc(np, sizeof(apr_redis_conn_t)); + + conn->p = np; + conn->tp = tp; + + rv = apr_socket_create(&conn->sock, family, SOCK_STREAM, 0, np); + + if (rv != APR_SUCCESS) { + apr_pool_destroy(np); + return rv; + } + + conn->buffer = apr_palloc(conn->p, BUFFER_SIZE + 1); + conn->blen = 0; + conn->rs = rs; + + rv = conn_connect(conn); + if (rv != APR_SUCCESS) { + apr_pool_destroy(np); + } + else { + *conn_ = conn; + } + + return rv; +} + +#if APR_HAS_THREADS +static apr_status_t +rc_conn_destruct(void *conn_, void *params, apr_pool_t *pool) +{ + apr_redis_conn_t *conn = (apr_redis_conn_t *) conn_; + struct iovec vec[3]; + apr_size_t written; + + /* send a quit message to the Redis server to be nice about it. */ + + /* + * RESP Command: + * *1 + * $4 + * QUIT + */ + vec[0].iov_base = RC_RESP_1; + vec[0].iov_len = RC_RESP_1_LEN; + + vec[1].iov_base = RC_QUIT_SIZE; + vec[1].iov_len = RC_QUIT_SIZE_LEN; + + vec[2].iov_base = RC_QUIT; + vec[2].iov_len = RC_QUIT_LEN; + + /* Return values not checked, since we just want to make it go away. */ + apr_socket_sendv(conn->sock, vec, 3, &written); + apr_socket_close(conn->sock); + + apr_pool_destroy(conn->p); + + return APR_SUCCESS; +} +#endif + +APU_DECLARE(apr_status_t) apr_redis_server_create(apr_pool_t *p, + const char *host, + apr_port_t port, + apr_uint32_t min, + apr_uint32_t smax, + apr_uint32_t max, + apr_uint32_t ttl, + apr_uint32_t rwto, + apr_redis_server_t **rs) +{ + apr_status_t rv = APR_SUCCESS; + apr_redis_server_t *server; + apr_pool_t *np; + + rv = apr_pool_create(&np, p); + + server = apr_palloc(np, sizeof(apr_redis_server_t)); + + server->p = np; + server->host = apr_pstrdup(np, host); + server->port = port; + server->status = APR_RC_SERVER_DEAD; + server->rwto = rwto; + server->version.major = 0; + server->version.minor = 0; + server->version.patch = 0; + +#if APR_HAS_THREADS + rv = apr_thread_mutex_create(&server->lock, APR_THREAD_MUTEX_DEFAULT, np); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_reslist_create(&server->conns, + min, /* hard minimum */ + smax, /* soft maximum */ + max, /* hard maximum */ + ttl, /* Time to live */ + rc_conn_construct, /* Make a New Connection */ + rc_conn_destruct, /* Kill Old Connection */ + server, np); + if (rv != APR_SUCCESS) { + return rv; + } + + apr_reslist_cleanup_order_set(server->conns, APR_RESLIST_CLEANUP_FIRST); +#else + rv = rc_conn_construct((void **) &(server->conn), server, np); + if (rv != APR_SUCCESS) { + return rv; + } +#endif + + *rs = server; + + return rv; +} + +APU_DECLARE(apr_status_t) apr_redis_create(apr_pool_t *p, + apr_uint16_t max_servers, + apr_uint32_t flags, + apr_redis_t **redis) +{ + apr_status_t rv = APR_SUCCESS; + apr_redis_t *rc; + + rc = apr_palloc(p, sizeof(apr_redis_t)); + rc->p = p; + rc->nalloc = max_servers; + rc->ntotal = 0; + rc->live_servers = + apr_palloc(p, rc->nalloc * sizeof(struct apr_redis_server_t *)); + rc->hash_func = NULL; + rc->hash_baton = NULL; + rc->server_func = NULL; + rc->server_baton = NULL; + *redis = rc; + return rv; +} + + +/* The crc32 functions and data was originally written by Spencer + * Garrett and was gleaned from the PostgreSQL source + * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at + * src/usr.bin/cksum/crc32.c. + */ + +static const apr_uint32_t crc32tab[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +APU_DECLARE(apr_uint32_t) apr_redis_hash_crc32(void *baton, + const char *data, + const apr_size_t data_len) +{ + apr_uint32_t i; + apr_uint32_t crc; + crc = ~0; + + for (i = 0; i < data_len; i++) + crc = (crc >> 8) ^ crc32tab[(crc ^ (data[i])) & 0xff]; + + return ~crc; +} + +APU_DECLARE(apr_uint32_t) apr_redis_hash_default(void *baton, + const char *data, + const apr_size_t data_len) +{ + /* The default Perl Client doesn't actually use just crc32 -- it shifts it again + * like this.... + */ + return ((apr_redis_hash_crc32(baton, data, data_len) >> 16) & 0x7fff); +} + +APU_DECLARE(apr_uint32_t) apr_redis_hash(apr_redis_t *rc, + const char *data, + const apr_size_t data_len) +{ + if (rc->hash_func) { + return rc->hash_func(rc->hash_baton, data, data_len); + } + else { + return apr_redis_hash_default(NULL, data, data_len); + } +} + +static apr_status_t get_server_line(apr_redis_conn_t *conn) +{ + apr_size_t bsize = BUFFER_SIZE; + apr_status_t rv = APR_SUCCESS; + + rv = apr_brigade_split_line(conn->tb, conn->bb, APR_BLOCK_READ, + BUFFER_SIZE); + + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_brigade_flatten(conn->tb, conn->buffer, &bsize); + + if (rv != APR_SUCCESS) { + return rv; + } + + conn->blen = bsize; + conn->buffer[bsize] = '\0'; + + return apr_brigade_cleanup(conn->tb); +} + +APU_DECLARE(apr_status_t) apr_redis_set(apr_redis_t *rc, + const char *key, + char *data, + const apr_size_t data_size, + apr_uint16_t flags) +{ + apr_uint32_t hash; + apr_redis_server_t *rs; + apr_redis_conn_t *conn; + apr_status_t rv; + apr_size_t written; + struct iovec vec[9]; + char keysize_str[LILBUFF_SIZE]; + char datasize_str[LILBUFF_SIZE]; + apr_size_t len, klen; + + klen = strlen(key); + hash = apr_redis_hash(rc, key, klen); + + rs = apr_redis_find_server_hash(rc, hash); + + if (rs == NULL) + return APR_NOTFOUND; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + apr_redis_disable_server(rc, rs); + return rv; + } + + /* + * RESP Command: + * *3 + * $3 + * SET + * $ + * key + * $ + * data + */ + + vec[0].iov_base = RC_RESP_3; + vec[0].iov_len = RC_RESP_3_LEN; + + vec[1].iov_base = RC_SET_SIZE; + vec[1].iov_len = RC_SET_SIZE_LEN; + + vec[2].iov_base = RC_SET; + vec[2].iov_len = RC_SET_LEN; + + len = apr_snprintf(keysize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", klen); + vec[3].iov_base = keysize_str; + vec[3].iov_len = len; + + vec[4].iov_base = (void *) key; + vec[4].iov_len = klen; + + vec[5].iov_base = RC_EOL; + vec[5].iov_len = RC_EOL_LEN; + + len = apr_snprintf(datasize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + data_size); + vec[6].iov_base = datasize_str; + vec[6].iov_len = len; + + vec[7].iov_base = data; + vec[7].iov_len = data_size; + + vec[8].iov_base = RC_EOL; + vec[8].iov_len = RC_EOL_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 9, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + if (strcmp(conn->buffer, RS_STORED RC_EOL) == 0) { + rv = APR_SUCCESS; + } + else if (strcmp(conn->buffer, RS_NOT_STORED RC_EOL) == 0) { + rv = APR_EEXIST; + } + else { + rv = APR_EGENERAL; + } + + rs_release_conn(rs, conn); + return rv; +} + +APU_DECLARE(apr_status_t) apr_redis_setex(apr_redis_t *rc, + const char *key, + char *data, + const apr_size_t data_size, + apr_uint32_t timeout, + apr_uint16_t flags) +{ + apr_uint32_t hash; + apr_redis_server_t *rs; + apr_redis_conn_t *conn; + apr_status_t rv; + apr_size_t written; + struct iovec vec[11]; + char keysize_str[LILBUFF_SIZE]; + char expire_str[LILBUFF_SIZE]; + char expiresize_str[LILBUFF_SIZE]; + char datasize_str[LILBUFF_SIZE]; + apr_size_t len, klen, expire_len; + + + klen = strlen(key); + hash = apr_redis_hash(rc, key, klen); + + rs = apr_redis_find_server_hash(rc, hash); + + if (rs == NULL) + return APR_NOTFOUND; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + apr_redis_disable_server(rc, rs); + return rv; + } + + /* + * RESP Command: + * *4 + * $5 + * SETEX + * $ + * key + * $ + * expirey + * $ + * data + */ + + vec[0].iov_base = RC_RESP_4; + vec[0].iov_len = RC_RESP_4_LEN; + + vec[1].iov_base = RC_SETEX_SIZE; + vec[1].iov_len = RC_SETEX_SIZE_LEN; + + vec[2].iov_base = RC_SETEX; + vec[2].iov_len = RC_SETEX_LEN; + + len = apr_snprintf(keysize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", klen); + vec[3].iov_base = keysize_str; + vec[3].iov_len = len; + + vec[4].iov_base = (void *) key; + vec[4].iov_len = klen; + + vec[5].iov_base = RC_EOL; + vec[5].iov_len = RC_EOL_LEN; + + expire_len = apr_snprintf(expire_str, LILBUFF_SIZE, "%u\r\n", timeout); + len = apr_snprintf(expiresize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + expire_len - 2); + vec[6].iov_base = (void *) expiresize_str; + vec[6].iov_len = len; + + vec[7].iov_base = (void *) expire_str; + vec[7].iov_len = expire_len; + + len = apr_snprintf(datasize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + data_size); + vec[8].iov_base = datasize_str; + vec[8].iov_len = len; + + vec[9].iov_base = data; + vec[9].iov_len = data_size; + + vec[10].iov_base = RC_EOL; + vec[10].iov_len = RC_EOL_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 11, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + if (strcmp(conn->buffer, RS_STORED RC_EOL) == 0) { + rv = APR_SUCCESS; + } + else if (strcmp(conn->buffer, RS_NOT_STORED RC_EOL) == 0) { + rv = APR_EEXIST; + } + else { + rv = APR_EGENERAL; + } + + rs_release_conn(rs, conn); + return rv; +} + +static apr_status_t grab_bulk_resp(apr_redis_server_t *rs, apr_redis_t *rc, + apr_redis_conn_t *conn, apr_pool_t *p, + char **baton, apr_size_t *new_length) +{ + char *length; + char *last; + apr_status_t rv; + apr_size_t len = 0; + *new_length = 0; + + length = apr_strtok(conn->buffer + 1, " ", &last); + if (length) { + len = strtol(length, (char **) NULL, 10); + } + + if (len == 0) { + *new_length = 0; + *baton = NULL; + } + else { + apr_bucket_brigade *bbb; + apr_bucket *e; + + /* eat the trailing \r\n */ + rv = apr_brigade_partition(conn->bb, len + 2, &e); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + if (rc) + apr_redis_disable_server(rc, rs); + return rv; + } + + bbb = apr_brigade_split(conn->bb, e); + + rv = apr_brigade_pflatten(conn->bb, baton, &len, p); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + if (rc) + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = apr_brigade_destroy(conn->bb); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + if (rc) + apr_redis_disable_server(rc, rs); + return rv; + } + + conn->bb = bbb; + + *new_length = len - 2; + (*baton)[*new_length] = '\0'; + } + return APR_SUCCESS; + +} + +APU_DECLARE(apr_status_t) apr_redis_getp(apr_redis_t *rc, + apr_pool_t *p, + const char *key, + char **baton, + apr_size_t *new_length, + apr_uint16_t *flags) +{ + apr_status_t rv; + apr_redis_server_t *rs; + apr_redis_conn_t *conn; + apr_uint32_t hash; + apr_size_t written; + apr_size_t len, klen; + struct iovec vec[6]; + char keysize_str[LILBUFF_SIZE]; + + klen = strlen(key); + hash = apr_redis_hash(rc, key, klen); + rs = apr_redis_find_server_hash(rc, hash); + + if (rs == NULL) + return APR_NOTFOUND; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + apr_redis_disable_server(rc, rs); + return rv; + } + + /* + * RESP Command: + * *2 + * $3 + * GET + * $ + * key + */ + vec[0].iov_base = RC_RESP_2; + vec[0].iov_len = RC_RESP_2_LEN; + + vec[1].iov_base = RC_GET_SIZE; + vec[1].iov_len = RC_GET_SIZE_LEN; + + vec[2].iov_base = RC_GET; + vec[2].iov_len = RC_GET_LEN; + + len = apr_snprintf(keysize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + klen); + vec[3].iov_base = keysize_str; + vec[3].iov_len = len; + + vec[4].iov_base = (void *) key; + vec[4].iov_len = klen; + + vec[5].iov_base = RC_EOL; + vec[5].iov_len = RC_EOL_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 6, &written); + + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + if (strncmp(RS_NOT_FOUND_GET, conn->buffer, RS_NOT_FOUND_GET_LEN) == 0) { + rv = APR_NOTFOUND; + } + else if (strncmp(RS_TYPE_STRING, conn->buffer, RS_TYPE_STRING_LEN) == 0) { + rv = grab_bulk_resp(rs, rc, conn, p, baton, new_length); + } + else { + rv = APR_EGENERAL; + } + + rs_release_conn(rs, conn); + return rv; +} + +APU_DECLARE(apr_status_t) + apr_redis_delete(apr_redis_t *rc, const char *key, apr_uint32_t timeout) +{ + apr_status_t rv; + apr_redis_server_t *rs; + apr_redis_conn_t *conn; + apr_uint32_t hash; + apr_size_t written; + struct iovec vec[6]; + apr_size_t len, klen; + char keysize_str[LILBUFF_SIZE]; + + klen = strlen(key); + hash = apr_redis_hash(rc, key, klen); + rs = apr_redis_find_server_hash(rc, hash); + if (rs == NULL) + return APR_NOTFOUND; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + apr_redis_disable_server(rc, rs); + return rv; + } + + /* + * RESP Command: + * *2 + * $3 + * DEL + * $ + * key + */ + vec[0].iov_base = RC_RESP_2; + vec[0].iov_len = RC_RESP_2_LEN; + + vec[1].iov_base = RC_DEL_SIZE; + vec[1].iov_len = RC_DEL_SIZE_LEN; + + vec[2].iov_base = RC_DEL; + vec[2].iov_len = RC_DEL_LEN; + + len = apr_snprintf(keysize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + klen); + vec[3].iov_base = keysize_str; + vec[3].iov_len = len; + + vec[4].iov_base = (void *) key; + vec[4].iov_len = klen; + + vec[5].iov_base = RC_EOL; + vec[5].iov_len = RC_EOL_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 6, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + if (strncmp(RS_DELETED, conn->buffer, RS_DELETED_LEN) == 0) { + rv = APR_SUCCESS; + } + else if (strncmp(RS_NOT_FOUND_DEL, conn->buffer, RS_NOT_FOUND_DEL_LEN) == 0) { + rv = APR_NOTFOUND; + } + else { + rv = APR_EGENERAL; + } + + rs_release_conn(rs, conn); + return rv; +} + +APU_DECLARE(apr_status_t) +apr_redis_ping(apr_redis_server_t *rs) +{ + apr_status_t rv; + apr_size_t written; + struct iovec vec[3]; + apr_redis_conn_t *conn; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + return rv; + } + + /* + * RESP Command: + * *1 + * $4 + * PING + */ + vec[0].iov_base = RC_RESP_1; + vec[0].iov_len = RC_RESP_1_LEN; + + vec[1].iov_base = RC_PING_SIZE; + vec[1].iov_len = RC_PING_SIZE_LEN; + + vec[2].iov_base = RC_PING; + vec[2].iov_len = RC_PING_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 3, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + return rv; + } + + rv = get_server_line(conn); + if (rv == APR_SUCCESS) { + /* we got *something*. Was it Redis? */ + if (strncmp(conn->buffer, "+PONG", sizeof("+PONG")-1) != 0) { + rv = APR_EGENERAL; + } + } + rs_release_conn(rs, conn); + return rv; +} + +APU_DECLARE(apr_status_t) +apr_redis_info(apr_redis_server_t *rs, apr_pool_t *p, char **baton) +{ + apr_status_t rv; + apr_redis_conn_t *conn; + apr_size_t written; + struct iovec vec[3]; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + return rv; + } + + /* + * RESP Command: + * *1 + * $4 + * INFO + */ + vec[0].iov_base = RC_RESP_1; + vec[0].iov_len = RC_RESP_1_LEN; + + vec[1].iov_base = RC_INFO_SIZE; + vec[1].iov_len = RC_INFO_SIZE_LEN; + + vec[2].iov_base = RC_INFO; + vec[2].iov_len = RC_INFO_LEN; + + rv = apr_socket_sendv(conn->sock, vec, 3, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + return rv; + } + + if (strncmp(RS_TYPE_STRING, conn->buffer, RS_TYPE_STRING_LEN) == 0) { + apr_size_t nl; + rv = grab_bulk_resp(rs, NULL, conn, p, baton, &nl); + } else { + rs_bad_conn(rs, conn); + rv = APR_EGENERAL; + } + + rs_release_conn(rs, conn); + return rv; +} + +#define RV_FIELD "redis_version:" +APU_DECLARE(apr_status_t) +apr_redis_version(apr_redis_server_t *rs, apr_pool_t *p, char **baton) +{ + apr_status_t rv; + char *ptr, *eptr; + apr_pool_t *subpool; + + /* Have we already obtained the version number? */ + if (rs->version.minor != 0) { + if (baton) + *baton = apr_pstrdup(p, rs->version.number); + return APR_SUCCESS; + } + if (apr_pool_create(&subpool, p) != APR_SUCCESS) { + /* well, we tried */ + subpool = p; + } + rv = apr_redis_info(rs, subpool, baton); + + if (rv != APR_SUCCESS) { + if (subpool != p) { + apr_pool_destroy(subpool); + } + return rv; + } + + ptr = strstr(*baton, RV_FIELD); + if (ptr) { + rs->version.major = strtol(ptr + sizeof(RV_FIELD) - 1, &eptr, 10); + ptr = eptr + 1; + rs->version.minor = strtol(ptr, &eptr, 10); + ptr = eptr + 1; + rs->version.patch = strtol(ptr, &eptr, 10); + rs->version.number = apr_psprintf(rs->p, "%d.%d.%d", + rs->version.major, rs->version.minor, + rs->version.patch); + } + if (baton) + *baton = apr_pstrdup(p, rs->version.number); + if (subpool != p) { + apr_pool_destroy(subpool); + } + return APR_SUCCESS; +} + +static apr_status_t plus_minus(apr_redis_t *rc, + int incr, + const char *key, + apr_int32_t inc, + apr_uint32_t *new_value) +{ + apr_status_t rv; + apr_redis_server_t *rs; + apr_redis_conn_t *conn; + apr_uint32_t hash; + apr_size_t written; + apr_size_t len, klen; + struct iovec vec[12]; + char keysize_str[LILBUFF_SIZE]; + char inc_str[LILBUFF_SIZE]; + char inc_str_len[LILBUFF_SIZE]; + int i = 0; + + klen = strlen(key); + hash = apr_redis_hash(rc, key, klen); + rs = apr_redis_find_server_hash(rc, hash); + if (rs == NULL) + return APR_NOTFOUND; + + rv = rs_find_conn(rs, &conn); + + if (rv != APR_SUCCESS) { + apr_redis_disable_server(rc, rs); + return rv; + } + + /* + * RESP Command: + * *2|*3 + * $4|$6 + * INCR/DECR|INCRBY/DECRBY + * $ + * key + * <:inc> + */ + if (inc == 1) { + vec[i].iov_base = RC_RESP_2; + vec[i].iov_len = RC_RESP_2_LEN; + i++; + + vec[i].iov_base = "$4\r\n"; + vec[i].iov_len = sizeof("$4\r\n")-1; + i++; + + if (incr) + vec[i].iov_base = "INCR\r\n"; + else + vec[i].iov_base = "DECR\r\n"; + vec[i].iov_len = sizeof("INCR\r\n")-1; + i++; + } + else { + vec[i].iov_base = RC_RESP_3; + vec[i].iov_len = RC_RESP_3_LEN; + i++; + + vec[i].iov_base = "$6\r\n"; + vec[i].iov_len = sizeof("$6\r\n")-1; + i++; + + if (incr) + vec[i].iov_base = "INCRBY\r\n"; + else + vec[i].iov_base = "DECRBY\r\n"; + vec[i].iov_len = sizeof("INCRBY\r\n")-1; + i++; + } + + len = apr_snprintf(keysize_str, LILBUFF_SIZE, "$%" APR_SIZE_T_FMT "\r\n", + klen); + vec[i].iov_base = keysize_str; + vec[i].iov_len = len; + i++; + + vec[i].iov_base = (void *) key; + vec[i].iov_len = klen; + i++; + + vec[i].iov_base = RC_EOL; + vec[i].iov_len = RC_EOL_LEN; + i++; + + if (inc != 1) { + len = apr_snprintf(inc_str, LILBUFF_SIZE, "%d\r\n", inc); + klen = apr_snprintf(inc_str_len, LILBUFF_SIZE, "$%d\r\n", (int)(len-2)); + vec[i].iov_base = inc_str_len; + vec[i].iov_len = klen; + i++; + + vec[i].iov_base = inc_str; + vec[i].iov_len = len; + i++; + + vec[i].iov_base = RC_EOL; + vec[i].iov_len = RC_EOL_LEN; + i++; + } + + rv = apr_socket_sendv(conn->sock, vec, i, &written); + + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + + rv = get_server_line(conn); + if (rv != APR_SUCCESS) { + rs_bad_conn(rs, conn); + apr_redis_disable_server(rc, rs); + return rv; + } + if (strncmp(RS_NOT_FOUND_GET, conn->buffer, RS_NOT_FOUND_GET_LEN) == 0) { + rv = APR_NOTFOUND; + } + else if (*conn->buffer == ':') { + *new_value = atoi((const char *)(conn->buffer + 1)); + rv = APR_SUCCESS; + } + else { + rv = APR_EGENERAL; + } + rs_release_conn(rs, conn); + return rv; +} + +APU_DECLARE(apr_status_t) +apr_redis_incr(apr_redis_t *rc, const char *key, apr_int32_t inc, apr_uint32_t *new_value) +{ + return plus_minus(rc, 1, key, inc, new_value); +} + +APU_DECLARE(apr_status_t) +apr_redis_decr(apr_redis_t *rc, const char *key, apr_int32_t inc, apr_uint32_t *new_value) +{ + return plus_minus(rc, 0, key, inc, new_value); +} + +APU_DECLARE(apr_status_t) +apr_redis_multgetp(apr_redis_t *rc, + apr_pool_t *temp_pool, + apr_pool_t *data_pool, + apr_hash_t *values) +{ + return APR_ENOTIMPL; +} + +/** + * Define all of the strings for stats + */ + +#define STAT_process_id "process_id:" +#define STAT_process_id_LEN (sizeof(STAT_process_id)-1) + +#define STAT_uptime_in_seconds "uptime_in_seconds:" +#define STAT_uptime_in_seconds_LEN (sizeof(STAT_uptime_in_seconds)-1) + +#define STAT_arch_bits "arch_bits:" +#define STAT_arch_bits_LEN (sizeof(STAT_arch_bits)-1) + +#define STAT_connected_clients "connected_clients:" +#define STAT_connected_clients_LEN (sizeof(STAT_connected_clients)-1) + +#define STAT_blocked_clients "blocked_clients:" +#define STAT_blocked_clients_LEN (sizeof(STAT_blocked_clients)-1) + +#define STAT_maxmemory "maxmemory:" +#define STAT_maxmemory_LEN (sizeof(STAT_maxmemory)-1) + +#define STAT_used_memory "used_memory:" +#define STAT_used_memory_LEN (sizeof(STAT_used_memory)-1) + +#define STAT_total_system_memory "total_system_memory:" +#define STAT_total_system_memory_LEN (sizeof(STAT_total_system_memory)-1) + +#define STAT_total_connections_received "total_connections_received:" +#define STAT_total_connections_received_LEN (sizeof(STAT_total_connections_received)-1) + +#define STAT_total_commands_processed "total_commands_processed:" +#define STAT_total_commands_processed_LEN (sizeof(STAT_total_commands_processed)-1) + +#define STAT_rejected_connections "rejected_connections:" +#define STAT_rejected_connections_LEN (sizeof(STAT_rejected_connections)-1) + +#define STAT_total_net_input_bytes "total_net_input_bytes:" +#define STAT_total_net_input_bytes_LEN (sizeof(STAT_total_net_input_bytes)-1) + +#define STAT_total_net_output_bytes "total_net_output_bytes:" +#define STAT_total_net_output_bytes_LEN (sizeof(STAT_total_net_output_bytes)-1) + +#define STAT_keyspace_hits "keyspace_hits:" +#define STAT_keyspace_hits_LEN (sizeof(STAT_keyspace_hits)-1) + +#define STAT_keyspace_misses "keyspace_misses:" +#define STAT_keyspace_misses_LEN (sizeof(STAT_keyspace_misses)-1) + +#define STAT_connected_slaves "connected_slaves:" +#define STAT_connected_slaves_LEN (sizeof(STAT_connected_slaves)-1) + +#define STAT_used_cpu_sys "used_cpu_sys:" +#define STAT_used_cpu_sys_LEN (sizeof(STAT_used_cpu_sys)-1) + +#define STAT_used_cpu_user "used_cpu_user:" +#define STAT_used_cpu_user_LEN (sizeof(STAT_used_cpu_user)-1) + +#define STAT_cluster_enabled "cluster_enabled:" +#define STAT_cluster_enabled_LEN (sizeof(STAT_cluster_enabled)-1) + +static apr_uint32_t stat_read_uint32( char *buf) +{ + return atoi(buf); +} + +static apr_uint64_t stat_read_uint64(char *buf) +{ + return apr_atoi64(buf); +} + +#define rc_do_stat(name, type) \ + if ((ptr = strstr(info , STAT_ ## name )) != NULL ) { \ + char *str = ptr + (STAT_ ## name ## _LEN ); \ + stats-> name = stat_read_ ## type (str); \ + } + +static void update_stats(char *info, apr_redis_stats_t *stats) +{ + char *ptr; + + rc_do_stat(process_id, uint32); + rc_do_stat(uptime_in_seconds, uint32); + rc_do_stat(arch_bits, uint32); + rc_do_stat(connected_clients, uint32); + rc_do_stat(blocked_clients, uint32); + rc_do_stat(maxmemory, uint64); + rc_do_stat(used_memory, uint64); + rc_do_stat(total_system_memory, uint64); + rc_do_stat(total_connections_received, uint64); + rc_do_stat(total_commands_processed, uint64); + rc_do_stat(rejected_connections, uint64); + rc_do_stat(total_net_input_bytes, uint64); + rc_do_stat(total_net_output_bytes, uint64); + rc_do_stat(keyspace_hits, uint64); + rc_do_stat(keyspace_misses, uint64); + rc_do_stat(connected_slaves, uint32); + rc_do_stat(used_cpu_sys, uint32); + rc_do_stat(used_cpu_user, uint32); + rc_do_stat(cluster_enabled, uint32); +} + +APU_DECLARE(apr_status_t) +apr_redis_stats(apr_redis_server_t *rs, + apr_pool_t *p, + apr_redis_stats_t **stats) +{ + apr_status_t rv; + char *info; + apr_pool_t *subpool; + apr_redis_stats_t *ret; + char *ptr; + + if (apr_pool_create(&subpool, p) != APR_SUCCESS) { + /* well, we tried */ + subpool = p; + } + rv = apr_redis_info(rs, subpool, &info); + + if (rv != APR_SUCCESS) { + if (subpool != p) { + apr_pool_destroy(subpool); + } + return rv; + } + ret = apr_pcalloc(p, sizeof(apr_redis_stats_t)); + /* Get the bulk of the stats */ + update_stats(info, ret); + + /* Now the version number */ + if (rs->version.major != 0) { + ret->major = rs->version.major; + ret->minor = rs->version.minor; + ret->patch = rs->version.patch; + } + else { + char *eptr; + ptr = strstr(info, RV_FIELD); + if (ptr) { + ret->major = rs->version.major = strtol(ptr + sizeof(RV_FIELD) - 1, &eptr, 10); + ptr = eptr + 1; + ret->minor = rs->version.minor = strtol(ptr, &eptr, 10); + ptr = eptr + 1; + ret->patch = rs->version.patch = strtol(ptr, &eptr, 10); + } + } + + /* Finally, the role */ + ptr = strstr(info, "role:"); + if (!ptr) { + ret->role = APR_RS_SERVER_UNKNOWN; + } + else if (!strncmp("master", ptr + sizeof("role:") - 1, sizeof("master")-1)) { + ret->role = APR_RS_SERVER_MASTER; + } + else { + ret->role = APR_RS_SERVER_SLAVE; + } + if (stats) { + *stats = ret; + } + + return APR_SUCCESS; +} diff --git a/contrib/apr-util/test/Makefile.in b/contrib/apr-util/test/Makefile.in index 5f4cf91b9b13..e1b4d7c20333 100644 --- a/contrib/apr-util/test/Makefile.in +++ b/contrib/apr-util/test/Makefile.in @@ -17,7 +17,7 @@ STDTEST_PORTABLE = dbd testall TESTS = teststrmatch.lo testuri.lo testuuid.lo testbuckets.lo testpass.lo \ testmd4.lo testmd5.lo testldap.lo testdate.lo testdbm.lo testdbd.lo \ testxml.lo testrmm.lo testreslist.lo testqueue.lo testxlate.lo \ - testmemcache.lo testcrypto.lo + testmemcache.lo testcrypto.lo testsiphash.lo testredis.lo PROGRAMS = $(STDTEST_PORTABLE) diff --git a/contrib/apr-util/test/Makefile.win b/contrib/apr-util/test/Makefile.win index a30f39e2b520..fa3d2eba5c2f 100644 --- a/contrib/apr-util/test/Makefile.win +++ b/contrib/apr-util/test/Makefile.win @@ -62,6 +62,7 @@ ALL_TESTS = $(INTDIR)\teststrmatch.obj $(INTDIR)\testuri.obj \ $(INTDIR)\testxml.obj $(INTDIR)\testqueue.obj \ $(INTDIR)\testrmm.obj $(INTDIR)\testxlate.obj \ $(INTDIR)\testdate.obj $(INTDIR)\testmemcache.obj \ + $(INTDIR)\testredis.obj $(INTDIR)\testsiphash.obj \ $(INTDIR)\testcrypto.obj CLEAN_DATA = manyfile.bin testfile.txt data\sqlite*.db @@ -89,10 +90,9 @@ APROUTDIR=$(OUTDIR) PROGRAM_DEPENDENCIES = \ $(APR_PATH)\$(APROUTDIR)\apr-1.lib \ $(API_PATH)\$(OUTDIR)\apriconv-1.lib \ - ..\xml\expat\lib\$(OUTDIR)\xml.lib \ ..\$(OUTDIR)\aprutil-1.lib STATIC_CFLAGS = /D APR_DECLARE_STATIC /D APU_DECLARE_STATIC -STATIC_LIBS = odbc32.lib odbccp32.lib wldap32.lib +STATIC_LIBS = libexpatMT.lib odbc32.lib odbccp32.lib wldap32.lib !ELSE PROGRAM_DEPENDENCIES = \ $(APR_PATH)\$(APROUTDIR)\libapr-1.lib \ diff --git a/contrib/apr-util/test/NWGNUaputest b/contrib/apr-util/test/NWGNUaputest index 6b710ad84d53..caf3cd49f6f5 100644 --- a/contrib/apr-util/test/NWGNUaputest +++ b/contrib/apr-util/test/NWGNUaputest @@ -185,6 +185,7 @@ FILES_nlm_objs = \ $(OBJDIR)/testqueue.o \ $(OBJDIR)/testreslist.o \ $(OBJDIR)/testrmm.o \ + $(OBJDIR)/testsiphash.o \ $(OBJDIR)/teststrmatch.o \ $(OBJDIR)/testuri.o \ $(OBJDIR)/testutil.o \ diff --git a/contrib/apr-util/test/abts_tests.h b/contrib/apr-util/test/abts_tests.h index b612d31b8fa5..cb4e113fe8b6 100644 --- a/contrib/apr-util/test/abts_tests.h +++ b/contrib/apr-util/test/abts_tests.h @@ -35,12 +35,14 @@ const struct testlist { {testdbd}, {testdate}, {testmemcache}, + {testredis}, {testxml}, {testxlate}, {testrmm}, {testdbm}, {testqueue}, - {testreslist} + {testreslist}, + {testsiphash} }; #endif /* APR_TEST_INCLUDES */ diff --git a/contrib/apr-util/test/testall.dsw b/contrib/apr-util/test/testall.dsw index 0a640c8be296..7fde202c2b07 100644 --- a/contrib/apr-util/test/testall.dsw +++ b/contrib/apr-util/test/testall.dsw @@ -28,23 +28,6 @@ Package=<4> End Project Dependency }}} -############################################################################### - -Project: "apr_dbd_freetds"="..\dbd\apr_dbd_freetds.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libapr - End Project Dependency - Begin Project Dependency - Project_Dep_Name libaprutil - End Project Dependency -}}} ############################################################################### diff --git a/contrib/apr-util/test/testcrypto.c b/contrib/apr-util/test/testcrypto.c index 335c3ae65d77..865cffc6d5ed 100644 --- a/contrib/apr-util/test/testcrypto.c +++ b/contrib/apr-util/test/testcrypto.c @@ -33,22 +33,32 @@ static const apr_crypto_driver_t *get_driver(abts_case *tc, apr_pool_t *pool, { const apr_crypto_driver_t *driver = NULL; - const apu_err_t *err = NULL; + const apu_err_t *result = NULL; apr_status_t rv; rv = apr_crypto_init(pool); ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS); - rv = apr_crypto_get_driver(&driver, name, params, &err, pool); - if (APR_SUCCESS != rv && err) { - ABTS_NOT_IMPL(tc, err->msg); - return NULL; - } + rv = apr_crypto_get_driver(&driver, name, params, &result, pool); if (APR_ENOTIMPL == rv) { - ABTS_NOT_IMPL(tc, (char *)driver); + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "Crypto driver '%s' not implemented", (char *)name)); return NULL; } - ABTS_ASSERT(tc, "failed to apr_crypto_get_driver", rv == APR_SUCCESS); + if (APR_EDSOOPEN == rv) { + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "Crypto driver '%s' DSO could not be opened", (char *)name)); + return NULL; + } + if (APR_SUCCESS != rv && result) { + char err[1024]; + apr_strerror(rv, err, sizeof(err) - 1); + fprintf(stderr, "get_driver error %d: %s: '%s' native error %d: %s (%s),", + rv, err, name, result->rc, result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, apr_psprintf(pool, "failed to apr_crypto_get_driver for '%s' with %d", + name, rv), rv == APR_SUCCESS); ABTS_ASSERT(tc, "apr_crypto_get_driver returned NULL", driver != NULL); if (!driver || rv) { return NULL; @@ -63,7 +73,7 @@ static const apr_crypto_driver_t *get_nss_driver(abts_case *tc, { /* initialise NSS */ - return get_driver(tc, pool, "nss", "dir=data"); + return get_driver(tc, pool, "nss", ""); } @@ -75,6 +85,14 @@ static const apr_crypto_driver_t *get_openssl_driver(abts_case *tc, } +static const apr_crypto_driver_t *get_commoncrypto_driver(abts_case *tc, + apr_pool_t *pool) +{ + + return get_driver(tc, pool, "commoncrypto", NULL); + +} + static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver) { @@ -93,6 +111,59 @@ static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool, } +static const apr_crypto_key_t *keysecret(abts_case *tc, apr_pool_t *pool, + const apr_crypto_driver_t *driver, const apr_crypto_t *f, + apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, + int doPad, apr_size_t secretLen, const char *description) +{ + apr_crypto_key_t *key = NULL; + const apu_err_t *result = NULL; + apr_crypto_key_rec_t *rec = apr_pcalloc(pool, sizeof(apr_crypto_key_rec_t)); + apr_status_t rv; + + if (!f) { + return NULL; + } + + rec->ktype = APR_CRYPTO_KTYPE_SECRET; + rec->type = type; + rec->mode = mode; + rec->pad = doPad; + rec->k.secret.secret = apr_pcalloc(pool, secretLen); + rec->k.secret.secretLen = secretLen; + + /* init the passphrase */ + rv = apr_crypto_key(&key, rec, f, pool); + if (APR_ENOCIPHER == rv) { + apr_crypto_error(&result, f); + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "skipped: %s %s key return APR_ENOCIPHER: error %d: %s (%s)\n", description, apr_crypto_driver_name(driver), result->rc, result->reason ? result->reason : "", result->msg ? result->msg : "")); + return NULL; + } + else { + if (APR_SUCCESS != rv) { + apr_crypto_error(&result, f); + fprintf(stderr, "key: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_ENOKEY", rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EPADDING", + rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYTYPE", + rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "failed to apr_crypto_key", rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_key returned NULL context", key != NULL); + } + if (rv) { + return NULL; + } + return key; + +} + static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver, const apr_crypto_t *f, apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, @@ -124,8 +195,8 @@ static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "passphrase: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, "passphrase: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } @@ -142,6 +213,64 @@ static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, } +static const apr_crypto_key_t *keypassphrase(abts_case *tc, apr_pool_t *pool, + const apr_crypto_driver_t *driver, const apr_crypto_t *f, + apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, + int doPad, const char *description) +{ + + apr_crypto_key_t *key = NULL; + const apu_err_t *result = NULL; + const char *pass = "secret"; + const char *salt = "salt"; + apr_crypto_key_rec_t *rec = apr_pcalloc(pool, sizeof(apr_crypto_key_rec_t)); + apr_status_t rv; + + if (!f) { + return NULL; + } + + rec->ktype = APR_CRYPTO_KTYPE_PASSPHRASE; + rec->type = type; + rec->mode = mode; + rec->pad = doPad; + rec->k.passphrase.pass = pass; + rec->k.passphrase.passLen = strlen(pass); + rec->k.passphrase.salt = (unsigned char *)salt; + rec->k.passphrase.saltLen = strlen(salt); + rec->k.passphrase.iterations = 4096; + + /* init the passphrase */ + rv = apr_crypto_key(&key, rec, f, pool); + if (APR_ENOCIPHER == rv) { + apr_crypto_error(&result, f); + ABTS_NOT_IMPL(tc, apr_psprintf(pool, + "skipped: %s %s key passphrase return APR_ENOCIPHER: error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), result->rc, + result->reason ? result->reason : "", result->msg ? result->msg : "")); + return NULL; + } + else { + if (APR_SUCCESS != rv) { + apr_crypto_error(&result, f); + fprintf(stderr, "key passphrase: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, "apr_crypto_key returned APR_ENOKEY", rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYTYPE", rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "failed to apr_crypto_key", rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_key returned NULL context", key != NULL); + } + if (rv) { + return NULL; + } + return key; + +} + static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver, const apr_crypto_t *f, const apr_crypto_key_t *key, const unsigned char *in, @@ -167,17 +296,27 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt_init: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, + "encrypt_init: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", rv != APR_ENOKEY); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", rv != APR_ENOIV); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYTYPE", rv != APR_EKEYTYPE); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH); - ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_init", rv == APR_SUCCESS); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned NULL context", block != NULL); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", + rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", + rv != APR_ENOIV); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYTYPE", + rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYLENGTH", + rv != APR_EKEYLENGTH); + ABTS_ASSERT(tc, + "apr_crypto_block_encrypt_init returned APR_ENOTENOUGHENTROPY", + rv != APR_ENOTENOUGHENTROPY); + ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_init", + rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned NULL context", + block != NULL); } if (!block || rv) { return NULL; @@ -187,10 +326,10 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, rv = apr_crypto_block_encrypt(cipherText, cipherTextLen, in, inlen, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, "encrypt: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_encrypt returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt", rv == APR_SUCCESS); @@ -204,13 +343,15 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt_finish: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, + "encrypt_finish: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ENOSPACE", rv != APR_ENOSPACE); ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_finish", rv == APR_SUCCESS); *cipherTextLen += len; apr_crypto_block_cleanup(block); @@ -247,8 +388,9 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt_init: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, + "decrypt_init: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } @@ -268,10 +410,10 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, cipherTextLen, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, "decrypt: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_decrypt returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt", rv == APR_SUCCESS); @@ -285,13 +427,15 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt_finish: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, + "decrypt_finish: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ENOSPACE", rv != APR_ENOSPACE); ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt_finish", rv == APR_SUCCESS); if (rv) { return NULL; @@ -316,7 +460,8 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t **drivers, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, int doPad, - const unsigned char *in, apr_size_t inlen, const char *description) + const unsigned char *in, apr_size_t inlen, apr_size_t secretLen, + const char *description) { const apr_crypto_driver_t *driver1 = drivers[0]; const apr_crypto_driver_t *driver2 = drivers[1]; @@ -324,6 +469,10 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, apr_crypto_t *f2 = NULL; const apr_crypto_key_t *key1 = NULL; const apr_crypto_key_t *key2 = NULL; + const apr_crypto_key_t *key3 = NULL; + const apr_crypto_key_t *key4 = NULL; + const apr_crypto_key_t *key5 = NULL; + const apr_crypto_key_t *key6 = NULL; unsigned char *cipherText = NULL; apr_size_t cipherTextLen = 0; @@ -345,7 +494,51 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, if (cipherText && plainText) { if (memcmp(in, plainText, inlen)) { - fprintf(stderr, "cross mismatch: %s %s/%s\n", description, + fprintf(stderr, "passphrase cross mismatch: %s %s/%s\n", description, + apr_crypto_driver_name(driver1), apr_crypto_driver_name( + driver2)); + } + ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); + } + + key3 = keysecret(tc, pool, driver1, f1, type, mode, doPad, secretLen, description); + key4 = keysecret(tc, pool, driver2, f2, type, mode, doPad, secretLen, description); + + iv = NULL; + blockSize = 0; + cipherText = NULL; + plainText = NULL; + cipherText = encrypt_block(tc, pool, driver1, f1, key3, in, inlen, + &cipherText, &cipherTextLen, &iv, &blockSize, description); + plainText = decrypt_block(tc, pool, driver2, f2, key4, cipherText, + cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, + description); + + if (cipherText && plainText) { + if (memcmp(in, plainText, inlen)) { + fprintf(stderr, "key secret cross mismatch: %s %s/%s\n", description, + apr_crypto_driver_name(driver1), apr_crypto_driver_name( + driver2)); + } + ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); + } + + key5 = keypassphrase(tc, pool, driver1, f1, type, mode, doPad, description); + key6 = keypassphrase(tc, pool, driver2, f2, type, mode, doPad, description); + + iv = NULL; + blockSize = 0; + cipherText = NULL; + plainText = NULL; + cipherText = encrypt_block(tc, pool, driver1, f1, key5, in, inlen, + &cipherText, &cipherTextLen, &iv, &blockSize, description); + plainText = decrypt_block(tc, pool, driver2, f2, key6, cipherText, + cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, + description); + + if (cipherText && plainText) { + if (memcmp(in, plainText, inlen)) { + fprintf(stderr, "key passphrase cross mismatch: %s %s/%s\n", description, apr_crypto_driver_name(driver1), apr_crypto_driver_name( driver2)); } @@ -371,6 +564,63 @@ static void test_crypto_init(abts_case *tc, void *data) } +/** + * Simple test of OpenSSL key. + */ +static void test_crypto_key_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_openssl_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of NSS key. + */ +static void test_crypto_key_nss(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_nss_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of CommonCrypto key. + */ +static void test_crypto_key_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_commoncrypto_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + /** * Simple test of OpenSSL block crypt. */ @@ -386,21 +636,21 @@ static void test_crypto_block_openssl(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, - in, inlen, "KEY_3DES_192/MODE_ECB"); + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -420,21 +670,55 @@ static void test_crypto_block_nss(abts_case *tc, void *data) drivers[0] = get_nss_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of Common Crypto block crypt. + */ +static void test_crypto_block_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -455,25 +739,22 @@ static void test_crypto_block_nss_openssl(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); - - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB"); - */ + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -493,26 +774,95 @@ static void test_crypto_block_openssl_nss(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB"); - */ +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_openssl_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_openssl_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); + +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_commoncrypto_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_openssl_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -533,21 +883,21 @@ static void test_crypto_block_openssl_pad(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, - in, inlen, "KEY_3DES_192/MODE_ECB"); + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); @@ -570,27 +920,63 @@ static void test_crypto_block_nss_pad(abts_case *tc, void *data) drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, 24, "KEY_AES_192/MODE_ECB");*/ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, 16, "KEY_AES_128/MODE_ECB");*/ + + apr_pool_destroy(pool); + +} + +/** + * Simple test of Common Crypto block crypt. + */ +static void test_crypto_block_commoncrypto_pad(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); @@ -612,27 +998,31 @@ static void test_crypto_block_nss_openssl_pad(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB");*/ - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB"); - */ apr_pool_destroy(pool); } @@ -652,27 +1042,107 @@ static void test_crypto_block_openssl_nss_pad(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, inlen, + 24, "KEY_AES_192/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, inlen, + 24, "KEY_AES_192/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, inlen, + 16, "KEY_AES_128/MODE_CBC"); + + /* KEY_AES_128 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, inlen, + 16, "KEY_AES_128/MODE_ECB");*/ + + apr_pool_destroy(pool); + +} + +/** + * Encrypt CommonCrypto, decrypt OpenSSL. + */ +static void test_crypto_block_commoncrypto_openssl_pad(abts_case *tc, + void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_openssl_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + + apr_pool_destroy(pool); + +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_openssl_commoncrypto_pad(abts_case *tc, + void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_openssl_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB"); - */ apr_pool_destroy(pool); } @@ -763,6 +1233,49 @@ static void test_crypto_get_block_key_types_nss(abts_case *tc, void *data) } +/** + * Get Types, Common Crypto. + */ +static void test_crypto_get_block_key_types_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *types; + int *key_3des_192; + int *key_aes_128; + int *key_aes_192; + int *key_aes_256; + + apr_pool_create(&pool, NULL); + driver = get_commoncrypto_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_types(&types, f); + + key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_3des_192); + ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192); + + key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_128); + ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128); + + key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_192); + ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192); + + key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_256); + ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256); + + } + + apr_pool_destroy(pool); + +} + /** * Get Modes, OpenSSL. */ @@ -829,6 +1342,114 @@ static void test_crypto_get_block_key_modes_nss(abts_case *tc, void *data) } +/** + * Get Modes, Common Crypto. + */ +static void test_crypto_get_block_key_modes_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *modes; + int *mode_ecb; + int *mode_cbc; + + apr_pool_create(&pool, NULL); + driver = get_commoncrypto_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_modes(&modes, f); + + mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_ecb); + ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB); + + mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_cbc); + ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC); + + } + + apr_pool_destroy(pool); + +} + +static void test_crypto_memzero(abts_case *tc, void *data) +{ + /* Aligned message */ + struct { + char buf[7 * sizeof(int)]; + int untouched; + } msg; + /* A bit of type punning such that 'msg' might look unused + * after the call to apr_crypto_memzero(). + */ + int *ptr = (int *)&msg; + int i; + + /* Fill buf with non-zeros (odds) */ + for (i = 1; i < 2 * sizeof(msg.buf); i += 2) { + msg.buf[i / 2] = (char)i; + ABTS_ASSERT(tc, "test_crypto_memzero() barrier", msg.buf[i / 2] != 0); + } + + /* Zero out the whole, and check it */ + apr_crypto_memzero(&msg, sizeof msg); + for (i = 0; i < sizeof(msg) / sizeof(*ptr); ++i) { + ABTS_ASSERT(tc, "test_crypto_memzero() optimized out", ptr[i] == 0); + } +} + +static void test_crypto_equals(abts_case *tc, void *data) +{ + /* Buffers of each type of scalar */ + union { + char c; + short s; + int i; + long l; + float f; + double d; + void *p; + } buf0[7], buf1[7], buf[7]; + char *ptr = (char *)buf; + int i; + +#define TEST_SCALAR_MATCH(i, x, r) \ + ABTS_ASSERT(tc, "test_crypto_equals(" APR_STRINGIFY(x) ")" \ + " != " APR_STRINGIFY(r), \ + apr_crypto_equals(&buf##r[i].x, &buf[i].x, \ + sizeof(buf[i].x)) == r) + + /* Fill buf with non-zeros (odds) */ + for (i = 1; i < 2 * sizeof(buf); i += 2) { + ptr[i / 2] = (char)i; + } + /* Set buf1 = buf */ + memcpy(buf1, buf, sizeof buf); + /* Set buf0 = {0} */ + memset(buf0, 0, sizeof buf0); + + /* Check that buf1 == buf for each scalar */ + TEST_SCALAR_MATCH(0, c, 1); + TEST_SCALAR_MATCH(1, s, 1); + TEST_SCALAR_MATCH(2, i, 1); + TEST_SCALAR_MATCH(3, l, 1); + TEST_SCALAR_MATCH(4, f, 1); + TEST_SCALAR_MATCH(5, d, 1); + TEST_SCALAR_MATCH(6, p, 1); + + /* Check that buf0 != buf for each scalar */ + TEST_SCALAR_MATCH(0, c, 0); + TEST_SCALAR_MATCH(1, s, 0); + TEST_SCALAR_MATCH(2, i, 0); + TEST_SCALAR_MATCH(3, l, 0); + TEST_SCALAR_MATCH(4, f, 0); + TEST_SCALAR_MATCH(5, d, 0); + TEST_SCALAR_MATCH(6, p, 0); +} + abts_suite *testcrypto(abts_suite *suite) { suite = ADD_SUITE(suite); @@ -836,6 +1457,15 @@ abts_suite *testcrypto(abts_suite *suite) /* test simple init and shutdown */ abts_run_test(suite, test_crypto_init, NULL); + /* test key parsing - openssl */ + abts_run_test(suite, test_crypto_key_openssl, NULL); + + /* test key parsing - nss */ + abts_run_test(suite, test_crypto_key_nss, NULL); + + /* test key parsing - commoncrypto */ + abts_run_test(suite, test_crypto_key_commoncrypto, NULL); + /* test a simple encrypt / decrypt operation - openssl */ abts_run_test(suite, test_crypto_block_openssl, NULL); @@ -848,6 +1478,12 @@ abts_suite *testcrypto(abts_suite *suite) /* test a padded encrypt / decrypt operation - nss */ abts_run_test(suite, test_crypto_block_nss_pad, NULL); + /* test a simple encrypt / decrypt operation - commoncrypto */ + abts_run_test(suite, test_crypto_block_commoncrypto, NULL); + + /* test a padded encrypt / decrypt operation - commoncrypto */ + abts_run_test(suite, test_crypto_block_commoncrypto_pad, NULL); + /* test encrypt nss / decrypt openssl */ abts_run_test(suite, test_crypto_block_nss_openssl, NULL); @@ -860,18 +1496,39 @@ abts_suite *testcrypto(abts_suite *suite) /* test padded encrypt openssl / decrypt nss */ abts_run_test(suite, test_crypto_block_openssl_nss_pad, NULL); + /* test encrypt openssl / decrypt commoncrypto */ + abts_run_test(suite, test_crypto_block_openssl_commoncrypto, NULL); + + /* test padded encrypt openssl / decrypt commoncrypto */ + abts_run_test(suite, test_crypto_block_openssl_commoncrypto_pad, NULL); + + /* test encrypt commoncrypto / decrypt openssl */ + abts_run_test(suite, test_crypto_block_commoncrypto_openssl, NULL); + + /* test padded encrypt commoncrypto / decrypt openssl */ + abts_run_test(suite, test_crypto_block_commoncrypto_openssl_pad, NULL); + /* test block key types openssl */ abts_run_test(suite, test_crypto_get_block_key_types_openssl, NULL); /* test block key types nss */ abts_run_test(suite, test_crypto_get_block_key_types_nss, NULL); + /* test block key types commoncrypto */ + abts_run_test(suite, test_crypto_get_block_key_types_commoncrypto, NULL); + /* test block key modes openssl */ abts_run_test(suite, test_crypto_get_block_key_modes_openssl, NULL); /* test block key modes nss */ abts_run_test(suite, test_crypto_get_block_key_modes_nss, NULL); + /* test block key modes commoncrypto */ + abts_run_test(suite, test_crypto_get_block_key_modes_commoncrypto, NULL); + + abts_run_test(suite, test_crypto_memzero, NULL); + abts_run_test(suite, test_crypto_equals, NULL); + return suite; } diff --git a/contrib/apr-util/test/testredis.c b/contrib/apr-util/test/testredis.c new file mode 100644 index 000000000000..4b654322f54e --- /dev/null +++ b/contrib/apr-util/test/testredis.c @@ -0,0 +1,552 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "testutil.h" +#include "apr.h" +#include "apu.h" +#include "apr_general.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "apr_redis.h" +#include "apr_network_io.h" + +#include +#if APR_HAVE_STDLIB_H +#include /* for exit() */ +#endif + +#define HOST "localhost" +#define PORT 6379 + +/* the total number of items to use for set/get testing */ +#define TDATA_SIZE 3000 + +/* some smaller subset of TDATA_SIZE used for multiget testing */ +#define TDATA_SET 100 + +/* our custom hash function just returns this all the time */ +#define HASH_FUNC_RESULT 510 + +/* all keys will be prefixed with this */ +static const char prefix[] = "testredis"; + +/* text for values we store */ +static const char txt[] = +"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis at" +"lacus in ligula hendrerit consectetuer. Vestibulum tristique odio" +"iaculis leo. In massa arcu, ultricies a, laoreet nec, hendrerit non," +"neque. Nulla sagittis sapien ac risus. Morbi ligula dolor, vestibulum" +"nec, viverra id, placerat dapibus, arcu. Curabitur egestas feugiat" +"tellus. Donec dignissim. Nunc ante. Curabitur id lorem. In mollis" +"tortor sit amet eros auctor dapibus. Proin nulla sem, tristique in," +"convallis id, iaculis feugiat cras amet."; + +/* + * this datatype is for our custom server determination function. this might + * be useful if you don't want to rely on simply hashing keys to determine + * where a key belongs, but instead want to write something fancy, or use some + * other kind of configuration data, i.e. a hash plus some data about a + * namespace, or whatever. see my_server_func, and test_redis_user_funcs + * for the examples. + */ +typedef struct { + const char *someval; + apr_uint32_t which_server; +} my_hash_server_baton; + + +/* this could do something fancy and return some hash result. + * for simplicity, just return the same value, so we can test it later on. + * if you wanted to use some external hashing library or functions for + * consistent hashing, for example, this would be a good place to do it. + */ +static apr_uint32_t my_hash_func(void *baton, const char *data, + apr_size_t data_len) +{ + + return HASH_FUNC_RESULT; +} + +/* + * a fancy function to determine which server to use given some kind of data + * and a hash value. this example actually ignores the hash value itself + * and pulls some number from the *baton, which is a struct that has some + * kind of meaningful stuff in it. + */ +static apr_redis_server_t *my_server_func(void *baton, + apr_redis_t *mc, + const apr_uint32_t hash) +{ + apr_redis_server_t *ms = NULL; + my_hash_server_baton *mhsb = (my_hash_server_baton *)baton; + + if(mc->ntotal == 0) { + return NULL; + } + + if(mc->ntotal < mhsb->which_server) { + return NULL; + } + + ms = mc->live_servers[mhsb->which_server - 1]; + + return ms; +} + +static apr_uint16_t firsttime = 0; +static int randval(apr_uint32_t high) +{ + apr_uint32_t i = 0; + double d = 0; + + if (firsttime == 0) { + srand((unsigned) (getpid())); + firsttime = 1; + } + + d = (double) rand() / ((double) RAND_MAX + 1); + i = (int) (d * (high - 0 + 1)); + + return i > 0 ? i : 1; +} + +/* + * general test to make sure we can create the redis struct and add + * some servers, but not more than we tell it we can add + */ + +static void test_redis_create(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server, *s; + apr_uint32_t max_servers = 10; + apr_uint32_t i; + apr_uint32_t hash; + + rv = apr_redis_create(pool, max_servers, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + for (i = 1; i <= max_servers; i++) { + apr_port_t port; + + port = PORT + i; + rv = + apr_redis_server_create(pool, HOST, PORT + i, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + s = apr_redis_find_server(redis, HOST, port); + ABTS_PTR_EQUAL(tc, server, s); + + rv = apr_redis_disable_server(redis, s); + ABTS_ASSERT(tc, "server disable failed", rv == APR_SUCCESS); + + rv = apr_redis_enable_server(redis, s); + ABTS_ASSERT(tc, "server enable failed", rv == APR_SUCCESS); + + hash = apr_redis_hash(redis, prefix, strlen(prefix)); + ABTS_ASSERT(tc, "hash failed", hash > 0); + + s = apr_redis_find_server_hash(redis, hash); + ABTS_PTR_NOTNULL(tc, s); + } + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add should have failed", rv != APR_SUCCESS); + +} + +/* install our own custom hashing and server selection routines. */ + +static int create_test_hash(apr_pool_t *p, apr_hash_t *h) +{ + int i; + + for (i = 0; i < TDATA_SIZE; i++) { + char *k, *v; + + k = apr_pstrcat(p, prefix, apr_itoa(p, i), NULL); + v = apr_pstrndup(p, txt, randval((apr_uint32_t)strlen(txt))); + + apr_hash_set(h, k, APR_HASH_KEY_STRING, v); + } + + return i; +} + +static void test_redis_user_funcs(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *found; + apr_uint32_t max_servers = 10; + apr_uint32_t hres; + apr_uint32_t i; + my_hash_server_baton *baton = + apr_pcalloc(pool, sizeof(my_hash_server_baton)); + + rv = apr_redis_create(pool, max_servers, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + /* as noted above, install our custom hash function, and call + * apr_redis_hash. the return value should be our predefined number, + * and our function just ignores the other args, for simplicity. + */ + redis->hash_func = my_hash_func; + + hres = apr_redis_hash(redis, "whatever", sizeof("whatever") - 1); + ABTS_INT_EQUAL(tc, HASH_FUNC_RESULT, hres); + + /* add some servers */ + for(i = 1; i <= 10; i++) { + apr_redis_server_t *ms; + + rv = apr_redis_server_create(pool, HOST, i, 0, 1, 1, 60, 60, &ms); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, ms); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + } + + /* + * set 'which_server' in our server_baton to find the third server + * which should have the same port. + */ + baton->which_server = 3; + redis->server_func = my_server_func; + redis->server_baton = baton; + found = apr_redis_find_server_hash(redis, 0); + ABTS_ASSERT(tc, "wrong server found", found->port == baton->which_server); +} + +/* test non data related commands like stats and version */ +static void test_redis_meta(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_redis_stats_t *stats; + char *result; + apr_status_t rv; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + rv = apr_redis_version(server, pool, &result); + ABTS_PTR_NOTNULL(tc, result); + + rv = apr_redis_stats(server, p, &stats); + ABTS_PTR_NOTNULL(tc, stats); + + /* + * no way to know exactly what will be in most of these, so + * just make sure there is something. + */ + ABTS_ASSERT(tc, "major", stats->major >= 1); + ABTS_ASSERT(tc, "minor", stats->minor >= 0); + ABTS_ASSERT(tc, "patch", stats->patch >= 0); + ABTS_ASSERT(tc, "process_id", stats->process_id >= 0); + ABTS_ASSERT(tc, "uptime_in_seconds", stats->uptime_in_seconds >= 0); + ABTS_ASSERT(tc, "arch_bits", stats->arch_bits >= 0); + ABTS_ASSERT(tc, "connected_clients", stats->connected_clients >= 0); + ABTS_ASSERT(tc, "blocked_clients", stats->blocked_clients >= 0); + ABTS_ASSERT(tc, "maxmemory", stats->maxmemory >= 0); + ABTS_ASSERT(tc, "used_memory", stats->used_memory >= 0); + ABTS_ASSERT(tc, "total_system_memory", stats->total_system_memory >= 0); + ABTS_ASSERT(tc, "total_connections_received", stats->total_connections_received >= 0); + ABTS_ASSERT(tc, "total_commands_processed", stats->total_commands_processed >= 0); + ABTS_ASSERT(tc, "total_net_input_bytes", stats->total_net_input_bytes >= 0); + ABTS_ASSERT(tc, "total_net_output_bytes", stats->total_net_output_bytes >= 0); + ABTS_ASSERT(tc, "keyspace_hits", stats->keyspace_hits >= 0); + ABTS_ASSERT(tc, "keyspace_misses", stats->keyspace_misses >= 0); + ABTS_ASSERT(tc, "role", stats->role >= 0); + ABTS_ASSERT(tc, "connected_slaves", stats->connected_slaves >= 0); + ABTS_ASSERT(tc, "used_cpu_sys", stats->used_cpu_sys >= 0); + ABTS_ASSERT(tc, "used_cpu_user", stats->used_cpu_user >= 0); + ABTS_ASSERT(tc, "cluster_enabled", stats->cluster_enabled >= 0); +} + + +/* basic tests of the increment and decrement commands */ +static void test_redis_incrdecr(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_uint32_t new; + char *result; + apr_size_t len; + apr_uint32_t i; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + rv = apr_redis_set(redis, prefix, "271", sizeof("271") - 1, 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + + for( i = 1; i <= TDATA_SIZE; i++) { + apr_uint32_t expect; + + rv = apr_redis_getp(redis, pool, prefix, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + + expect = i + atoi(result); + + rv = apr_redis_incr(redis, prefix, i, &new); + ABTS_ASSERT(tc, "incr failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, expect, new); + + rv = apr_redis_decr(redis, prefix, i, &new); + ABTS_ASSERT(tc, "decr failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, atoi(result), new); + + } + + rv = apr_redis_getp(redis, pool, prefix, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, 271, atoi(result)); + + rv = apr_redis_delete(redis, prefix, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); +} + + +/* test setting and getting */ + +static void test_redis_setget(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_hash_t *tdata; + apr_hash_index_t *hi; + char *result; + apr_size_t len; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + tdata = apr_hash_make(pool); + + create_test_hash(pool, tdata); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + void *v; + const char *key; + + apr_hash_this(hi, &k, NULL, &v); + key = k; + + rv = apr_redis_set(redis, key, v, strlen(v), 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + rv = apr_redis_getp(redis, pool, key, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + } + + rv = apr_redis_getp(redis, pool, "nothere3423", &result, &len, NULL); + + ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + const char *key; + + apr_hash_this(hi, &k, NULL, NULL); + key = k; + + rv = apr_redis_delete(redis, key, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); + } +} + +/* test setting and getting */ + +static void test_redis_setexget(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_hash_t *tdata; + apr_hash_index_t *hi; + char *result; + apr_size_t len; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + tdata = apr_hash_make(pool); + + create_test_hash(pool, tdata); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + void *v; + const char *key; + + apr_hash_this(hi, &k, NULL, &v); + key = k; + + rv = apr_redis_ping(server); + ABTS_ASSERT(tc, "ping failed", rv == APR_SUCCESS); + rv = apr_redis_setex(redis, key, v, strlen(v), 10, 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + rv = apr_redis_getp(redis, pool, key, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + } + + rv = apr_redis_getp(redis, pool, "nothere3423", &result, &len, NULL); + + ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + const char *key; + + apr_hash_this(hi, &k, NULL, NULL); + key = k; + + rv = apr_redis_delete(redis, key, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); + } +} + +/* use apr_socket stuff to see if there is in fact a Redis server + * running on PORT. + */ +static apr_status_t check_redis(void) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_socket_t *sock = NULL; + apr_sockaddr_t *sa; + struct iovec vec[2]; + apr_size_t written; + char buf[128]; + apr_size_t len; + + rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, pool); + if(rv != APR_SUCCESS) { + return rv; + } + + rv = apr_sockaddr_info_get(&sa, HOST, APR_INET, PORT, 0, pool); + if(rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(sock, 1 * APR_USEC_PER_SEC); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_connect(sock, sa); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(sock, -1); + if (rv != APR_SUCCESS) { + return rv; + } + + vec[0].iov_base = "PING"; + vec[0].iov_len = sizeof("PING") - 1; + + vec[1].iov_base = "\r\n"; + vec[1].iov_len = sizeof("\r\n") -1; + + rv = apr_socket_sendv(sock, vec, 2, &written); + if (rv != APR_SUCCESS) { + return rv; + } + + len = sizeof(buf); + rv = apr_socket_recv(sock, buf, &len); + if(rv != APR_SUCCESS) { + return rv; + } + if(strncmp(buf, "+PONG", sizeof("+PONG")-1) != 0) { + rv = APR_EGENERAL; + } + + apr_socket_close(sock); + return rv; +} + +abts_suite *testredis(abts_suite * suite) +{ + apr_status_t rv; + suite = ADD_SUITE(suite); + /* check for a running redis on the typical port before + * trying to run the tests. succeed if we don't find one. + */ + rv = check_redis(); + if (rv == APR_SUCCESS) { + abts_run_test(suite, test_redis_create, NULL); + abts_run_test(suite, test_redis_user_funcs, NULL); + abts_run_test(suite, test_redis_meta, NULL); + abts_run_test(suite, test_redis_setget, NULL); + abts_run_test(suite, test_redis_setexget, NULL); + /* abts_run_test(suite, test_redis_multiget, NULL); */ + abts_run_test(suite, test_redis_incrdecr, NULL); + } + else { + abts_log_message("Error %d occurred attempting to reach Redis " + "on %s:%d. Skipping apr_redis tests...", + rv, HOST, PORT); + } + + return suite; +} diff --git a/contrib/apr-util/test/testsiphash.c b/contrib/apr-util/test/testsiphash.c new file mode 100644 index 000000000000..58321adebd85 --- /dev/null +++ b/contrib/apr-util/test/testsiphash.c @@ -0,0 +1,148 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "apr_siphash.h" + +#include "abts.h" +#include "testutil.h" + +/* + * Wrapped test vectors from the authors, see + * https://131002.net/siphash/siphash24.c + */ +typedef unsigned char u8; +#define crypto_auth apr_siphash24_auth + +#define MAXLEN 64 + +/* + SipHash-2-4 output with + k = 00 01 02 ... + and + in = (empty string) + in = 00 (1 byte) + in = 00 01 (2 bytes) + in = 00 01 02 (3 bytes) + ... + in = 00 01 02 ... 3e (63 bytes) +*/ +static const u8 vectors[MAXLEN][8] = +{ + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } +}; + +static int test_vectors(void) +{ + u8 in[MAXLEN], out[8], k[16]; + int i; + int ok = 1; + + for( i = 0; i < 16; ++i ) k[i] = i; + + for( i = 0; i < MAXLEN; ++i ) + { + in[i] = i; + crypto_auth( out, in, i, k ); + + if ( memcmp( out, vectors[i], 8 ) ) + { + printf( "test vector failed for %d bytes\n", i ); + ok = 0; + } + } + + return ok; +} + +static void test_siphash_vectors(abts_case *tc, void *data) +{ + ABTS_ASSERT(tc, "SipHash-2-4 test vectors", test_vectors()); +} + +abts_suite *testsiphash(abts_suite *suite) +{ + suite = ADD_SUITE(suite); + + abts_run_test(suite, test_siphash_vectors, NULL); + + return suite; +} diff --git a/contrib/apr-util/test/testutil.h b/contrib/apr-util/test/testutil.h index c471af40a4a6..eaa7e7590572 100644 --- a/contrib/apr-util/test/testutil.h +++ b/contrib/apr-util/test/testutil.h @@ -61,11 +61,13 @@ abts_suite *testldap(abts_suite *suite); abts_suite *testdbd(abts_suite *suite); abts_suite *testdate(abts_suite *suite); abts_suite *testmemcache(abts_suite *suite); +abts_suite *testredis(abts_suite *suite); abts_suite *testreslist(abts_suite *suite); abts_suite *testqueue(abts_suite *suite); abts_suite *testxml(abts_suite *suite); abts_suite *testxlate(abts_suite *suite); abts_suite *testrmm(abts_suite *suite); abts_suite *testdbm(abts_suite *suite); +abts_suite *testsiphash(abts_suite *suite); #endif /* APR_TEST_INCLUDES */ diff --git a/contrib/apr-util/xml/apr_xml.c b/contrib/apr-util/xml/apr_xml.c index b3ec875781e2..ec3bea749761 100644 --- a/contrib/apr-util/xml/apr_xml.c +++ b/contrib/apr-util/xml/apr_xml.c @@ -86,7 +86,7 @@ static int find_prefix(apr_xml_parser *parser, const char *prefix) ** prefix. */ for (; elem; elem = elem->parent) { - apr_xml_ns_scope *ns_scope = elem->ns_scope; + apr_xml_ns_scope *ns_scope; for (ns_scope = elem->ns_scope; ns_scope; ns_scope = ns_scope->next) { if (strcmp(prefix, ns_scope->prefix) == 0) { @@ -120,6 +120,26 @@ static int find_prefix(apr_xml_parser *parser, const char *prefix) return APR_XML_NS_ERROR_UNKNOWN_PREFIX; } +/* return original prefix given ns index */ +static const char * find_prefix_name(const apr_xml_elem *elem, int ns, int parent) +{ + /* + ** Walk up the tree, looking for a namespace scope that defines this + ** prefix. + */ + for (; elem; elem = parent ? elem->parent : NULL) { + apr_xml_ns_scope *ns_scope = elem->ns_scope; + + for (; ns_scope; ns_scope = ns_scope->next) { + if (ns_scope->ns == ns) + return ns_scope->prefix; + } + } + /* not found */ + return ""; +} + + static void start_handler(void *userdata, const char *name, const char **attrs) { apr_xml_parser *parser = userdata; @@ -646,7 +666,8 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style, { apr_size_t size; - if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) { + if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG || + style == APR_XML_X2T_PARSED) { const apr_xml_attr *attr; size = 0; @@ -670,11 +691,29 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style, size += 11 + strlen(elem->lang) + 1; } } + else if (style == APR_XML_X2T_PARSED) { + apr_xml_ns_scope *ns_scope = elem->ns_scope; + + /* compute size of: ' xmlns:%s="%s"' */ + for (; ns_scope; ns_scope = ns_scope->next) { + size += 10 + strlen(find_prefix_name(elem, ns_scope->ns, 0)) + + strlen(APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns)); + } + + if (elem->lang != NULL) { + /* compute size of: ' xml:lang="%s"' */ + size += 11 + strlen(elem->lang) + 1; + } + } if (elem->ns == APR_XML_NS_NONE) { /* compute size of: <%s> */ size += 1 + strlen(elem->name) + 1; } + else if (style == APR_XML_X2T_PARSED) { + /* compute size of: <%s:%s> */ + size += 3 + strlen(find_prefix_name(elem, elem->ns, 1)) + strlen(elem->name); + } else { int ns = ns_map ? ns_map[elem->ns] : elem->ns; @@ -700,6 +739,10 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style, /* compute size of: ' %s="%s"' */ size += 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1; } + else if (style == APR_XML_X2T_PARSED) { + /* compute size of: ' %s:%s="%s"' */ + size += 5 + strlen(find_prefix_name(elem, attr->ns, 1)) + strlen(attr->name) + strlen(attr->value); + } else { /* compute size of: ' ns%d:%s="%s"' */ int ns = ns_map ? ns_map[attr->ns] : attr->ns; @@ -733,7 +776,7 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style, for (elem = elem->first_child; elem; elem = elem->next) { /* the size of the child element plus the CDATA that follows it */ - size += (elem_size(elem, APR_XML_X2T_FULL, NULL, ns_map) + + size += (elem_size(elem, style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL, NULL, ns_map) + text_size(elem->following_cdata.first)); } @@ -757,13 +800,15 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style, apr_size_t len; int ns; - if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) { + if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG || + style == APR_XML_X2T_PARSED) { int empty = APR_XML_ELEM_IS_EMPTY(elem); const apr_xml_attr *attr; - if (elem->ns == APR_XML_NS_NONE) { + if (elem->ns == APR_XML_NS_NONE) len = sprintf(s, "<%s", elem->name); - } + else if (style == APR_XML_X2T_PARSED) + len = sprintf(s, "<%s:%s", find_prefix_name(elem, elem->ns, 1), elem->name); else { ns = ns_map ? ns_map[elem->ns] : elem->ns; len = sprintf(s, "name); @@ -773,10 +818,13 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style, for (attr = elem->attr; attr; attr = attr->next) { if (attr->ns == APR_XML_NS_NONE) len = sprintf(s, " %s=\"%s\"", attr->name, attr->value); - else { - ns = ns_map ? ns_map[attr->ns] : attr->ns; - len = sprintf(s, " ns%d:%s=\"%s\"", ns, attr->name, attr->value); - } + else if (style == APR_XML_X2T_PARSED) + len = sprintf(s, " %s:%s=\"%s\"", + find_prefix_name(elem, attr->ns, 1), attr->name, attr->value); + else { + ns = ns_map ? ns_map[attr->ns] : attr->ns; + len = sprintf(s, " ns%d:%s=\"%s\"", ns, attr->name, attr->value); + } s += len; } @@ -799,6 +847,18 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style, s += len; } } + else if (style == APR_XML_X2T_PARSED) { + apr_xml_ns_scope *ns_scope = elem->ns_scope; + + for (; ns_scope; ns_scope = ns_scope->next) { + const char *prefix = find_prefix_name(elem, ns_scope->ns, 0); + + len = sprintf(s, " xmlns%s%s=\"%s\"", + *prefix ? ":" : "", *prefix ? prefix : "", + APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns)); + s += len; + } + } /* no more to do. close it up and go. */ if (empty) { @@ -823,14 +883,17 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style, s = write_text(s, elem->first_cdata.first); for (child = elem->first_child; child; child = child->next) { - s = write_elem(s, child, APR_XML_X2T_FULL, NULL, ns_map); + s = write_elem(s, child, + style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL, + NULL, ns_map); s = write_text(s, child->following_cdata.first); } - if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) { - if (elem->ns == APR_XML_NS_NONE) { + if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG || style == APR_XML_X2T_PARSED) { + if (elem->ns == APR_XML_NS_NONE) len = sprintf(s, "", elem->name); - } + else if (style == APR_XML_X2T_PARSED) + len = sprintf(s, "", find_prefix_name(elem, elem->ns, 1), elem->name); else { ns = ns_map ? ns_map[elem->ns] : elem->ns; len = sprintf(s, "", ns, elem->name); diff --git a/usr.bin/svn/lib/libapr_util/apu.h b/usr.bin/svn/lib/libapr_util/apu.h index 575d633162d7..875e28c05e74 100644 --- a/usr.bin/svn/lib/libapr_util/apu.h +++ b/usr.bin/svn/lib/libapr_util/apu.h @@ -114,12 +114,12 @@ #define APU_HAVE_SQLITE3 0 #define APU_HAVE_SQLITE2 0 #define APU_HAVE_ORACLE 0 -#define APU_HAVE_FREETDS 0 #define APU_HAVE_ODBC 0 #define APU_HAVE_CRYPTO 1 #define APU_HAVE_OPENSSL 1 #define APU_HAVE_NSS 0 +#define APU_HAVE_COMMONCRYPTO 0 #define APU_HAVE_APR_ICONV 0 #ifndef APU_HAVE_ICONV diff --git a/usr.bin/svn/lib/libapr_util/apu_config.h b/usr.bin/svn/lib/libapr_util/apu_config.h index ac247d06b132..1e709f71da7e 100644 --- a/usr.bin/svn/lib/libapr_util/apu_config.h +++ b/usr.bin/svn/lib/libapr_util/apu_config.h @@ -27,6 +27,10 @@ /* Define if CODESET is defined in langinfo.h */ #define HAVE_CODESET 1 +/* Define to 1 if you have the header + file. */ +/* #undef HAVE_COMMONCRYPTO_COMMONKEYDERIVATION_H */ + /* Define to 1 if you have the `crypt_r' function. */ /* #undef HAVE_CRYPT_R */ @@ -37,9 +41,6 @@ /* Define if expat.h is available */ #define HAVE_EXPAT_H 1 -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FREETDS_SYBDB_H */ - /* Define to 1 if you have the header file. */ /* #undef HAVE_ICONV_H */ @@ -64,6 +65,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 +/* Define if memset_s function is supported */ +#define HAVE_MEMSET_S 1 + /* Define to 1 if you have the header file. */ /* #undef HAVE_MYSQL_H */ @@ -133,9 +137,6 @@ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYBDB_H */ - /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 @@ -145,6 +146,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 +/* Define if compiler handles weak symbols */ +#define HAVE_WEAK_SYMBOLS 1 + /* Define if xmlparse/xmlparse.h is available */ /* #undef HAVE_XMLPARSE_XMLPARSE_H */