Vendor import apr-util-1.6.1
This commit is contained in:
parent
998df08c00
commit
30aa745c7c
157
CHANGES
157
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 <weiqiang_li hotmail.com>]
|
||||
*) 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 <philip.martin wandisco.com>]
|
||||
*) 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
|
||||
<fredrik fornwall.net>, 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 <brnrd freebsd.org>, 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 <polynomial-c gentoo.org>]
|
||||
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 <carlo.bramix libero.it>]
|
||||
*) Update MySQL build to stop using libmysqlclient_r.
|
||||
[Petr Sumbera <petr.sumbera oracle.com>]
|
||||
|
||||
*) 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 <hanno hboeck.de>]
|
||||
|
||||
*) Add support to apr_memcache for unix domain sockets. PR 54573 [Remi
|
||||
Gacogne <rgacogne+asf aquaray.com>]
|
||||
*) 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
|
||||
<jari.urpalainen nokia.com>]
|
||||
|
||||
*) Fix memory leak in hook sorting function. PR 51256.
|
||||
[<horowity checkpoint com>]
|
||||
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
|
||||
<stefanfuhrmann alice-dsl de>]
|
||||
|
||||
*) 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 <harvey.eneman oracle.com>]
|
||||
|
||||
*) 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 <christophe jaillet wanadoo fr>]
|
||||
|
||||
*) 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 <columbusmonkey me.com>]
|
||||
|
||||
Changes with APR-util 1.5.1
|
||||
|
||||
*) testmemcache: Fix crash. PR 52705. [Peter Poeml <peter poeml de>]
|
||||
|
||||
*) MinGW: Support shared builds of apr-util when apr is shared.
|
||||
PR 46175. [Carlo Bramini <carlo.bramix libero.it>, 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 <solar openwall com>. 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. [<arthur echo gmail com>]
|
||||
|
||||
*) APR dbd FreeTDS support: Fix spurious API errors caused by uninitialized
|
||||
fields. [TROY.LIU 劉春偉 <TROY.LIU deltaww.com.cn>]
|
||||
|
||||
*) 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 <arekm pld-linux.org>]
|
||||
|
||||
*) 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:
|
||||
|
||||
|
355
CMakeLists.txt
Normal file
355
CMakeLists.txt
Normal file
@ -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()
|
16
LICENSE
16
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 <solar at openwall.com> 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:
|
||||
|
||||
*
|
||||
|
@ -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 \
|
||||
|
33
Makefile.win
33
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 \
|
||||
|
2
NOTICE
2
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/).
|
||||
|
@ -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
|
||||
|
4
README
4
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.
|
||||
|
||||
|
11
README.FREETDS
Normal file
11
README.FREETDS
Normal file
@ -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.
|
139
README.cmake
Normal file
139
README.cmake
Normal file
@ -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.
|
@ -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 <minfrin@sharp.fm> 1.0.0-1
|
||||
|
36
aprutil.dsw
36
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>
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
14
build.conf
14
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
|
||||
|
18
buildconf
18
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
|
||||
|
54
configure.in
54
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 <string.h>
|
||||
#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 <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#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)
|
||||
|
@ -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
|
||||
|
906
crypto/apr_crypto_commoncrypto.c
Normal file
906
crypto/apr_crypto_commoncrypto.c
Normal file
@ -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 <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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 <CommonCrypto/CommonCrypto.h>
|
||||
|
||||
#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
|
@ -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
|
||||
|
@ -31,15 +31,27 @@
|
||||
#if APU_HAVE_CRYPTO
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#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
|
||||
|
196
crypto/apr_siphash.c
Normal file
196
crypto/apr_siphash.c
Normal file
@ -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);
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
197
include/apr_ldap.hwc
Normal file
197
include/apr_ldap.hwc
Normal file
@ -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 <winldap.h>
|
||||
|
||||
|
||||
/*
|
||||
* 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 */
|
459
include/apr_redis.h
Normal file
459
include/apr_redis.h
Normal file
@ -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 */
|
148
include/apr_siphash.h
Normal file
148
include/apr_siphash.h
Normal file
@ -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
|
||||
<jeanphilippe.aumasson@gmail.com>
|
||||
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
|
||||
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
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#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 */
|
@ -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
|
||||
* </PRE>
|
||||
* @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
|
||||
|
@ -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@
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
145
include/apu.hwc
Normal file
145
include/apu.hwc
Normal file
@ -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 */
|
||||
/** @} */
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -24,6 +24,10 @@
|
||||
/* Define if CODESET is defined in langinfo.h */
|
||||
#undef HAVE_CODESET
|
||||
|
||||
/* Define to 1 if you have the <CommonCrypto/CommonKeyDerivation.h> 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 <freetds/sybdb.h> 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 <iconv.h> header file. */
|
||||
#undef HAVE_ICONV_H
|
||||
@ -61,6 +65,9 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define if memset_s function is supported */
|
||||
#undef HAVE_MEMSET_S
|
||||
|
||||
/* Define to 1 if you have the <mysql.h> header file. */
|
||||
#undef HAVE_MYSQL_H
|
||||
|
||||
@ -130,9 +137,6 @@
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sybdb.h> header file. */
|
||||
#undef HAVE_SYBDB_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
@ -142,6 +146,9 @@
|
||||
/* Define to 1 if you have the <unistd.h> 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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
1548
redis/apr_redis.c
Normal file
1548
redis/apr_redis.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -35,12 +35,14 @@ const struct testlist {
|
||||
{testdbd},
|
||||
{testdate},
|
||||
{testmemcache},
|
||||
{testredis},
|
||||
{testxml},
|
||||
{testxlate},
|
||||
{testrmm},
|
||||
{testdbm},
|
||||
{testqueue},
|
||||
{testreslist}
|
||||
{testreslist},
|
||||
{testsiphash}
|
||||
};
|
||||
|
||||
#endif /* APR_TEST_INCLUDES */
|
||||
|
@ -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
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
552
test/testredis.c
Normal file
552
test/testredis.c
Normal file
@ -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 <stdio.h>
|
||||
#if APR_HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* 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;
|
||||
}
|
148
test/testsiphash.c
Normal file
148
test/testsiphash.c
Normal file
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -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 */
|
||||
|
@ -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, "<ns%d:%s", ns, elem->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, "</%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, "</ns%d:%s>", ns, elem->name);
|
||||
|
Loading…
Reference in New Issue
Block a user