diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1227315ef..9a62df590 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -71,7 +71,7 @@ jobs: # uses a compiled language - name: Install tools / libraries - run: sudo apt-get update && sudo apt-get -y install autoconf automake libtool libtool-bin make tar libssl-dev cmake perl ninja-build + run: sudo apt-get update && sudo apt-get -y install autoconf automake libtool libtool-bin make tar libapr1-dev libssl-dev cmake perl ninja-build - name: Build project run: ./mvnw clean package -pl openssl-dynamic -DskipTests=true diff --git a/Brewfile b/Brewfile index ec8fb678c..70472a290 100644 --- a/Brewfile +++ b/Brewfile @@ -6,3 +6,4 @@ brew 'perl' brew 'ninja' brew 'golang' brew 'cmake' +brew 'apr' diff --git a/boringssl-static/pom.xml b/boringssl-static/pom.xml index 699595f30..2acd2e9be 100644 --- a/boringssl-static/pom.xml +++ b/boringssl-static/pom.xml @@ -27,7 +27,7 @@ Netty/TomcatNative [BoringSSL - Static] A Mavenized fork of Tomcat Native which incorporates various patches. This artifact is statically linked - to BoringSSL. + to BoringSSL and Apache APR. @@ -130,6 +130,7 @@ maven-bundle-plugin + ${aprVersion} ${boringsslCommitSha} ${boringsslBranch} @@ -317,7 +318,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -340,6 +341,7 @@ --with-ssl=no + --with-apr=${aprHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib ${macOsxDeploymentTarget} @@ -417,6 +419,10 @@ release 7.6 + + aprArmHome + The folder of APR for aarch64 must be specified by hand. Please try -DaprArmHome= + true @@ -469,6 +475,7 @@ maven-bundle-plugin + ${aprVersion} ${boringsslCommitSha} ${boringsslBranch} @@ -645,7 +652,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -668,6 +675,7 @@ --with-ssl=no + --with-apr=${aprArmHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib CFLAGS=-O3 -Werror -fno-omit-frame-pointer -fvisibility=hidden -Wunused -Wno-unused-value @@ -675,7 +683,6 @@ LDFLAGS=-L${boringsslHome}/ssl -L${boringsslHome}/crypto -lssl -lcrypto --host=aarch64-linux-gnu CC=aarch64-none-linux-gnu-gcc - CXX=aarch64-none-linux-gnu-g++ @@ -928,6 +935,7 @@ maven-bundle-plugin + ${aprVersion} ${boringsslCommitSha} ${boringsslBranch} @@ -1063,7 +1071,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -1085,6 +1093,7 @@ --with-ssl=no + --with-apr=${aprHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib --host=aarch64-apple-darwin @@ -1173,6 +1182,7 @@ maven-bundle-plugin + ${aprVersion} ${boringsslCommitSha} ${boringsslBranch} @@ -1308,7 +1318,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -1330,6 +1340,7 @@ --with-ssl=no + --with-apr=${aprHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib --host=x86_64-apple-darwin diff --git a/docker/Dockerfile.arch b/docker/Dockerfile.arch index c1d1dfb9e..70c534461 100644 --- a/docker/Dockerfile.arch +++ b/docker/Dockerfile.arch @@ -6,6 +6,7 @@ ENV JAVA_VERSION $java_version # install dependencies # use openSSL 1.0.x for now, for highest compatibility RUN pacman -Sy --noconfirm --needed \ + apr \ autoconf \ automake \ bzip2 \ diff --git a/docker/Dockerfile.centos6 b/docker/Dockerfile.centos6 index ea2cdccec..281389b80 100644 --- a/docker/Dockerfile.centos6 +++ b/docker/Dockerfile.centos6 @@ -12,12 +12,14 @@ RUN sed -i -e 's/^mirrorlist/#mirrorlist/g' -e 's/^#baseurl=http:\/\/mirror.cent # install dependencies RUN yum install -y \ + apr-devel \ autoconf \ automake \ bzip2 \ git \ glibc-devel \ gnupg \ + libapr1-dev \ libtool \ lsb-core \ make \ diff --git a/docker/Dockerfile.cross_compile_aarch64 b/docker/Dockerfile.cross_compile_aarch64 index 5a50da99e..be4ba2a45 100644 --- a/docker/Dockerfile.cross_compile_aarch64 +++ b/docker/Dockerfile.cross_compile_aarch64 @@ -2,10 +2,12 @@ FROM centos:7.6.1810 ARG gcc_version=10.2-2020.11 ARG openssl_version=1_1_1d +ARG apr_version=1.7.4 ENV SOURCE_DIR /root/source ENV GCC_VERSION $gcc_version ENV OPENSSL_VERSION $openssl_version ENV MAVEN_VERSION 3.9.1 +ENV APR_VERSION $apr_version RUN mkdir $SOURCE_DIR WORKDIR $SOURCE_DIR @@ -32,6 +34,32 @@ ENV PATH="/gcc-arm-$GCC_VERSION-x86_64-aarch64-none-linux-gnu/bin:${PATH}" # Install CMake RUN yum install -y cmake3 && ln -s /usr/bin/cmake3 /usr/bin/cmake +# Cross compile Apache Apr for aarch64 - static +RUN set -x && \ + wget https://downloads.apache.org//apr/apr-$APR_VERSION.tar.gz && \ + tar xvf apr-$APR_VERSION.tar.gz && \ + pushd apr-$APR_VERSION && \ + CC=aarch64-none-linux-gnu-gcc CFLAGS='-O3 -fno-omit-frame-pointer -fPIC' ./configure --disable-shared --prefix=/opt/apr-$APR_VERSION-static --host=aarch64-none-linux-gnu ac_cv_file__dev_zero=yes ac_cv_func_setpgrp_void=yes apr_cv_tcp_nodelay_with_cork=yes ac_cv_sizeof_struct_iovec=8 && \ + make || true && \ + pushd tools && \ + gcc -Wall -O2 -DCROSS_COMPILE gen_test_char.c -s -o gen_test_char && \ + popd && \ + make && make install && \ + popd + +# Cross compile Apache Apr for aarch64 - share +RUN set -x && \ + wget https://downloads.apache.org//apr/apr-$APR_VERSION.tar.gz && \ + tar xvf apr-$APR_VERSION.tar.gz && \ + pushd apr-$APR_VERSION && \ + CC=aarch64-none-linux-gnu-gcc CFLAGS='-O3 -fno-omit-frame-pointer -fPIC' ./configure --prefix=/opt/apr-$APR_VERSION-share --host=aarch64-none-linux-gnu ac_cv_file__dev_zero=yes ac_cv_func_setpgrp_void=yes apr_cv_tcp_nodelay_with_cork=yes ac_cv_sizeof_struct_iovec=8 && \ + make || true && \ + pushd tools && \ + gcc -Wall -O2 -DCROSS_COMPILE gen_test_char.c -s -o gen_test_char && \ + popd && \ + make && make install && \ + popd + # Cross compile OpenSSL for aarch64 - share RUN set -x && \ wget https://github.com/openssl/openssl/archive/OpenSSL_$OPENSSL_VERSION.tar.gz && \ diff --git a/docker/Dockerfile.debian b/docker/Dockerfile.debian index 8a190b0c1..fd2e24119 100644 --- a/docker/Dockerfile.debian +++ b/docker/Dockerfile.debian @@ -24,6 +24,7 @@ RUN echo "deb http://archive.debian.org/debian/ wheezy contrib main non-free" > git \ gnupg \ g++ \ + libapr1-dev \ libssl1.0.0=1.0.1e-2+deb7u20 \ libssl-dev \ libtool \ diff --git a/docker/Dockerfile.opensuse b/docker/Dockerfile.opensuse index e1843ae8d..9df72437e 100644 --- a/docker/Dockerfile.opensuse +++ b/docker/Dockerfile.opensuse @@ -9,6 +9,7 @@ ENV JAVA_VERSION $java_version # install dependencies # use openSSL 1.0.x for now, for highest compatibility RUN zypper install --force-resolution --no-recommends --no-confirm \ + apr-devel \ autoconf \ automake \ bzip2 \ diff --git a/docker/docker-compose.centos-7.yaml b/docker/docker-compose.centos-7.yaml index 13024d51f..aeb6fc0fd 100644 --- a/docker/docker-compose.centos-7.yaml +++ b/docker/docker-compose.centos-7.yaml @@ -9,6 +9,7 @@ services: dockerfile: docker/Dockerfile.cross_compile_aarch64 args: gcc_version: "10.2-2020.11" + apr_version: "1.7.4" openssl_version: "1_1_1k" cross-compile-aarch64-common: &cross-compile-aarch64-common @@ -39,7 +40,7 @@ services: cross-compile-aarch64-build: <<: *cross-compile-aarch64-common - command: /bin/bash -cl "./mvnw clean package -Plinux-aarch64 -am -pl openssl-dynamic -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share -DskipTests && ./mvnw clean package -Plinux-aarch64 -am -pl boringssl-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl -DskipTests" + command: /bin/bash -cl "./mvnw clean package -Plinux-aarch64 -am -pl openssl-dynamic -DaprArmHome=/opt/apr-$$APR_VERSION-share -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share -DskipTests && ./mvnw clean package -Plinux-aarch64 -am -pl boringssl-static -DaprArmHome=/opt/apr-$$APR_VERSION-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl -DskipTests" cross-compile-aarch64-deploy: <<: *cross-compile-aarch64-common @@ -49,7 +50,7 @@ services: - ~/.m2/repository:/root/.m2/repository - ~/.m2/settings.xml:/root/.m2/settings.xml - ..:/code - command: /bin/bash -cl "./mvnw clean deploy -Plinux-aarch64 -am -pl openssl-dynamic -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share -DskipTests && ./mvnw clean deploy -Plinux-aarch64 -am -pl boringssl-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl -DskipTests" + command: /bin/bash -cl "./mvnw clean deploy -Plinux-aarch64 -am -pl openssl-dynamic -DaprArmHome=/opt/apr-$$APR_VERSION-share -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share -DskipTests && ./mvnw clean deploy -Plinux-aarch64 -am -pl boringssl-static -DaprArmHome=/opt/apr-$$APR_VERSION-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl -DskipTests" cross-compile-aarch64-stage-snapshot: <<: *cross-compile-aarch64-common @@ -59,7 +60,7 @@ services: - ~/.m2/repository:/root/.m2/repository - ~/local-staging:/root/local-staging - ..:/code - command: /bin/bash -cl "./mvnw -Plinux-aarch64 -am -pl openssl-dynamic -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true && ./mvnw -Plinux-aarch64 -am -pl boringssl-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true" + command: /bin/bash -cl "./mvnw -Plinux-aarch64 -am -pl openssl-dynamic -DaprArmHome=/opt/apr-$$APR_VERSION-share -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true && ./mvnw -Plinux-aarch64 -am -pl boringssl-static -DaprArmHome=/opt/apr-$$APR_VERSION-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true" cross-compile-aarch64-stage-release: <<: *cross-compile-aarch64-common @@ -69,4 +70,5 @@ services: - ~/.m2/settings.xml:/root/.m2/settings.xml - ~/local-staging:/root/local-staging - ..:/code - command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -Plinux-aarch64 -am -pl openssl-dynamic -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME} && ./mvnw -Plinux-aarch64 -am -pl boringssl-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}" + command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -Plinux-aarch64 -am -pl openssl-dynamic -DaprArmHome=/opt/apr-$$APR_VERSION-share -DopensslArmHome=/opt/openssl-$$OPENSSL_VERSION-share clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME} && ./mvnw -Plinux-aarch64 -am -pl boringssl-static -DaprArmHome=/opt/apr-$$APR_VERSION-static -DboringsslSourceDir=/root/workspace/boringssl-source -DboringsslHome=/root/workspace/boringssl clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}" + diff --git a/libressl-static/pom.xml b/libressl-static/pom.xml index 45dea0f55..3431b9aeb 100644 --- a/libressl-static/pom.xml +++ b/libressl-static/pom.xml @@ -27,7 +27,7 @@ Netty/TomcatNative [LibreSSL - Static] A Mavenized fork of Tomcat Native which incorporates various patches. This artifact is statically linked - to LibreSSL. + to LibreSSL and Apache APR. @@ -61,12 +61,14 @@ + org.apache.felix maven-bundle-plugin + ${aprVersion} ${libresslVersion} @@ -159,7 +161,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -181,6 +183,7 @@ msbuild --with-ssl=no + --with-apr=${aprHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib ${macOsxDeploymentTarget} diff --git a/openssl-classes/pom.xml b/openssl-classes/pom.xml index b3c157a3b..153d41e56 100644 --- a/openssl-classes/pom.xml +++ b/openssl-classes/pom.xml @@ -27,7 +27,7 @@ Netty/TomcatNative [OpenSSL - Classes] A Mavenized fork of Tomcat Native which incorporates various patches. This artifact is dynamically linked - to OpenSSL. + to OpenSSL and Apache APR. diff --git a/openssl-classes/src/main/java/io/netty/internal/tcnative/Library.java b/openssl-classes/src/main/java/io/netty/internal/tcnative/Library.java index 8dafb988a..074162a80 100644 --- a/openssl-classes/src/main/java/io/netty/internal/tcnative/Library.java +++ b/openssl-classes/src/main/java/io/netty/internal/tcnative/Library.java @@ -154,6 +154,17 @@ private static String calculatePackagePrefix() { return maybeShaded.substring(0, maybeShaded.length() - expected.length()); } + /* create global TCN's APR pool + * This has to be the first call to TCN library. + */ + private static native boolean initialize0(); + + private static native boolean aprHasThreads(); + + private static native int aprMajorVersion(); + + /* APR_VERSION_STRING */ + private static native String aprVersionString(); /** * Calls {@link #initialize(String, String)} with {@code "provided"} and {@code null}. @@ -176,8 +187,16 @@ public static boolean initialize() throws Exception { public static boolean initialize(String libraryName, String engine) throws Exception { if (_instance == null) { _instance = libraryName == null ? new Library() : new Library(libraryName); + + if (aprMajorVersion() < 1) { + throw new UnsatisfiedLinkError("Unsupported APR Version (" + + aprVersionString() + ")"); + } + + if (!aprHasThreads()) { + throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS"); + } } - SSL.initialize(engine); - return true; + return initialize0() && SSL.initialize(engine) == 0; } } diff --git a/openssl-classes/src/main/java/io/netty/internal/tcnative/SSL.java b/openssl-classes/src/main/java/io/netty/internal/tcnative/SSL.java index dc28fe854..16cc38857 100644 --- a/openssl-classes/src/main/java/io/netty/internal/tcnative/SSL.java +++ b/openssl-classes/src/main/java/io/netty/internal/tcnative/SSL.java @@ -138,8 +138,9 @@ private SSL() { } * * @param engine Support for external a Crypto Device ("engine"), * usually a hardware accelerator card for crypto operations. + * @return APR status code */ - static native void initialize(String engine); + static native int initialize(String engine); /** * Initialize new in-memory BIO that is located in the secure heap. diff --git a/openssl-classes/src/main/java/io/netty/internal/tcnative/SSLContext.java b/openssl-classes/src/main/java/io/netty/internal/tcnative/SSLContext.java index fc551b179..e83adbcfc 100644 --- a/openssl-classes/src/main/java/io/netty/internal/tcnative/SSLContext.java +++ b/openssl-classes/src/main/java/io/netty/internal/tcnative/SSLContext.java @@ -68,7 +68,7 @@ public static native long make(int protocol, int mode) /** * Free the resources used by the Context * @param ctx Server or Client context to free. - * @return {@code 0} on success. + * @return APR Status code. */ public static native int free(long ctx); diff --git a/openssl-dynamic/pom.xml b/openssl-dynamic/pom.xml index d6b57d091..e33a02cf9 100644 --- a/openssl-dynamic/pom.xml +++ b/openssl-dynamic/pom.xml @@ -27,7 +27,7 @@ Netty/TomcatNative [OpenSSL - Dynamic] A Mavenized fork of Tomcat Native which incorporates various patches. This artifact is dynamically linked - to OpenSSL. + to OpenSSL and Apache APR. @@ -189,6 +189,12 @@ + + APR_INCLUDE_DIR + + + APR_LIB_DIR + OPENSSL_INCLUDE_DIR @@ -229,6 +235,7 @@ ${forceConfigure} ${macOsxDeploymentTarget} + --with-apr=/usr/local/opt/apr/ --with-ssl=/usr/local/opt/openssl@1.1/ @@ -267,6 +274,7 @@ ${forceConfigure} ${macOsxDeploymentTarget} + --with-apr=/opt/homebrew/opt/apr/ --with-ssl=/opt/homebrew/opt/openssl@1.1/ @@ -348,6 +356,10 @@ release 7.6 + + aprArmHome + The folder of APR for aarch64 must be specified by hand. Please try -DaprArmHome= + opensslArmHome The folder of OpenSSL for aarch64 must be specified by hand. Please try -DopensslArmHome= @@ -374,10 +386,10 @@ ${forceConfigure} --libdir=${project.build.directory}/native-build/target/lib + --with-apr=${aprArmHome} --with-ssl=${opensslArmHome} --host=aarch64-linux-gnu CC=aarch64-none-linux-gnu-gcc - CXX=aarch64-none-linux-gnu-g++ diff --git a/openssl-dynamic/src/main/c/cert_compress.c b/openssl-dynamic/src/main/c/cert_compress.c index 23cf229ad..e14fe976a 100644 --- a/openssl-dynamic/src/main/c/cert_compress.c +++ b/openssl-dynamic/src/main/c/cert_compress.c @@ -18,7 +18,6 @@ #include "ssl_private.h" #ifdef OPENSSL_IS_BORINGSSL #include "cert_compress.h" -#include static int compress(jobject compression_algorithm, jmethodID compress_method, SSL* ssl, CBB* out, const uint8_t* in, size_t in_len) { diff --git a/openssl-dynamic/src/main/c/error.c b/openssl-dynamic/src/main/c/error.c index 50d183fef..01f3c5360 100644 --- a/openssl-dynamic/src/main/c/error.c +++ b/openssl-dynamic/src/main/c/error.c @@ -30,6 +30,7 @@ */ #include "tcn.h" +#include "apr_strings.h" static jclass exceptionClass; static jclass nullPointerExceptionClass; @@ -61,11 +62,19 @@ void tcn_Throw(JNIEnv *env, const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(msg, TCN_BUFFER_SZ, fmt, ap); + apr_vsnprintf(msg, TCN_BUFFER_SZ, fmt, ap); tcn_ThrowException(env, msg); va_end(ap); } +void tcn_ThrowAPRException(JNIEnv *e, apr_status_t err) +{ + char serr[512] = {0}; + + apr_strerror(err, serr, 512); + tcn_ThrowException(e, serr); +} + void tcn_throwOutOfMemoryError(JNIEnv* env, const char *msg) { (*env)->ThrowNew(env, oomeClass, msg); diff --git a/openssl-dynamic/src/main/c/jnilib.c b/openssl-dynamic/src/main/c/jnilib.c index ac5ba486b..86d356239 100644 --- a/openssl-dynamic/src/main/c/jnilib.c +++ b/openssl-dynamic/src/main/c/jnilib.c @@ -40,6 +40,9 @@ #endif #include "tcn.h" +#include "apr_version.h" +#include "apr_atomic.h" +#include "apr_strings.h" #include "bb.h" #include "native_constants.h" #include "ssl.h" @@ -47,6 +50,7 @@ #include "sslsession.h" #include "error.h" +apr_pool_t *tcn_global_pool = NULL; static JavaVM *tcn_global_vm = NULL; static jclass jString_class; @@ -84,6 +88,40 @@ jstring tcn_new_string(JNIEnv *env, const char *str) return (*env)->NewStringUTF(env, str); } +TCN_IMPLEMENT_CALL(jboolean, Library, initialize0)(TCN_STDARGS) +{ + + if (!tcn_global_pool) { + apr_initialize(); + if (apr_pool_create(&tcn_global_pool, NULL) != APR_SUCCESS) { + return JNI_FALSE; + } + apr_atomic_init(tcn_global_pool); + } + return JNI_TRUE; +} + +TCN_IMPLEMENT_CALL(jint, Library, aprMajorVersion)(TCN_STDARGS) +{ + apr_version_t apv; + + apr_version(&apv); + return apv.major; +} + +TCN_IMPLEMENT_CALL(jstring, Library, aprVersionString)(TCN_STDARGS) +{ + return AJP_TO_JSTRING(apr_version_string()); +} + +TCN_IMPLEMENT_CALL(jboolean, Library, aprHasThreads)(TCN_STDARGS) +{ +#if APR_HAS_THREADS + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +} jclass tcn_get_string_class() { @@ -100,6 +138,17 @@ jint tcn_get_java_env(JNIEnv **env) return (*tcn_global_vm)->GetEnv(tcn_global_vm, (void **)env, NETTY_JNI_UTIL_JNI_VERSION); } +// JNI Method Registration Table Begin +static const JNINativeMethod method_table[] = { + { TCN_METHOD_TABLE_ENTRY(initialize0, ()Z, Library) }, + { TCN_METHOD_TABLE_ENTRY(aprMajorVersion, ()I, Library) }, + { TCN_METHOD_TABLE_ENTRY(aprVersionString, ()Ljava/lang/String;, Library) }, + { TCN_METHOD_TABLE_ENTRY(aprHasThreads, ()Z, Library) }, +}; + +static const jint method_table_size = sizeof(method_table) / sizeof(method_table[0]); +// JNI Method Registration Table End + // IMPORTANT: If you add any NETTY_JNI_UTIL_LOAD_CLASS or NETTY_JNI_UTIL_FIND_CLASS calls you also need to update // Library to reflect that. static jint netty_internal_tcnative_Library_JNI_OnLoad(JNIEnv* env, char const* packagePrefix) { @@ -110,6 +159,10 @@ static jint netty_internal_tcnative_Library_JNI_OnLoad(JNIEnv* env, char const* int sslOnLoadCalled = 0; int contextOnLoadCalled = 0; + if (netty_jni_util_register_natives(env, packagePrefix, LIBRARY_CLASSNAME, method_table, method_table_size) != 0) { + goto error; + } + // Load all c modules that we depend upon if (netty_internal_tcnative_Error_JNI_OnLoad(env, packagePrefix) == JNI_ERR) { goto error; @@ -141,6 +194,21 @@ static jint netty_internal_tcnative_Library_JNI_OnLoad(JNIEnv* env, char const* } sessionOnLoadCalled = 1; + apr_version_t apv; + int apvn; + + /* Before doing anything else check if we have a valid + * APR version. + */ + apr_version(&apv); + apvn = apv.major * 1000 + apv.minor * 100 + apv.patch; + if (apvn < 1201) { + tcn_Throw(env, "Unsupported APR version (%s)", + apr_version_string()); + goto error; + } + + /* Initialize global java.lang.String class */ NETTY_JNI_UTIL_LOAD_CLASS(env, jString_class, "java/lang/String", error); @@ -153,7 +221,11 @@ static jint netty_internal_tcnative_Library_JNI_OnLoad(JNIEnv* env, char const* staticPackagePrefix = packagePrefix; return NETTY_JNI_UTIL_JNI_VERSION; error: - NETTY_JNI_UTIL_UNLOAD_CLASS(env, jString_class); + if (tcn_global_pool != NULL) { + NETTY_JNI_UTIL_UNLOAD_CLASS(env, jString_class); + apr_terminate(); + tcn_global_pool = NULL; + } NETTY_JNI_UTIL_UNLOAD_CLASS(env, byteArrayClass); @@ -182,7 +254,12 @@ static jint netty_internal_tcnative_Library_JNI_OnLoad(JNIEnv* env, char const* } static void netty_internal_tcnative_Library_JNI_OnUnload(JNIEnv* env) { - NETTY_JNI_UTIL_UNLOAD_CLASS(env, jString_class); + if (tcn_global_pool != NULL) { + NETTY_JNI_UTIL_UNLOAD_CLASS(env, jString_class); + apr_terminate(); + tcn_global_pool = NULL; + } + NETTY_JNI_UTIL_UNLOAD_CLASS(env, byteArrayClass); netty_internal_tcnative_Error_JNI_OnUnLoad(env, staticPackagePrefix); netty_internal_tcnative_Buffer_JNI_OnUnLoad(env, staticPackagePrefix); diff --git a/openssl-dynamic/src/main/c/ssl.c b/openssl-dynamic/src/main/c/ssl.c index dfbdc1d63..9745d9601 100644 --- a/openssl-dynamic/src/main/c/ssl.c +++ b/openssl-dynamic/src/main/c/ssl.c @@ -37,15 +37,18 @@ #endif // OPENSSL_NO_ENGINE #include "tcn.h" -#include "tcn_lock.h" -#include "tcn_thread.h" +#include "apr_file_io.h" +#include "apr_thread_mutex.h" +#include "apr_atomic.h" +#include "apr_strings.h" +#include "apr_portable.h" #include "ssl_private.h" #include "ssl.h" -#include #define SSL_CLASSNAME "io/netty/internal/tcnative/SSL" static int ssl_initialized = 0; +extern apr_pool_t *tcn_global_pool; void *SSL_temp_keys[SSL_TMP_KEY_MAX]; @@ -57,22 +60,16 @@ static UI_METHOD *ui_method = NULL; #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) +/* Global reference to the pool used by the dynamic mutexes */ +static apr_pool_t *dynlockpool = NULL; + /* Dynamic lock structure */ struct CRYPTO_dynlock_value { - char* file; + apr_pool_t *pool; + const char* file; int line; - tcn_lock_t mutex; + apr_thread_mutex_t *mutex; }; - -static void ssl_thread_cleanup() -{ - CRYPTO_set_locking_callback(NULL); - CRYPTO_THREADID_set_callback(NULL); - CRYPTO_set_dynlock_create_callback(NULL); - CRYPTO_set_dynlock_lock_callback(NULL); - CRYPTO_set_dynlock_destroy_callback(NULL); -} - #endif // OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) struct TCN_bio_bytebuffer { @@ -491,11 +488,12 @@ TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS) /* * the various processing hooks */ -void ssl_init_cleanup() +static apr_status_t ssl_init_cleanup(void *data) { if (!ssl_initialized) { - return; + return APR_SUCCESS; } + ssl_initialized = 0; SSL_TMP_KEYS_FREE(DH); @@ -555,9 +553,7 @@ void ssl_init_cleanup() * (when enabled) at this late stage in the game: * CRYPTO_mem_leaks_fp(stderr); */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) - ssl_thread_cleanup(); -#endif // OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) + return APR_SUCCESS; } #ifndef OPENSSL_NO_ENGINE @@ -582,7 +578,7 @@ static ENGINE *ssl_try_load_engine(const char *engine) #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) -static tcn_lock_t **ssl_lock_cs = NULL; +static apr_thread_mutex_t **ssl_lock_cs = NULL; static int ssl_lock_num_locks; static void ssl_thread_lock(int mode, int type, @@ -590,9 +586,9 @@ static void ssl_thread_lock(int mode, int type, { if (type < ssl_lock_num_locks) { if (mode & CRYPTO_LOCK) { - tcn_lock_acquire(ssl_lock_cs[type]); + apr_thread_mutex_lock(ssl_lock_cs[type]); } else { - tcn_lock_release(ssl_lock_cs[type]); + apr_thread_mutex_unlock(ssl_lock_cs[type]); } } } @@ -613,7 +609,7 @@ static unsigned long ssl_thread_id(void) #elif defined(_WIN32) return (unsigned long)GetCurrentThreadId(); #else - return (unsigned long)(tcn_current_thread_id()); + return (unsigned long)(apr_os_thread_current()); #endif } @@ -622,24 +618,61 @@ static void ssl_set_thread_id(CRYPTO_THREADID *id) CRYPTO_THREADID_set_numeric(id, ssl_thread_id()); } +static apr_status_t ssl_thread_cleanup(void *data) +{ + CRYPTO_set_locking_callback(NULL); + CRYPTO_THREADID_set_callback(NULL); + CRYPTO_set_dynlock_create_callback(NULL); + CRYPTO_set_dynlock_lock_callback(NULL); + CRYPTO_set_dynlock_destroy_callback(NULL); + + dynlockpool = NULL; + + /* Let the registered mutex cleanups do their own thing + */ + return APR_SUCCESS; +} + /* * Dynamic lock creation callback */ static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, int line) { - struct CRYPTO_dynlock_value *value = (struct CRYPTO_dynlock_value *)malloc(sizeof(struct CRYPTO_dynlock_value)); + struct CRYPTO_dynlock_value *value = NULL; + apr_pool_t *p = NULL; + apr_status_t rv; + /* + * We need a pool to allocate our mutex. Since we can't clear + * allocated memory from a pool, create a subpool that we can blow + * away in the destruction callback. + */ + rv = apr_pool_create(&p, dynlockpool); + if (rv != APR_SUCCESS) { + /* TODO log that fprintf(stderr, "Failed to create subpool for dynamic lock"); */ + return NULL; + } + + value = (struct CRYPTO_dynlock_value *)apr_palloc(p, + sizeof(struct CRYPTO_dynlock_value)); if (!value) { /* TODO log that fprintf(stderr, "Failed to allocate dynamic lock structure"); */ return NULL; } + value->pool = p; /* Keep our own copy of the place from which we were created, using our own pool. */ - value->file = strdup(file); + value->file = apr_pstrdup(p, file); value->line = line; - value->mutex = tcn_lock_create(); + rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT, + p); + if (rv != APR_SUCCESS) { + /* TODO log that fprintf(stderr, "Failed to create thread mutex for dynamic lock"); */ + apr_pool_destroy(p); + return NULL; + } return value; } @@ -650,9 +683,10 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) { if (mode & CRYPTO_LOCK) { - tcn_lock_acquire(l->mutex); - } else { - tcn_lock_release(l->mutex); + apr_thread_mutex_lock(l->mutex); + } + else { + apr_thread_mutex_unlock(l->mutex); } } @@ -662,51 +696,74 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) { - tcn_lock_destroy(l->mutex); - free(l->file); - free(l); + apr_status_t rv; + rv = apr_thread_mutex_destroy(l->mutex); + if (rv != APR_SUCCESS) { + /* TODO log that fprintf(stderr, "Failed to destroy mutex for dynamic lock %s:%d", l->file, l->line); */ + } + + /* Trust that whomever owned the CRYPTO_dynlock_value we were + * passed has no future use for it... + */ + apr_pool_destroy(l->pool); } -static void ssl_thread_setup() +static void ssl_thread_setup(apr_pool_t *p) { int i; ssl_lock_num_locks = CRYPTO_num_locks(); - ssl_lock_cs = OPENSSL_malloc(ssl_lock_num_locks * sizeof(*ssl_lock_cs)); + ssl_lock_cs = apr_palloc(p, ssl_lock_num_locks * sizeof(*ssl_lock_cs)); for (i = 0; i < ssl_lock_num_locks; i++) { - ssl_lock_cs[i] = tcn_lock_create(); + apr_thread_mutex_create(&(ssl_lock_cs[i]), + APR_THREAD_MUTEX_DEFAULT, p); } CRYPTO_THREADID_set_callback(ssl_set_thread_id); CRYPTO_set_locking_callback(ssl_thread_lock); + /* Set up dynamic locking scaffolding for OpenSSL to use at its + * convenience. + */ + dynlockpool = p; + CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function); CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function); + + apr_pool_cleanup_register(p, NULL, ssl_thread_cleanup, + apr_pool_cleanup_null); } #endif // OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) -TCN_IMPLEMENT_CALL(void, SSL, initialize)(TCN_STDARGS, jstring engine) +TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine) { int r = 0; + TCN_ALLOC_CSTRING(engine); + + if (!tcn_global_pool) { + TCN_FREE_CSTRING(engine); + tcn_ThrowAPRException(e, APR_EINVAL); + return (jint)APR_EINVAL; + } /* Check if already initialized */ if (ssl_initialized++) { - return; + TCN_FREE_CSTRING(engine); + return (jint)APR_SUCCESS; } #if OPENSSL_VERSION_NUMBER < 0x10100000L if (OpenSSL_version_num() < 0x0090700L) { - tcn_ThrowException(e, "openssl version too old"); + TCN_FREE_CSTRING(engine); + tcn_ThrowAPRException(e, APR_EINVAL); ssl_initialized = 0; - return; + return (jint)APR_EINVAL; } #endif - TCN_ALLOC_CSTRING(engine); - #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090200fL) /* We must register the library in full, to ensure our configuration * code can successfully test the SSL environment. @@ -724,9 +781,11 @@ TCN_IMPLEMENT_CALL(void, SSL, initialize)(TCN_STDARGS, jstring engine) #if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) /* Initialize thread support */ - ssl_thread_setup(); + ssl_thread_setup(tcn_global_pool); #endif // OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL) + apr_status_t err = APR_SUCCESS; + #ifndef OPENSSL_NO_ENGINE if (J2S(engine)) { // Let us load the builtin engines as we want to use a specific one. This will also allow us @@ -740,7 +799,7 @@ TCN_IMPLEMENT_CALL(void, SSL, initialize)(TCN_STDARGS, jstring engine) if ((tcn_ssl_engine = ENGINE_by_id(J2S(engine))) == NULL && (tcn_ssl_engine = ssl_try_load_engine(J2S(engine))) == NULL) { - goto error; + err = APR_ENOTIMPL; } else { #ifdef ENGINE_CTRL_CHIL_SET_FORKCHECK if (strcmp(J2S(engine), "chil") == 0) { @@ -748,24 +807,33 @@ TCN_IMPLEMENT_CALL(void, SSL, initialize)(TCN_STDARGS, jstring engine) } #endif if (!ENGINE_set_default(tcn_ssl_engine, ENGINE_METHOD_ALL)) { - goto error; + err = APR_ENOTIMPL; } } - // This code is based on libcurl: - // https://github.com/curl/curl/blob/curl-7_61_0/lib/vtls/openssl.c#L521 - ui_method = UI_create_method((char *)"netty-tcnative user interface"); - if (ui_method != NULL) { - if (UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())) != 0) { - goto error; - } - if (UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())) != 0) { - goto error; - } - if (UI_method_set_reader(ui_method, ssl_ui_reader) != 0) { - goto error; - } - if (UI_method_set_writer(ui_method, ssl_ui_writer) != 0) { + if (err == APR_SUCCESS) { + // This code is based on libcurl: + // https://github.com/curl/curl/blob/curl-7_61_0/lib/vtls/openssl.c#L521 + ui_method = UI_create_method((char *)"netty-tcnative user interface"); + if (ui_method != NULL) { + if (UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())) != 0) { + err = APR_EINVAL; + goto error; + } + if (UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())) != 0) { + err = APR_EINVAL; + goto error; + } + if (UI_method_set_reader(ui_method, ssl_ui_reader) != 0) { + err = APR_EINVAL; + goto error; + } + if (UI_method_set_writer(ui_method, ssl_ui_writer) != 0) { + err = APR_EINVAL; + goto error; + } + } else { + err = APR_EINVAL; goto error; } } else { @@ -786,16 +854,24 @@ TCN_IMPLEMENT_CALL(void, SSL, initialize)(TCN_STDARGS, jstring engine) if (r) { // TODO: Should we really do this as the user may want to inspect the error stack ? ERR_clear_error(); + err = APR_ENOTIMPL; goto error; } - + /* + * Let us cleanup the ssl library when the library is unloaded + */ + apr_pool_cleanup_register(tcn_global_pool, NULL, + ssl_init_cleanup, + apr_pool_cleanup_null); TCN_FREE_CSTRING(engine); - return; + + return (jint)APR_SUCCESS; error: TCN_FREE_CSTRING(engine); - ssl_init_cleanup(); - tcn_ThrowException(e, "Unable to init SSL"); + ssl_init_cleanup(NULL); + tcn_ThrowAPRException(e, err); + return (jint)err; } TCN_IMPLEMENT_CALL(jlong, SSL, newMemBIO)(TCN_STDARGS) @@ -2583,7 +2659,7 @@ static const JNINativeMethod method_table[] = { { TCN_METHOD_TABLE_ENTRY(bioLengthNonApplication, (J)I, SSL) }, { TCN_METHOD_TABLE_ENTRY(version, ()I, SSL) }, { TCN_METHOD_TABLE_ENTRY(versionString, ()Ljava/lang/String;, SSL) }, - { TCN_METHOD_TABLE_ENTRY(initialize, (Ljava/lang/String;)V, SSL) }, + { TCN_METHOD_TABLE_ENTRY(initialize, (Ljava/lang/String;)I, SSL) }, { TCN_METHOD_TABLE_ENTRY(newMemBIO, ()J, SSL) }, { TCN_METHOD_TABLE_ENTRY(getLastError, ()Ljava/lang/String;, SSL) }, { TCN_METHOD_TABLE_ENTRY(getLastErrorNumber, ()I, SSL) }, @@ -2673,6 +2749,4 @@ jint netty_internal_tcnative_SSL_JNI_OnLoad(JNIEnv* env, const char* packagePref void netty_internal_tcnative_SSL_JNI_OnUnLoad(JNIEnv* env, const char* packagePrefix) { netty_jni_util_unregister_natives(env, packagePrefix, SSL_CLASSNAME); - - ssl_init_cleanup(); } diff --git a/openssl-dynamic/src/main/c/ssl_private.h b/openssl-dynamic/src/main/c/ssl_private.h index efcc050fc..f8f75a692 100644 --- a/openssl-dynamic/src/main/c/ssl_private.h +++ b/openssl-dynamic/src/main/c/ssl_private.h @@ -48,8 +48,8 @@ #define OPENSSL_NO_RC5 #endif -#include "tcn_atomic.h" -#include "tcn_lock_rw.h" +#include "apr_thread_rwlock.h" +#include "apr_atomic.h" #include /* OpenSSL headers */ @@ -115,6 +115,8 @@ #define SSL_CVERIFY_OPTIONAL (1) #define SSL_CVERIFY_REQUIRED (2) +#define SSL_TO_APR_ERROR(X) (APR_OS_START_USERERR + 1000 + X) + extern const char* TCN_UNKNOWN_AUTH_METHOD; /* ECC: make sure we have at least 1.0.0 */ @@ -302,6 +304,7 @@ extern const SSL_PRIVATE_KEY_METHOD private_key_method; #endif // OPENSSL_IS_BORINGSSL struct tcn_ssl_ctxt_t { + apr_pool_t* pool; SSL_CTX* ctx; /* Holds the alpn protocols, each of them prefixed with the len of the protocol */ @@ -311,7 +314,7 @@ struct tcn_ssl_ctxt_t { /* for client or downstream server authentication */ char* password; - tcn_lock_rw_t ticket_keys_lock; // Session ticket lock + apr_thread_rwlock_t* mutex; // Session ticket mutext tcn_ssl_ticket_key_t* ticket_keys; /* certificate verifier callback */ @@ -367,13 +370,13 @@ struct tcn_ssl_ctxt_t { /* TLS ticket key session resumption statistics */ // The client did not present a ticket and we issued a new one. - tcn_atomic_uint32_t ticket_keys_new; + apr_uint32_t ticket_keys_new; // The client presented a ticket derived from the primary key - tcn_atomic_uint32_t ticket_keys_resume; + apr_uint32_t ticket_keys_resume; // The client presented a ticket derived from an older key, and we upgraded to the primary key. - tcn_atomic_uint32_t ticket_keys_renew; + apr_uint32_t ticket_keys_renew; // The client presented a ticket that did not match any key in the list. - tcn_atomic_uint32_t ticket_keys_fail; + apr_uint32_t ticket_keys_fail; unsigned char context_id[SHA_DIGEST_LENGTH]; diff --git a/openssl-dynamic/src/main/c/sslcontext.c b/openssl-dynamic/src/main/c/sslcontext.c index 23b5f73f3..1d45ca75a 100644 --- a/openssl-dynamic/src/main/c/sslcontext.c +++ b/openssl-dynamic/src/main/c/sslcontext.c @@ -31,11 +31,11 @@ #include "tcn.h" -#include "tcn_atomic.h" -#include "tcn_lock_rw.h" +#include "apr_thread_rwlock.h" +#include "apr_atomic.h" + #include "ssl_private.h" #include -#include #include "sslcontext.h" #include "cert_compress.h" @@ -62,9 +62,120 @@ static jmethodID sslPrivateKeyMethodDecryptTask_init; static const char* staticPackagePrefix = NULL; +extern apr_pool_t *tcn_global_pool; + +static apr_status_t ssl_context_cleanup(void *data) +{ + tcn_ssl_ctxt_t *c = (tcn_ssl_ctxt_t *)data; + JNIEnv *e = NULL; + + if (c != NULL) { + SSL_CTX_free(c->ctx); // this function is safe to call with NULL + c->ctx = NULL; + + tcn_get_java_env(&e); + +#ifdef OPENSSL_IS_BORINGSSL + if (c->ssl_private_key_method != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->ssl_private_key_method); + } + c->ssl_private_key_method = NULL; + } + if (c->ssl_cert_compression_zlib_algorithm != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_zlib_algorithm); + } + c->ssl_cert_compression_zlib_algorithm = NULL; + } + if (c->ssl_cert_compression_brotli_algorithm != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_brotli_algorithm); + } + c->ssl_cert_compression_brotli_algorithm = NULL; + } + if (c->ssl_cert_compression_zstd_algorithm != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_zstd_algorithm); + } + c->ssl_cert_compression_zstd_algorithm = NULL; + } +#endif // OPENSSL_IS_BORINGSSL + + if (c->ssl_session_cache != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->ssl_session_cache); + } + c->ssl_session_cache = NULL; + } + c->ssl_session_cache_creation_method = NULL; + c->ssl_session_cache_get_method = NULL; + + if (c->verifier != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->verifier); + } + c->verifier = NULL; + } + c->verifier_method = NULL; + + if (c->cert_requested_callback != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->cert_requested_callback); + } + c->cert_requested_callback = NULL; + } + c->cert_requested_callback_method = NULL; + + if (c->certificate_callback != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->certificate_callback); + } + c->certificate_callback = NULL; + } + c->certificate_callback_method = NULL; + + if (c->sni_hostname_matcher != NULL) { + if (e != NULL) { + (*e)->DeleteGlobalRef(e, c->sni_hostname_matcher); + } + c->sni_hostname_matcher = NULL; + } + c->sni_hostname_matcher_method = NULL; + + if (c->next_proto_data != NULL) { + OPENSSL_free(c->next_proto_data); + c->next_proto_data = NULL; + } + c->next_proto_len = 0; + + if (c->alpn_proto_data != NULL) { + OPENSSL_free(c->alpn_proto_data); + c->alpn_proto_data = NULL; + } + c->alpn_proto_len = 0; + + apr_thread_rwlock_destroy(c->mutex); + + if (c->ticket_keys != NULL) { + OPENSSL_free(c->ticket_keys); + c->ticket_keys = NULL; + } + c->ticket_keys_len = 0; + + if (c->password != NULL) { + // Just use free(...) as we used strdup(...) to create the stored password. + free(c->password); + c->password = NULL; + } + } + return APR_SUCCESS; +} + /* Initialize server context */ TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jint protocol, jint mode) { + apr_pool_t *p = NULL; tcn_ssl_ctxt_t *c = NULL; SSL_CTX *ctx = NULL; @@ -226,18 +337,17 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jint protocol, jint mod goto cleanup; } - if ((c = calloc(1, sizeof(tcn_ssl_ctxt_t))) == NULL) { - tcn_Throw(e, "Failed to calloc tcn_ssl_ctxt_t"); + TCN_THROW_IF_ERR(apr_pool_create(&p, tcn_global_pool), p); + + if ((c = apr_pcalloc(p, sizeof(tcn_ssl_ctxt_t))) == NULL) { + tcn_ThrowAPRException(e, apr_get_os_error()); goto cleanup; } c->protocol = protocol; c->mode = mode; c->ctx = ctx; - c->ticket_keys_new = tcn_atomic_uint32_create(); - c->ticket_keys_resume = tcn_atomic_uint32_create(); - c->ticket_keys_renew = tcn_atomic_uint32_create(); - c->ticket_keys_fail = tcn_atomic_uint32_create(); + c->pool = p; if (!(protocol & SSL_PROTOCOL_SSLV2)) { SSL_CTX_set_options(c->ctx, SSL_OP_NO_SSLv2); @@ -323,11 +433,20 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, make)(TCN_STDARGS, jint protocol, jint mod SSL_CTX_set_allow_unknown_alpn_protos(ctx, 1); } #endif - c->ticket_keys_lock = tcn_lock_rw_create(); + apr_thread_rwlock_create(&c->mutex, p); + /* + * Let us cleanup the ssl context when the pool is destroyed + */ + apr_pool_cleanup_register(p, (const void *)c, + ssl_context_cleanup, + apr_pool_cleanup_null); tcn_SSL_CTX_set_app_state(c->ctx, c); return P2J(c); cleanup: + if (p != NULL) { + apr_pool_destroy(p); + } SSL_CTX_free(ctx); // this function is safe to call with NULL. return 0; } @@ -338,108 +457,10 @@ TCN_IMPLEMENT_CALL(jint, SSLContext, free)(TCN_STDARGS, jlong ctx) TCN_CHECK_NULL(c, ctx, 0); - SSL_CTX_free(c->ctx); // this function is safe to call with NULL - c->ctx = NULL; - -#ifdef OPENSSL_IS_BORINGSSL - if (c->ssl_private_key_method != NULL) { - (*e)->DeleteGlobalRef(e, c->ssl_private_key_method); - c->ssl_private_key_method = NULL; - } - if (c->ssl_cert_compression_zlib_algorithm != NULL) { - (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_zlib_algorithm); - c->ssl_cert_compression_zlib_algorithm = NULL; - } - if (c->ssl_cert_compression_brotli_algorithm != NULL) { - (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_brotli_algorithm); - c->ssl_cert_compression_brotli_algorithm = NULL; - } - if (c->ssl_cert_compression_zstd_algorithm != NULL) { - (*e)->DeleteGlobalRef(e, c->ssl_cert_compression_zstd_algorithm); - c->ssl_cert_compression_zstd_algorithm = NULL; - } -#endif // OPENSSL_IS_BORINGSSL - - if (c->ssl_session_cache != NULL) { - (*e)->DeleteGlobalRef(e, c->ssl_session_cache); - c->ssl_session_cache = NULL; - } - c->ssl_session_cache_creation_method = NULL; - c->ssl_session_cache_get_method = NULL; - - if (c->verifier != NULL) { - (*e)->DeleteGlobalRef(e, c->verifier); - c->verifier = NULL; - } - c->verifier_method = NULL; - - if (c->cert_requested_callback != NULL) { - (*e)->DeleteGlobalRef(e, c->cert_requested_callback); - c->cert_requested_callback = NULL; - } - c->cert_requested_callback_method = NULL; - - if (c->certificate_callback != NULL) { - (*e)->DeleteGlobalRef(e, c->certificate_callback); - c->certificate_callback = NULL; - } - c->certificate_callback_method = NULL; - - if (c->sni_hostname_matcher != NULL) { - (*e)->DeleteGlobalRef(e, c->sni_hostname_matcher); - c->sni_hostname_matcher = NULL; - } - c->sni_hostname_matcher_method = NULL; - - if (c->next_proto_data != NULL) { - OPENSSL_free(c->next_proto_data); - c->next_proto_data = NULL; - } - c->next_proto_len = 0; - - if (c->alpn_proto_data != NULL) { - OPENSSL_free(c->alpn_proto_data); - c->alpn_proto_data = NULL; - } - c->alpn_proto_len = 0; - - if (c->ticket_keys_lock != NULL) { - tcn_lock_rw_destroy(c->ticket_keys_lock); - c->ticket_keys_lock = NULL; - } - - if (c->ticket_keys_new != NULL) { - tcn_atomic_uint32_destroy(c->ticket_keys_new); - c->ticket_keys_new = NULL; - } - if (c->ticket_keys_resume != NULL) { - tcn_atomic_uint32_destroy(c->ticket_keys_resume); - c->ticket_keys_resume = NULL; - } - if (c->ticket_keys_renew != NULL) { - tcn_atomic_uint32_destroy(c->ticket_keys_renew); - c->ticket_keys_renew = NULL; - } - if (c->ticket_keys_fail != NULL) { - tcn_atomic_uint32_destroy(c->ticket_keys_fail); - c->ticket_keys_fail = NULL; - } - - if (c->ticket_keys != NULL) { - OPENSSL_free(c->ticket_keys); - c->ticket_keys = NULL; - } - c->ticket_keys_len = 0; - - if (c->password != NULL) { - // Just use free(...) as we used strdup(...) to create the stored password. - free(c->password); - c->password = NULL; - } - - // Use free as we used calloc(...) to allocate - free(c); - return 0; + /* Run and destroy the cleanup callback */ + int result = apr_pool_cleanup_run(c->pool, c, ssl_context_cleanup); + apr_pool_destroy(c->pool); + return result; } TCN_IMPLEMENT_CALL(void, SSLContext, setContextId)(TCN_STDARGS, jlong ctx, @@ -644,7 +665,7 @@ TCN_IMPLEMENT_CALL(void, SSLContext, setTmpDHLength)(TCN_STDARGS, jlong ctx, jin SSL_CTX_set_tmp_dh_callback(c->ctx, tcn_SSL_callback_tmp_DH_4096); return; default: - tcn_Throw(e, "Unsupported length %d", length); + tcn_Throw(e, "Unsupported length %s", length); return; } } @@ -1187,7 +1208,8 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyNew)(TCN_STDARGS, jlong ct TCN_CHECK_NULL(c, ctx, 0); - return (jlong) tcn_atomic_uint32_get(c->ticket_keys_new); + jlong rv = apr_atomic_read32(&c->ticket_keys_new); + return rv; } TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyResume)(TCN_STDARGS, jlong ctx) @@ -1196,7 +1218,8 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyResume)(TCN_STDARGS, jlong TCN_CHECK_NULL(c, ctx, 0); - return (jlong) tcn_atomic_uint32_get(c->ticket_keys_resume); + jlong rv = apr_atomic_read32(&c->ticket_keys_resume); + return rv; } TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyRenew)(TCN_STDARGS, jlong ctx) @@ -1205,7 +1228,8 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyRenew)(TCN_STDARGS, jlong TCN_CHECK_NULL(c, ctx, 0); - return (jlong) tcn_atomic_uint32_get(c->ticket_keys_renew); + jlong rv = apr_atomic_read32(&c->ticket_keys_renew); + return rv; } TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyFail)(TCN_STDARGS, jlong ctx) @@ -1214,17 +1238,18 @@ TCN_IMPLEMENT_CALL(jlong, SSLContext, sessionTicketKeyFail)(TCN_STDARGS, jlong c TCN_CHECK_NULL(c, ctx, 0); - return (jlong) tcn_atomic_uint32_get(c->ticket_keys_fail); + jlong rv = apr_atomic_read32(&c->ticket_keys_fail); + return rv; } static int current_session_key(tcn_ssl_ctxt_t *c, tcn_ssl_ticket_key_t *key) { int result = JNI_FALSE; - tcn_lock_r_t reader_lock = tcn_lock_r_acquire(c->ticket_keys_lock); + apr_thread_rwlock_rdlock(c->mutex); if (c->ticket_keys_len > 0) { *key = c->ticket_keys[0]; result = JNI_TRUE; } - tcn_lock_r_release(reader_lock); + apr_thread_rwlock_unlock(c->mutex); return result; } @@ -1232,7 +1257,7 @@ static int find_session_key(tcn_ssl_ctxt_t *c, unsigned char key_name[16], tcn_s int result = JNI_FALSE; int i; - tcn_lock_r_t reader_lock = tcn_lock_r_acquire(c->ticket_keys_lock); + apr_thread_rwlock_rdlock(c->mutex); for (i = 0; i < c->ticket_keys_len; ++i) { // Check if we have a match for tickets. if (memcmp(c->ticket_keys[i].key_name, key_name, 16) == 0) { @@ -1242,7 +1267,7 @@ static int find_session_key(tcn_ssl_ctxt_t *c, unsigned char key_name[16], tcn_s break; } } - tcn_lock_r_release(reader_lock); + apr_thread_rwlock_unlock(c->mutex); return result; } @@ -1265,9 +1290,7 @@ static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key.aes_key, iv); HMAC_Init_ex(hctx, key.hmac_key, 16, EVP_sha256(), NULL); - if (c->ticket_keys_new != NULL) { - tcn_atomic_uint32_increment(c->ticket_keys_new); - } + apr_atomic_inc32(&c->ticket_keys_new); return 1; } // No ticket configured @@ -1279,21 +1302,15 @@ static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned if (!is_current_key) { // The ticket matched a key in the list, and we want to upgrade it to the current // key. - if (c->ticket_keys_renew != NULL) { - tcn_atomic_uint32_increment(c->ticket_keys_renew); - } + apr_atomic_inc32(&c->ticket_keys_renew); return 2; } // The ticket matched the current key. - if (c->ticket_keys_resume != NULL) { - tcn_atomic_uint32_increment(c->ticket_keys_resume); - } + apr_atomic_inc32(&c->ticket_keys_resume); return 1; } // No matching ticket. - if (c->ticket_keys_fail != NULL) { - tcn_atomic_uint32_increment(c->ticket_keys_fail); - } + apr_atomic_inc32(&c->ticket_keys_fail); return 0; } } @@ -1325,13 +1342,13 @@ TCN_IMPLEMENT_CALL(void, SSLContext, setSessionTicketKeys0)(TCN_STDARGS, jlong c } (*e)->ReleaseByteArrayElements(e, keys, b, 0); - tcn_lock_w_t writer_lock = tcn_lock_w_acquire(c->ticket_keys_lock); + apr_thread_rwlock_wrlock(c->mutex); if (c->ticket_keys) { OPENSSL_free(c->ticket_keys); } c->ticket_keys_len = cnt; c->ticket_keys = ticket_keys; - tcn_lock_w_release(writer_lock); + apr_thread_rwlock_unlock(c->mutex); SSL_CTX_set_tlsext_ticket_key_cb(c->ctx, ssl_tlsext_ticket_key_cb); } diff --git a/openssl-dynamic/src/main/c/sslutils.c b/openssl-dynamic/src/main/c/sslutils.c index 71b652896..74c972681 100644 --- a/openssl-dynamic/src/main/c/sslutils.c +++ b/openssl-dynamic/src/main/c/sslutils.c @@ -29,8 +29,8 @@ * limitations under the License. */ -#include #include "tcn.h" + #include "ssl_private.h" /* _________________________________________________________________ diff --git a/openssl-dynamic/src/main/c/tcn.h b/openssl-dynamic/src/main/c/tcn.h index a8b2daca9..549550f56 100644 --- a/openssl-dynamic/src/main/c/tcn.h +++ b/openssl-dynamic/src/main/c/tcn.h @@ -36,6 +36,13 @@ #include #include "netty_jni_util.h" +#include "apr.h" +#include "apr_pools.h" + +#ifndef APR_HAS_THREADS +#error "Missing APR_HAS_THREADS support from APR." +#endif + #include #include #if defined(_WIN32) && !defined(__CYGWIN__) @@ -79,6 +86,7 @@ void tcn_Throw(JNIEnv *, const char *, ...); void tcn_ThrowException(JNIEnv *, const char *); void tcn_ThrowNullPointerException(JNIEnv *, const char *); void tcn_ThrowIllegalArgumentException(JNIEnv *, const char *); +void tcn_ThrowAPRException(JNIEnv *, apr_status_t); void tcn_throwOutOfMemoryError(JNIEnv *, const char *); jstring tcn_new_string(JNIEnv *, const char *); @@ -109,6 +117,15 @@ jstring tcn_new_stringn(JNIEnv *, const char *, size_t); free(c##V); \ NETTY_JNI_UTIL_END_MACRO +#define TCN_THROW_IF_ERR(x, r) \ + NETTY_JNI_UTIL_BEGIN_MACRO \ + apr_status_t R = (x); \ + if (R != APR_SUCCESS) { \ + tcn_ThrowAPRException(e, R); \ + (r) = 0; \ + goto cleanup; \ + } \ + NETTY_JNI_UTIL_END_MACRO #define TCN_MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/openssl-dynamic/src/main/c/tcn_atomic.cpp b/openssl-dynamic/src/main/c/tcn_atomic.cpp deleted file mode 100644 index 89f05c47b..000000000 --- a/openssl-dynamic/src/main/c/tcn_atomic.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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 "tcn_atomic.h" -#include - -tcn_atomic_uint32_t tcn_atomic_uint32_create() { - return (tcn_atomic_uint32_t) new std::atomic(0); -} - -void tcn_atomic_uint32_destroy(tcn_atomic_uint32_t atomic) { - delete (std::atomic *) atomic; -} - -uint32_t tcn_atomic_uint32_get(tcn_atomic_uint32_t atomic) { - return *((std::atomic *) atomic); -} - -void tcn_atomic_uint32_increment(tcn_atomic_uint32_t atomic) { - auto *p = (std::atomic *) atomic; - ++(*p); -} diff --git a/openssl-dynamic/src/main/c/tcn_atomic.h b/openssl-dynamic/src/main/c/tcn_atomic.h deleted file mode 100644 index 04b608a65..000000000 --- a/openssl-dynamic/src/main/c/tcn_atomic.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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. - */ -#ifndef TCN_ATOMIC_H -#define TCN_ATOMIC_H - -#ifdef __cplusplus -#include -extern "C" { -#else -#include -#endif // __cplusplus - -typedef void* tcn_atomic_uint32_t; - -tcn_atomic_uint32_t tcn_atomic_uint32_create(); - -void tcn_atomic_uint32_destroy(tcn_atomic_uint32_t atomic); - -uint32_t tcn_atomic_uint32_get(tcn_atomic_uint32_t atomic); - -void tcn_atomic_uint32_increment(tcn_atomic_uint32_t atomic); - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif //TCN_ATOMIC_H diff --git a/openssl-dynamic/src/main/c/tcn_lock.cpp b/openssl-dynamic/src/main/c/tcn_lock.cpp deleted file mode 100644 index 9222bbe90..000000000 --- a/openssl-dynamic/src/main/c/tcn_lock.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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 "tcn_lock.h" -#include - -tcn_lock_t tcn_lock_create() { - return (tcn_lock_t) new std::mutex; -} - -void tcn_lock_destroy(tcn_lock_t lock) { - delete (std::mutex *) lock; -} - -void tcn_lock_acquire(tcn_lock_t lock) { - ((std::mutex *) lock)->lock(); -} - -void tcn_lock_release(tcn_lock_t lock) { - ((std::mutex *) lock)->unlock(); -} diff --git a/openssl-dynamic/src/main/c/tcn_lock.h b/openssl-dynamic/src/main/c/tcn_lock.h deleted file mode 100644 index a92bb4a38..000000000 --- a/openssl-dynamic/src/main/c/tcn_lock.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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. - */ -#ifndef TCN_LOCK_H -#define TCN_LOCK_H - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef void* tcn_lock_t; - -tcn_lock_t tcn_lock_create(); - -void tcn_lock_destroy(tcn_lock_t lock); - -void tcn_lock_acquire(tcn_lock_t lock); - -void tcn_lock_release(tcn_lock_t lock); - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif //TCN_LOCK_H diff --git a/openssl-dynamic/src/main/c/tcn_lock_rw.cpp b/openssl-dynamic/src/main/c/tcn_lock_rw.cpp deleted file mode 100644 index 8b5035a3f..000000000 --- a/openssl-dynamic/src/main/c/tcn_lock_rw.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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 "tcn_lock_rw.h" -#include -#include - -tcn_lock_rw_t tcn_lock_rw_create() { - // Once we switch to c++17 we should use std::shared_mutex - return (tcn_lock_rw_t) new std::shared_timed_mutex; -} - -void tcn_lock_rw_destroy(tcn_lock_rw_t lock) { - delete (std::shared_timed_mutex *) lock; -} - -tcn_lock_w_t tcn_lock_w_acquire(tcn_lock_rw_t lock) { - return (tcn_lock_w_t) new std::unique_lock(*((std::shared_timed_mutex *) lock)); -} - -void tcn_lock_w_release(tcn_lock_w_t lock) { - delete (std::unique_lock *) lock; -} - -tcn_lock_r_t tcn_lock_r_acquire(tcn_lock_rw_t lock) { - return (tcn_lock_r_t) new std::unique_lock(*((std::shared_timed_mutex *) lock)); -} - -void tcn_lock_r_release(tcn_lock_r_t lock) { - delete (std::unique_lock *) lock; -} diff --git a/openssl-dynamic/src/main/c/tcn_lock_rw.h b/openssl-dynamic/src/main/c/tcn_lock_rw.h deleted file mode 100644 index b7bccc7eb..000000000 --- a/openssl-dynamic/src/main/c/tcn_lock_rw.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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. - */ -#ifndef TCN_LOCK_RW_H -#define TCN_LOCK_RW_H - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef void* tcn_lock_rw_t; -typedef void* tcn_lock_w_t; -typedef void* tcn_lock_r_t; - -tcn_lock_rw_t tcn_lock_rw_create(); - -void tcn_lock_rw_destroy(tcn_lock_rw_t lock); - -tcn_lock_w_t tcn_lock_w_acquire(tcn_lock_rw_t lock); - -void tcn_lock_w_release(tcn_lock_w_t lock); - -tcn_lock_r_t tcn_lock_r_acquire(tcn_lock_rw_t lock); - -void tcn_lock_r_release(tcn_lock_r_t lock); - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif //TCN_LOCK_RW_H diff --git a/openssl-dynamic/src/main/c/tcn_thread.cpp b/openssl-dynamic/src/main/c/tcn_thread.cpp deleted file mode 100644 index e7fe2132e..000000000 --- a/openssl-dynamic/src/main/c/tcn_thread.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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 "tcn_thread.h" -#include - -size_t tcn_current_thread_id() { - return std::hash()(std::this_thread::get_id()); -} diff --git a/openssl-dynamic/src/main/c/tcn_thread.h b/openssl-dynamic/src/main/c/tcn_thread.h deleted file mode 100644 index 3175914cf..000000000 --- a/openssl-dynamic/src/main/c/tcn_thread.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2023 The Netty Project - * - * The Netty Project 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. - */ -#ifndef TCN_THREAD_H -#define TCN_THREAD_H - -#ifdef __cplusplus -#include -extern "C" { -#else -#include -#endif // __cplusplus - -size_t tcn_current_thread_id(); - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif //TCN_THREAD_H diff --git a/openssl-dynamic/src/main/native-package/configure.ac b/openssl-dynamic/src/main/native-package/configure.ac index 36d3e6bba..cdb97c4c7 100644 --- a/openssl-dynamic/src/main/native-package/configure.ac +++ b/openssl-dynamic/src/main/native-package/configure.ac @@ -29,14 +29,12 @@ AC_CANONICAL_HOST AC_CANONICAL_SYSTEM ${CFLAGS="-O3 -Werror -fno-omit-frame-pointer -fvisibility=hidden -Wunused -Wno-unused-value -Wno-deprecated-declarations"} -# Ensure we support c++14 for atomics etc -${CXXFLAGS="-O3 -Werror -fno-omit-frame-pointer -fvisibility=hidden -Wunused -Wno-unused-value -std=c++14"} +${CXXFLAGS="-O3 -Werror -fno-omit-frame-pointer -fvisibility=hidden -Wunused -Wno-unused-value"} ## ----------------------------------------------- ## Application Checks ## ----------------------------------------------- AC_PROG_CC -AC_PROG_CXX AC_PROG_INSTALL # Make AM_PROG_AR work before automake 1.12 m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) diff --git a/openssl-dynamic/src/main/native-package/m4/apr_common.m4 b/openssl-dynamic/src/main/native-package/m4/apr_common.m4 new file mode 100644 index 000000000..6b5c0f033 --- /dev/null +++ b/openssl-dynamic/src/main/native-package/m4/apr_common.m4 @@ -0,0 +1,990 @@ +dnl -------------------------------------------------------- -*- autoconf -*- +dnl Licensed to the Apache Software Foundation (ASF) under one or more +dnl contributor license agreements. See the NOTICE file distributed with +dnl this work for additional information regarding copyright ownership. +dnl The ASF licenses this file to You under the Apache License, Version 2.0 +dnl (the "License"); you may not use this file except in compliance with +dnl the License. You may obtain a copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, +dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +dnl See the License for the specific language governing permissions and +dnl limitations under the License. + +dnl +dnl apr_common.m4: APR's general-purpose autoconf macros +dnl + +dnl +dnl APR_CONFIG_NICE(filename) +dnl +dnl Saves a snapshot of the configure command-line for later reuse +dnl +AC_DEFUN([APR_CONFIG_NICE], [ + rm -f $1 + cat >$1<> $1 + fi + if test -n "$CFLAGS"; then + echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> $1 + fi + if test -n "$CPPFLAGS"; then + echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> $1 + fi + if test -n "$LDFLAGS"; then + echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> $1 + fi + if test -n "$LTFLAGS"; then + echo "LTFLAGS=\"$LTFLAGS\"; export LTFLAGS" >> $1 + fi + if test -n "$LIBS"; then + echo "LIBS=\"$LIBS\"; export LIBS" >> $1 + fi + if test -n "$INCLUDES"; then + echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> $1 + fi + if test -n "$NOTEST_CFLAGS"; then + echo "NOTEST_CFLAGS=\"$NOTEST_CFLAGS\"; export NOTEST_CFLAGS" >> $1 + fi + if test -n "$NOTEST_CPPFLAGS"; then + echo "NOTEST_CPPFLAGS=\"$NOTEST_CPPFLAGS\"; export NOTEST_CPPFLAGS" >> $1 + fi + if test -n "$NOTEST_LDFLAGS"; then + echo "NOTEST_LDFLAGS=\"$NOTEST_LDFLAGS\"; export NOTEST_LDFLAGS" >> $1 + fi + if test -n "$NOTEST_LIBS"; then + echo "NOTEST_LIBS=\"$NOTEST_LIBS\"; export NOTEST_LIBS" >> $1 + fi + + # Retrieve command-line arguments. + eval "set x $[0] $ac_configure_args" + shift + + for arg + do + APR_EXPAND_VAR(arg, $arg) + echo "\"[$]arg\" \\" >> $1 + done + echo '"[$]@"' >> $1 + chmod +x $1 +])dnl + +dnl APR_MKDIR_P_CHECK(fallback-mkdir-p) +dnl checks whether mkdir -p works +AC_DEFUN([APR_MKDIR_P_CHECK], [ + AC_CACHE_CHECK(for working mkdir -p, ac_cv_mkdir_p,[ + test -d conftestdir && rm -rf conftestdir + mkdir -p conftestdir/somedir >/dev/null 2>&1 + if test -d conftestdir/somedir; then + ac_cv_mkdir_p=yes + else + ac_cv_mkdir_p=no + fi + rm -rf conftestdir + ]) + if test "$ac_cv_mkdir_p" = "yes"; then + mkdir_p="mkdir -p" + else + mkdir_p="$1" + fi +]) + +dnl +dnl APR_SUBDIR_CONFIG(dir [, sub-package-cmdline-args, args-to-drop]) +dnl +dnl dir: directory to find configure in +dnl sub-package-cmdline-args: arguments to add to the invocation (optional) +dnl args-to-drop: arguments to drop from the invocation (optional) +dnl +dnl Note: This macro relies on ac_configure_args being set properly. +dnl +dnl The args-to-drop argument is shoved into a case statement, so +dnl multiple arguments can be separated with a |. +dnl +dnl Note: Older versions of autoconf do not single-quote args, while 2.54+ +dnl places quotes around every argument. So, if you want to drop the +dnl argument called --enable-layout, you must pass the third argument as: +dnl [--enable-layout=*|\'--enable-layout=*] +dnl +dnl Trying to optimize this is left as an exercise to the reader who wants +dnl to put up with more autoconf craziness. I give up. +dnl +AC_DEFUN([APR_SUBDIR_CONFIG], [ + # save our work to this point; this allows the sub-package to use it + AC_CACHE_SAVE + + echo "configuring package in $1 now" + ac_popdir=`pwd` + apr_config_subdirs="$1" + test -d $1 || $mkdir_p $1 + ac_abs_srcdir=`(cd $srcdir/$1 && pwd)` + cd $1 + +changequote(, )dnl + # A "../" for each directory in /$config_subdirs. + ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` +changequote([, ])dnl + + # Make the cache file pathname absolute for the subdirs + # required to correctly handle subdirs that might actually + # be symlinks + case "$cache_file" in + /*) # already absolute + ac_sub_cache_file=$cache_file ;; + *) # Was relative path. + ac_sub_cache_file="$ac_popdir/$cache_file" ;; + esac + + ifelse($3, [], [apr_configure_args=$ac_configure_args],[ + apr_configure_args= + apr_sep= + for apr_configure_arg in $ac_configure_args + do + case "$apr_configure_arg" in + $3) + continue ;; + esac + apr_configure_args="$apr_configure_args$apr_sep'$apr_configure_arg'" + apr_sep=" " + done + ]) + + dnl autoconf doesn't add --silent to ac_configure_args; explicitly pass it + test "x$silent" = "xyes" && apr_configure_args="$apr_configure_args --silent" + + dnl AC_CONFIG_SUBDIRS silences option warnings, emulate this for 2.62 + apr_configure_args="--disable-option-checking $apr_configure_args" + + dnl The eval makes quoting arguments work - specifically the second argument + dnl where the quoting mechanisms used is "" rather than []. + dnl + dnl We need to execute another shell because some autoconf/shell combinations + dnl will choke after doing repeated APR_SUBDIR_CONFIG()s. (Namely Solaris + dnl and autoconf-2.54+) + if eval $SHELL $ac_abs_srcdir/configure $apr_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir $2 + then : + echo "$1 configured properly" + else + echo "configure failed for $1" + exit 1 + fi + + cd $ac_popdir + + # grab any updates from the sub-package + AC_CACHE_LOAD +])dnl + +dnl +dnl APR_SAVE_THE_ENVIRONMENT(variable_name) +dnl +dnl Stores the variable (usually a Makefile macro) for later restoration +dnl +AC_DEFUN([APR_SAVE_THE_ENVIRONMENT], [ + apr_ste_save_$1="$$1" +])dnl + +dnl +dnl APR_RESTORE_THE_ENVIRONMENT(variable_name, prefix_) +dnl +dnl Uses the previously saved variable content to figure out what configure +dnl has added to the variable, moving the new bits to prefix_variable_name +dnl and restoring the original variable contents. This makes it possible +dnl for a user to override configure when it does something stupid. +dnl +AC_DEFUN([APR_RESTORE_THE_ENVIRONMENT], [ +dnl Check whether $apr_ste_save_$1 is empty or +dnl only whitespace. The verbatim "X" is token number 1, +dnl the following whitespace will be ignored. +set X $apr_ste_save_$1 +if test ${#} -eq 1; then + $2$1="$$1" + $1= +else + if test "x$apr_ste_save_$1" = "x$$1"; then + $2$1= + else + $2$1=`echo "$$1" | sed -e "s%${apr_ste_save_$1}%%"` + $1="$apr_ste_save_$1" + fi +fi +if test "x$silent" != "xyes"; then + echo " restoring $1 to \"$$1\"" + echo " setting $2$1 to \"$$2$1\"" +fi +AC_SUBST($2$1) +])dnl + +dnl +dnl APR_SETIFNULL(variable, value) +dnl +dnl Set variable iff it's currently null +dnl +AC_DEFUN([APR_SETIFNULL], [ + if test -z "$$1"; then + test "x$silent" != "xyes" && echo " setting $1 to \"$2\"" + $1="$2" + fi +])dnl + +dnl +dnl APR_SETVAR(variable, value) +dnl +dnl Set variable no matter what +dnl +AC_DEFUN([APR_SETVAR], [ + test "x$silent" != "xyes" && echo " forcing $1 to \"$2\"" + $1="$2" +])dnl + +dnl +dnl APR_ADDTO(variable, value) +dnl +dnl Add value to variable +dnl +AC_DEFUN([APR_ADDTO], [ + if test "x$$1" = "x"; then + test "x$silent" != "xyes" && echo " setting $1 to \"$2\"" + $1="$2" + else + apr_addto_bugger="$2" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $$1; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to $1" + $1="$$1 $i" + fi + done + fi +])dnl + +dnl +dnl APR_REMOVEFROM(variable, value) +dnl +dnl Remove a value from a variable +dnl +AC_DEFUN([APR_REMOVEFROM], [ + if test "x$$1" = "x$2"; then + test "x$silent" != "xyes" && echo " nulling $1" + $1="" + else + apr_new_bugger="" + apr_removed=0 + for i in $$1; do + if test "x$i" != "x$2"; then + apr_new_bugger="$apr_new_bugger $i" + else + apr_removed=1 + fi + done + if test $apr_removed = "1"; then + test "x$silent" != "xyes" && echo " removed \"$2\" from $1" + $1=$apr_new_bugger + fi + fi +]) dnl + +dnl +dnl APR_CHECK_DEFINE_FILES( symbol, header_file [header_file ...] ) +dnl +AC_DEFUN([APR_CHECK_DEFINE_FILES], [ + AC_CACHE_CHECK([for $1 in $2],ac_cv_define_$1,[ + ac_cv_define_$1=no + for curhdr in $2 + do + AC_EGREP_CPP(YES_IS_DEFINED, [ +#include <$curhdr> +#ifdef $1 +YES_IS_DEFINED +#endif + ], ac_cv_define_$1=yes) + done + ]) + if test "$ac_cv_define_$1" = "yes"; then + AC_DEFINE(HAVE_$1, 1, [Define if $1 is defined]) + fi +]) + + +dnl +dnl APR_CHECK_DEFINE(symbol, header_file) +dnl +AC_DEFUN([APR_CHECK_DEFINE], [ + AC_CACHE_CHECK([for $1 in $2],ac_cv_define_$1,[ + AC_EGREP_CPP(YES_IS_DEFINED, [ +#include <$2> +#ifdef $1 +YES_IS_DEFINED +#endif + ], ac_cv_define_$1=yes, ac_cv_define_$1=no) + ]) + if test "$ac_cv_define_$1" = "yes"; then + AC_DEFINE(HAVE_$1, 1, [Define if $1 is defined in $2]) + fi +]) + +dnl +dnl APR_CHECK_APR_DEFINE( symbol ) +dnl +AC_DEFUN([APR_CHECK_APR_DEFINE], [ +apr_old_cppflags=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $INCLUDES" +AC_EGREP_CPP(YES_IS_DEFINED, [ +#include +#if $1 +YES_IS_DEFINED +#endif +], ac_cv_define_$1=yes, ac_cv_define_$1=no) +CPPFLAGS=$apr_old_cppflags +]) + +dnl APR_CHECK_FILE(filename); set ac_cv_file_filename to +dnl "yes" if 'filename' is readable, else "no". +dnl @deprecated! - use AC_CHECK_FILE instead +AC_DEFUN([APR_CHECK_FILE], [ +dnl Pick a safe variable name +define([apr_cvname], ac_cv_file_[]translit([$1], [./+-], [__p_])) +AC_CACHE_CHECK([for $1], [apr_cvname], +[if test -r $1; then + apr_cvname=yes + else + apr_cvname=no + fi]) +]) + +define(APR_IFALLYES,[dnl +ac_rc=yes +for ac_spec in $1; do + ac_type=`echo "$ac_spec" | sed -e 's/:.*$//'` + ac_item=`echo "$ac_spec" | sed -e 's/^.*://'` + case $ac_type in + header ) + ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'` + ac_var="ac_cv_header_$ac_item" + ;; + file ) + ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'` + ac_var="ac_cv_file_$ac_item" + ;; + func ) ac_var="ac_cv_func_$ac_item" ;; + struct ) ac_var="ac_cv_struct_$ac_item" ;; + define ) ac_var="ac_cv_define_$ac_item" ;; + custom ) ac_var="$ac_item" ;; + esac + eval "ac_val=\$$ac_var" + if test ".$ac_val" != .yes; then + ac_rc=no + break + fi +done +if test ".$ac_rc" = .yes; then + : + $2 +else + : + $3 +fi +]) + + +define(APR_BEGIN_DECISION,[dnl +ac_decision_item='$1' +ac_decision_msg='FAILED' +ac_decision='' +]) + + +AC_DEFUN([APR_DECIDE],[dnl +dnl Define the flag (or not) in apr_private.h via autoheader +AH_TEMPLATE($1, [Define if $2 will be used]) +ac_decision='$1' +ac_decision_msg='$2' +ac_decision_$1=yes +ac_decision_$1_msg='$2' +]) + + +define(APR_DECISION_OVERRIDE,[dnl + ac_decision='' + for ac_item in $1; do + eval "ac_decision_this=\$ac_decision_${ac_item}" + if test ".$ac_decision_this" = .yes; then + ac_decision=$ac_item + eval "ac_decision_msg=\$ac_decision_${ac_item}_msg" + fi + done +]) + + +define(APR_DECISION_FORCE,[dnl +ac_decision="$1" +eval "ac_decision_msg=\"\$ac_decision_${ac_decision}_msg\"" +]) + + +define(APR_END_DECISION,[dnl +if test ".$ac_decision" = .; then + echo "[$]0:Error: decision on $ac_decision_item failed" 1>&2 + exit 1 +else + if test ".$ac_decision_msg" = .; then + ac_decision_msg="$ac_decision" + fi + AC_DEFINE_UNQUOTED(${ac_decision_item}) + AC_MSG_RESULT([decision on $ac_decision_item... $ac_decision_msg]) +fi +]) + + +dnl +dnl APR_CHECK_SIZEOF_EXTENDED(INCLUDES, TYPE [, CROSS_SIZE]) +dnl +dnl A variant of AC_CHECK_SIZEOF which allows the checking of +dnl sizes of non-builtin types +dnl +AC_DEFUN([APR_CHECK_SIZEOF_EXTENDED], +[changequote(<<, >>)dnl +dnl The name to #define. +define(<>, translit(sizeof_$2, [a-z *], [A-Z_P]))dnl +dnl The cache variable name. +define(<>, translit(ac_cv_sizeof_$2, [ *], [_p]))dnl +changequote([, ])dnl +AC_MSG_CHECKING(size of $2) +AC_CACHE_VAL(AC_CV_NAME, +[AC_TRY_RUN([#include +$1 +#ifdef WIN32 +#define binmode "b" +#else +#define binmode +#endif +main() +{ + FILE *f=fopen("conftestval", "w" binmode); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof($2)); + exit(0); +}], AC_CV_NAME=`cat conftestval`, AC_CV_NAME=0, ifelse([$3],,, +AC_CV_NAME=$3))])dnl +AC_MSG_RESULT($AC_CV_NAME) +AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The size of ]$2) +undefine([AC_TYPE_NAME])dnl +undefine([AC_CV_NAME])dnl +]) + + +dnl +dnl APR_TRY_COMPILE_NO_WARNING(INCLUDES, FUNCTION-BODY, +dnl [ACTIONS-IF-NO-WARNINGS], [ACTIONS-IF-WARNINGS]) +dnl +dnl Tries a compile test with warnings activated so that the result +dnl is false if the code doesn't compile cleanly. For compilers +dnl where it is not known how to activate a "fail-on-error" mode, +dnl it is undefined which of the sets of actions will be run. +dnl +AC_DEFUN([APR_TRY_COMPILE_NO_WARNING], +[apr_save_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $CFLAGS_WARN" + if test "$ac_cv_prog_gcc" = "yes"; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [#include "confdefs.h" + ] + [[$1]] + [int main(int argc, const char *const *argv) {] + [[$2]] + [ return 0; }] + )], + [$3], [$4]) + CFLAGS=$apr_save_CFLAGS +]) + +dnl +dnl APR_CHECK_STRERROR_R_RC +dnl +dnl Decide which style of retcode is used by this system's +dnl strerror_r(). It either returns int (0 for success, -1 +dnl for failure), or it returns a pointer to the error +dnl string. +dnl +dnl +AC_DEFUN([APR_CHECK_STRERROR_R_RC], [ +AC_MSG_CHECKING(for type of return code from strerror_r) +AC_TRY_RUN([ +#include +#include +#include +main() +{ + char buf[1024]; + if (strerror_r(ERANGE, buf, sizeof buf) < 1) { + exit(0); + } + else { + exit(1); + } +}], [ + ac_cv_strerror_r_rc_int=yes ], [ + ac_cv_strerror_r_rc_int=no ], [ + ac_cv_strerror_r_rc_int=no ] ) +if test "x$ac_cv_strerror_r_rc_int" = xyes; then + AC_DEFINE(STRERROR_R_RC_INT, 1, [Define if strerror returns int]) + msg="int" +else + msg="pointer" +fi +AC_MSG_RESULT([$msg]) +] ) + +dnl +dnl APR_CHECK_DIRENT_INODE +dnl +dnl Decide if d_fileno or d_ino are available in the dirent +dnl structure on this platform. Single UNIX Spec says d_ino, +dnl BSD uses d_fileno. Undef to find the real beast. +dnl +AC_DEFUN([APR_CHECK_DIRENT_INODE], [ +AC_CACHE_CHECK([for inode member of struct dirent], apr_cv_dirent_inode, [ +apr_cv_dirent_inode=no +AC_TRY_COMPILE([ +#include +#include +],[ +#ifdef d_ino +#undef d_ino +#endif +struct dirent de; de.d_fileno; +], apr_cv_dirent_inode=d_fileno) +if test "$apr_cv_dirent_inode" = "no"; then +AC_TRY_COMPILE([ +#include +#include +],[ +#ifdef d_fileno +#undef d_fileno +#endif +struct dirent de; de.d_ino; +], apr_cv_dirent_inode=d_ino) +fi +]) +if test "$apr_cv_dirent_inode" != "no"; then + AC_DEFINE_UNQUOTED(DIRENT_INODE, $apr_cv_dirent_inode, + [Define if struct dirent has an inode member]) +fi +]) + +dnl +dnl APR_CHECK_DIRENT_TYPE +dnl +dnl Decide if d_type is available in the dirent structure +dnl on this platform. Not part of the Single UNIX Spec. +dnl Note that this is worthless without DT_xxx macros, so +dnl look for one while we are at it. +dnl +AC_DEFUN([APR_CHECK_DIRENT_TYPE], [ +AC_CACHE_CHECK([for file type member of struct dirent], apr_cv_dirent_type,[ +apr_cv_dirent_type=no +AC_TRY_COMPILE([ +#include +#include +],[ +struct dirent de; de.d_type = DT_REG; +], apr_cv_dirent_type=d_type) +]) +if test "$apr_cv_dirent_type" != "no"; then + AC_DEFINE_UNQUOTED(DIRENT_TYPE, $apr_cv_dirent_type, + [Define if struct dirent has a d_type member]) +fi +]) + +dnl the following is a newline, a space, a tab, and a backslash (the +dnl backslash is used by the shell to skip newlines, but m4 sees it; +dnl treat it like whitespace). +dnl WARNING: don't reindent these lines, or the space/tab will be lost! +define([apr_whitespace],[ + \]) + +dnl +dnl APR_COMMA_ARGS(ARG1 ...) +dnl convert the whitespace-separated arguments into comman-separated +dnl arguments. +dnl +dnl APR_FOREACH(CODE-BLOCK, ARG1, ARG2, ...) +dnl subsitute CODE-BLOCK for each ARG[i]. "eachval" will be set to ARG[i] +dnl within each iteration. +dnl +changequote({,}) +define({APR_COMMA_ARGS},{patsubst([$}{1],[[}apr_whitespace{]+],[,])}) +define({APR_FOREACH}, + {ifelse($}{2,,, + [define([eachval], + $}{2)$}{1[]APR_FOREACH([$}{1], + builtin([shift], + builtin([shift], $}{@)))])}) +changequote([,]) + +dnl APR_FLAG_HEADERS(HEADER-FILE ... [, FLAG-TO-SET ] [, "yes" ]) +dnl we set FLAG-TO-SET to 1 if we find HEADER-FILE, otherwise we set to 0 +dnl if FLAG-TO-SET is null, we automagically determine it's name +dnl by changing all "/" to "_" in the HEADER-FILE and dropping +dnl all "." and "-" chars. If the 3rd parameter is "yes" then instead of +dnl setting to 1 or 0, we set FLAG-TO-SET to yes or no. +dnl +AC_DEFUN([APR_FLAG_HEADERS], [ +AC_CHECK_HEADERS($1) +for aprt_i in $1 +do + ac_safe=`echo "$aprt_i" | sed 'y%./+-%__p_%'` + aprt_2=`echo "$aprt_i" | sed -e 's%/%_%g' -e 's/\.//g' -e 's/-//g'` + if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + eval "ifelse($2,,$aprt_2,$2)=ifelse($3,yes,yes,1)" + else + eval "ifelse($2,,$aprt_2,$2)=ifelse($3,yes,no,0)" + fi +done +]) + +dnl APR_FLAG_FUNCS(FUNC ... [, FLAG-TO-SET] [, "yes" ]) +dnl if FLAG-TO-SET is null, we automagically determine it's name +dnl prepending "have_" to the function name in FUNC, otherwise +dnl we use what's provided as FLAG-TO-SET. If the 3rd parameter +dnl is "yes" then instead of setting to 1 or 0, we set FLAG-TO-SET +dnl to yes or no. +dnl +AC_DEFUN([APR_FLAG_FUNCS], [ +AC_CHECK_FUNCS($1) +for aprt_j in $1 +do + aprt_3="have_$aprt_j" + if eval "test \"`echo '$ac_cv_func_'$aprt_j`\" = yes"; then + eval "ifelse($2,,$aprt_3,$2)=ifelse($3,yes,yes,1)" + else + eval "ifelse($2,,$aprt_3,$2)=ifelse($3,yes,no,0)" + fi +done +]) + +dnl Iteratively interpolate the contents of the second argument +dnl until interpolation offers no new result. Then assign the +dnl final result to $1. +dnl +dnl Example: +dnl +dnl foo=1 +dnl bar='${foo}/2' +dnl baz='${bar}/3' +dnl APR_EXPAND_VAR(fraz, $baz) +dnl $fraz is now "1/2/3" +dnl +AC_DEFUN([APR_EXPAND_VAR], [ +ap_last= +ap_cur="$2" +while test "x${ap_cur}" != "x${ap_last}"; +do + ap_last="${ap_cur}" + ap_cur=`eval "echo ${ap_cur}"` +done +$1="${ap_cur}" +]) + +dnl +dnl Removes the value of $3 from the string in $2, strips of any leading +dnl slashes, and returns the value in $1. +dnl +dnl Example: +dnl orig_path="${prefix}/bar" +dnl APR_PATH_RELATIVE(final_path, $orig_path, $prefix) +dnl $final_path now contains "bar" +AC_DEFUN([APR_PATH_RELATIVE], [ +ap_stripped=`echo $2 | sed -e "s#^$3##"` +# check if the stripping was successful +if test "x$2" != "x${ap_stripped}"; then + # it was, so strip of any leading slashes + $1="`echo ${ap_stripped} | sed -e 's#^/*##'`" +else + # it wasn't so return the original + $1="$2" +fi +]) + +dnl APR_HELP_STRING(LHS, RHS) +dnl Autoconf 2.50 can not handle substr correctly. It does have +dnl AC_HELP_STRING, so let's try to call it if we can. +dnl Note: this define must be on one line so that it can be properly returned +dnl as the help string. When using this macro with a multi-line RHS, ensure +dnl that you surround the macro invocation with []s +AC_DEFUN([APR_HELP_STRING], [ifelse(regexp(AC_ACVERSION, 2\.1), -1, AC_HELP_STRING([$1],[$2]),[ ][$1] substr([ ],len($1))[$2])]) + +dnl +dnl APR_LAYOUT(configlayout, layoutname [, extravars]) +dnl +AC_DEFUN([APR_LAYOUT], [ + if test ! -f $srcdir/config.layout; then + echo "** Error: Layout file $srcdir/config.layout not found" + echo "** Error: Cannot use undefined layout '$LAYOUT'" + exit 1 + fi + # Catch layout names including a slash which will otherwise + # confuse the heck out of the sed script. + case $2 in + */*) + echo "** Error: $2 is not a valid layout name" + exit 1 ;; + esac + pldconf=./config.pld + changequote({,}) + sed -e "1s/[ ]*<[lL]ayout[ ]*$2[ ]*>[ ]*//;1t" \ + -e "1,/[ ]*<[lL]ayout[ ]*$2[ ]*>[ ]*/d" \ + -e '/[ ]*<\/Layout>[ ]*/,$d' \ + -e "s/^[ ]*//g" \ + -e "s/:[ ]*/=\'/g" \ + -e "s/[ ]*$/'/g" \ + $1 > $pldconf + layout_name=$2 + if test ! -s $pldconf; then + echo "** Error: unable to find layout $layout_name" + exit 1 + fi + . $pldconf + rm $pldconf + for var in prefix exec_prefix bindir sbindir libexecdir mandir \ + sysconfdir datadir includedir localstatedir runtimedir \ + logfiledir libdir installbuilddir libsuffix $3; do + eval "val=\"\$$var\"" + case $val in + *+) + val=`echo $val | sed -e 's;\+$;;'` + eval "$var=\"\$val\"" + autosuffix=yes + ;; + *) + autosuffix=no + ;; + esac + val=`echo $val | sed -e 's:\(.\)/*$:\1:'` + val=`echo $val | sed -e 's:[\$]\([a-z_]*\):${\1}:g'` + if test "$autosuffix" = "yes"; then + if echo $val | grep apache >/dev/null; then + addtarget=no + else + addtarget=yes + fi + if test "$addtarget" = "yes"; then + val="$val/apache2" + fi + fi + eval "$var='$val'" + done + changequote([,]) +])dnl + +dnl +dnl APR_ENABLE_LAYOUT(default layout name [, extra vars]) +dnl +AC_DEFUN([APR_ENABLE_LAYOUT], [ +AC_ARG_ENABLE(layout, +[ --enable-layout=LAYOUT],[ + LAYOUT=$enableval +]) + +if test -z "$LAYOUT"; then + LAYOUT="$1" +fi +APR_LAYOUT($srcdir/config.layout, $LAYOUT, $2) + +AC_MSG_CHECKING(for chosen layout) +AC_MSG_RESULT($layout_name) +]) + + +dnl +dnl APR_PARSE_ARGUMENTS +dnl a reimplementation of autoconf's argument parser, +dnl used here to allow us to co-exist layouts and argument based +dnl set ups. +AC_DEFUN([APR_PARSE_ARGUMENTS], [ +ac_prev= +# Retrieve the command-line arguments. The eval is needed because +# the arguments are quoted to preserve accuracy. +eval "set x $ac_configure_args" +shift +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[[^=]]*=\(.*\)'` + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + esac +done + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [[\\/$]]* | ?:[[\\/]]* | NONE | '' ) ;; + *) AC_MSG_ERROR([expected an absolute path for --$ac_var: $ac_val]);; + esac +done + +])dnl + +dnl +dnl APR_CHECK_DEPEND +dnl +dnl Determine what program we can use to generate .deps-style dependencies +dnl +AC_DEFUN([APR_CHECK_DEPEND], [ +dnl Try to determine what depend program we can use +dnl All GCC-variants should have -MM. +dnl If not, then we can check on those, too. +if test "$GCC" = "yes"; then + MKDEP='$(CC) -MM' +else + rm -f conftest.c +dnl should be available everywhere! + cat > conftest.c < + int main() { return 0; } +EOF + MKDEP="true" + for i in "$CC -MM" "$CC -M" "$CPP -MM" "$CPP -M" "cpp -M"; do + AC_MSG_CHECKING([if $i can create proper make dependencies]) + if $i conftest.c 2>/dev/null | grep 'conftest.o: conftest.c' >/dev/null; then + MKDEP=$i + AC_MSG_RESULT(yes) + break; + fi + AC_MSG_RESULT(no) + done + rm -f conftest.c +fi + +AC_SUBST(MKDEP) +]) + +dnl +dnl APR_CHECK_TYPES_COMPATIBLE(TYPE-1, TYPE-2, [ACTION-IF-TRUE]) +dnl +dnl Try to determine whether two types are the same. Only works +dnl for gcc and icc. +dnl +AC_DEFUN([APR_CHECK_TYPES_COMPATIBLE], [ +define([apr_cvname], apr_cv_typematch_[]translit([$1], [ ], [_])_[]translit([$2], [ ], [_])) +AC_CACHE_CHECK([whether $1 and $2 are the same], apr_cvname, [ +AC_TRY_COMPILE(AC_INCLUDES_DEFAULT, [ + int foo[0 - !__builtin_types_compatible_p($1, $2)]; +], [apr_cvname=yes +$3], [apr_cvname=no])]) +]) diff --git a/openssl-dynamic/src/main/native-package/m4/custom.m4 b/openssl-dynamic/src/main/native-package/m4/custom.m4 index 0435a265e..11242ba67 100644 --- a/openssl-dynamic/src/main/native-package/m4/custom.m4 +++ b/openssl-dynamic/src/main/native-package/m4/custom.m4 @@ -17,18 +17,25 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([CUSTOM_M4_SETUP], [ dnl These macros were copied from tomcat-native/jni/native/build/ + sinclude(m4/apr_common.m4) + sinclude(m4/find_apr.m4) dnl This macro was copied from tomcat-native/jni/native/build with slight modifications dnl - Fix autoconf warnings + dnl - Make TCN_FIND_APR try the system's APR installation sinclude(m4/tcnative.m4) + dnl Make sure Apache Portable Runtime is available in the system. + APR_PARSE_ARGUMENTS + TCN_FIND_APR + dnl Enable OpenSSL OCSP verification support. AC_ARG_ENABLE(ocsp, [AS_HELP_STRING([--enable-ocsp],[Turn on OpenSSL OCSP verification support])], [ case "${enableval}" in yes) - TCN_ADDTO(CFLAGS, [-DHAVE_OPENSSL_OCSP]) + APR_ADDTO(CFLAGS, [-DHAVE_OPENSSL_OCSP]) AC_MSG_RESULT([Enabling OCSP verification support...]) ;; esac @@ -42,10 +49,10 @@ AC_DEFUN([CUSTOM_M4_SETUP], TCN_CHECK_SSL_TOOLKIT fi - dnl Update the compiler/linker flags to add OpenSSL to the build path. - CFLAGS="$CFLAGS $TCN_OPENSSL_INC -D_LARGEFILE64_SOURCE" - CXXFLAGS="$CXXFLAGS $TCN_OPENSSL_INC" - LDFLAGS="$LDFLAGS $TCN_OPENSSL_LIBS" + dnl Update the compiler/linker flags to add APR and OpenSSL to the build path. + CFLAGS="$CFLAGS $TCN_OPENSSL_INC $APR_INCLUDES -D_LARGEFILE64_SOURCE" + CXXFLAGS="$CXXFLAGS $TCN_OPENSSL_INC $APR_INCLUDES" + LDFLAGS="$LDFLAGS $TCN_OPENSSL_LIBS $APR_LIBS" AC_SUBST(CFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(LDFLAGS) diff --git a/openssl-dynamic/src/main/native-package/m4/find_apr.m4 b/openssl-dynamic/src/main/native-package/m4/find_apr.m4 new file mode 100644 index 000000000..925e523f8 --- /dev/null +++ b/openssl-dynamic/src/main/native-package/m4/find_apr.m4 @@ -0,0 +1,202 @@ +dnl -------------------------------------------------------- -*- autoconf -*- +dnl Licensed to the Apache Software Foundation (ASF) under one or more +dnl contributor license agreements. See the NOTICE file distributed with +dnl this work for additional information regarding copyright ownership. +dnl The ASF licenses this file to You under the Apache License, Version 2.0 +dnl (the "License"); you may not use this file except in compliance with +dnl the License. You may obtain a copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, +dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +dnl See the License for the specific language governing permissions and +dnl limitations under the License. + +dnl +dnl find_apr.m4 : locate the APR include files and libraries +dnl +dnl This macro file can be used by applications to find and use the APR +dnl library. It provides a standardized mechanism for using APR. It supports +dnl embedding APR into the application source, or locating an installed +dnl copy of APR. +dnl +dnl APR_FIND_APR(srcdir, builddir, implicit-install-check, acceptable-majors, +dnl detailed-check) +dnl +dnl where srcdir is the location of the bundled APR source directory, or +dnl empty if source is not bundled. +dnl +dnl where builddir is the location where the bundled APR will will be built, +dnl or empty if the build will occur in the srcdir. +dnl +dnl where implicit-install-check set to 1 indicates if there is no +dnl --with-apr option specified, we will look for installed copies. +dnl +dnl where acceptable-majors is a space separated list of acceptable major +dnl version numbers. Often only a single major version will be acceptable. +dnl If multiple versions are specified, and --with-apr=PREFIX or the +dnl implicit installed search are used, then the first (leftmost) version +dnl in the list that is found will be used. Currently defaults to [0 1]. +dnl +dnl where detailed-check is an M4 macro which sets the apr_acceptable to +dnl either "yes" or "no". The macro will be invoked for each installed +dnl copy of APR found, with the apr_config variable set appropriately. +dnl Only installed copies of APR which are considered acceptable by +dnl this macro will be considered found. If no installed copies are +dnl considered acceptable by this macro, apr_found will be set to either +dnl either "no" or "reconfig". +dnl +dnl Sets the following variables on exit: +dnl +dnl apr_found : "yes", "no", "reconfig" +dnl +dnl apr_config : If the apr-config tool exists, this refers to it. If +dnl apr_found is "reconfig", then the bundled directory +dnl should be reconfigured *before* using apr_config. +dnl +dnl Note: this macro file assumes that apr-config has been installed; it +dnl is normally considered a required part of an APR installation. +dnl +dnl If a bundled source directory is available and needs to be (re)configured, +dnl then apr_found is set to "reconfig". The caller should reconfigure the +dnl (passed-in) source directory, placing the result in the build directory, +dnl as appropriate. +dnl +dnl If apr_found is "yes" or "reconfig", then the caller should use the +dnl value of apr_config to fetch any necessary build/link information. +dnl + +AC_DEFUN([APR_FIND_APR], [ + apr_found="no" + + if test "$target_os" = "os2-emx"; then + # Scripts don't pass test -x on OS/2 + TEST_X="test -f" + else + TEST_X="test -x" + fi + + ifelse([$4], [], [ + ifdef(AC_WARNING,AC_WARNING([$0: missing argument 4 (acceptable-majors): Defaulting to APR 0.x then APR 1.x])) + acceptable_majors="0 1"], + [acceptable_majors="$4"]) + + apr_temp_acceptable_apr_config="" + for apr_temp_major in $acceptable_majors + do + case $apr_temp_major in + 0) + apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-config" + ;; + *) + apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-$apr_temp_major-config" + ;; + esac + done + + AC_MSG_CHECKING(for APR) + AC_ARG_WITH(apr, + [ --with-apr=PATH prefix for installed APR or the full path to + apr-config], + [ + if test "$withval" = "no" || test "$withval" = "yes"; then + AC_MSG_ERROR([--with-apr requires a directory or file to be provided]) + fi + + for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config + do + for lookdir in "$withval/bin" "$withval" + do + if $TEST_X "$lookdir/$apr_temp_apr_config_file"; then + apr_config="$lookdir/$apr_temp_apr_config_file" + ifelse([$5], [], [], [ + apr_acceptable="yes" + $5 + if test "$apr_acceptable" != "yes"; then + AC_MSG_WARN([Found APR in $apr_config, but we think it is considered unacceptable]) + continue + fi]) + apr_found="yes" + break 2 + fi + done + done + + if test "$apr_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then + apr_config="$withval" + ifelse([$5], [], [apr_found="yes"], [ + apr_acceptable="yes" + $5 + if test "$apr_acceptable" = "yes"; then + apr_found="yes" + fi]) + fi + + dnl if --with-apr is used, it is a fatal error for its argument + dnl to be invalid + if test "$apr_found" != "yes"; then + AC_MSG_ERROR([the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file.]) + fi + ],[ + dnl If we allow installed copies, check those before using bundled copy. + if test -n "$3" && test "$3" = "1"; then + for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config + do + if $apr_temp_apr_config_file --help > /dev/null 2>&1 ; then + apr_config="$apr_temp_apr_config_file" + ifelse([$5], [], [], [ + apr_acceptable="yes" + $5 + if test "$apr_acceptable" != "yes"; then + AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) + continue + fi]) + apr_found="yes" + break + else + dnl look in some standard places + for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do + if $TEST_X "$lookdir/bin/$apr_temp_apr_config_file"; then + apr_config="$lookdir/bin/$apr_temp_apr_config_file" + ifelse([$5], [], [], [ + apr_acceptable="yes" + $5 + if test "$apr_acceptable" != "yes"; then + AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) + continue + fi]) + apr_found="yes" + break 2 + fi + done + fi + done + fi + dnl if we have not found anything yet and have bundled source, use that + if test "$apr_found" = "no" && test -d "$1"; then + apr_temp_abs_srcdir="`cd \"$1\" && pwd`" + apr_found="reconfig" + apr_bundled_major="`sed -n '/#define.*APR_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apr_version.h\"`" + case $apr_bundled_major in + "") + AC_MSG_ERROR([failed to find major version of bundled APR]) + ;; + 0) + apr_temp_apr_config_file="apr-config" + ;; + *) + apr_temp_apr_config_file="apr-$apr_bundled_major-config" + ;; + esac + if test -n "$2"; then + apr_config="$2/$apr_temp_apr_config_file" + else + apr_config="$1/$apr_temp_apr_config_file" + fi + fi + ]) + + AC_MSG_RESULT($apr_found) +]) diff --git a/openssl-dynamic/src/main/native-package/m4/tcnative.m4 b/openssl-dynamic/src/main/native-package/m4/tcnative.m4 index 136cbb318..52262f901 100644 --- a/openssl-dynamic/src/main/native-package/m4/tcnative.m4 +++ b/openssl-dynamic/src/main/native-package/m4/tcnative.m4 @@ -16,30 +16,46 @@ # dnl -dnl TCN_ADDTO(variable, value) +dnl TCN_FIND_APR: figure out where APR is located dnl -dnl Add value to variable -dnl -AC_DEFUN([TCN_ADDTO], [ - if test "x$$1" = "x"; then - test "x$silent" != "xyes" && echo " setting $1 to \"$2\"" - $1="$2" +AC_DEFUN([TCN_FIND_APR],[ + + dnl use the find_apr.m4 script to locate APR. sets apr_found and apr_config + APR_FIND_APR(,,[1],[1]) + if test "$apr_found" = "no"; then + AC_MSG_ERROR(APR could not be located. Please use the --with-apr option.) + fi + + sapr_pversion="`$apr_config --version`" + if test -z "$sapr_pversion"; then + AC_MSG_ERROR(APR config could not be located. Please use the --with-apr option.) + fi + sapr_version="`echo $sapr_pversion|sed -e 's/\([a-z]*\)$/.\1/'`" + tc_save_IFS=$IFS; IFS=.; set $sapr_version; IFS=$tc_save_IFS + if test "${1}" -lt "1"; then + AC_MSG_ERROR(You need APR version 1.2.1 or newer installed. For optimal performance version 1.3.0 or newer is needed.) else - tcn_addto_bugger="$2" - for i in $tcn_addto_bugger; do - tcn_addto_duplicate="0" - for j in $$1; do - if test "x$i" = "x$j"; then - tcn_addto_duplicate="1" - break - fi - done - if test $tcn_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to $1" - $1="$$1 $i" - fi - done + if test "${2}" -lt "2"; then + AC_MSG_ERROR(You need APR version 1.2.1 or newer installed. For optimal performance version 1.3.0 or newer is needed.) + elif test "${2}" -lt "3"; then + AC_MSG_WARN(For optimal performance you need APR version 1.3.0 or newer installed.) + fi fi + + APR_BUILD_DIR="`$apr_config --installbuilddir`" + + dnl make APR_BUILD_DIR an absolute directory (we'll need it in the + dnl sub-projects in some cases) + APR_BUILD_DIR="`cd $APR_BUILD_DIR && pwd`" + + APR_INCLUDES="`$apr_config --includes`" + APR_LIBS="`$apr_config --link-libtool --libs`" + APR_SO_EXT="`$apr_config --apr-so-ext`" + APR_LIB_TARGET="`$apr_config --apr-lib-target`" + + AC_SUBST(APR_INCLUDES) + AC_SUBST(APR_LIBS) + AC_SUBST(APR_BUILD_DIR) ]) dnl -------------------------------------------------------------------------- @@ -261,7 +277,7 @@ AC_DEFUN([TCN_HELP_STRING],[ifelse(regexp(AC_ACVERSION, 2\.1), -1, AC_HELP_STRIN dnl dnl TCN_CHECK_STATIC -dnl Will prepare more LDFLAGS that should be set to ensure we do not export any functions from the static compiled OpenSSL libs. +dnl Will prepare more LDFLAGS that should be set to ensure we do not export any functions from the static compiled APR / OpenSSL libs. dnl AC_DEFUN([TCN_CHECK_STATIC],[ LD_FLAGS_STATIC="" @@ -275,21 +291,7 @@ AC_DEFUN([TCN_CHECK_STATIC],[ LD_FLAGS_STATIC="-Wl,-exported_symbol,_JNI_*" ;; *linux*) - dnl On linux we also statically link libstdc++ etc to make it as backward / forward compatible as possible. - LD_FLAGS_STATIC="-static-libstdc++ -static-libgcc -l:libgcc.a -l:libstdc++.a -Wl,--exclude-libs,ALL" - - dnl Cleanup libtool postdeps so it will not link against libtdc++ dynamically. - AC_MSG_NOTICE([Cleanup libtool C++ postdeps: $postdeps_CXX]) - tmppostdeps=; - for x in ${postdeps_CXX}; - do - case $x in - -lstdc++) true; ;; - -lgcc_s) true; ;; - *) tmppostdeps=${tmppostdeps}${tmppostdeps:+ }$x; ;; - esac; - done; - postdeps_CXX="${tmppostdeps}"; + LD_FLAGS_STATIC="-Wl,--exclude-libs,ALL" ;; *) LD_FLAGS_STATIC="" @@ -430,10 +432,10 @@ esac esac if test "x$USE_OPENSSL" != "x" then - TCN_ADDTO(TCNATIVE_PRIV_INCLUDES, [$TCN_OPENSSL_INC]) - TCN_ADDTO(TCNATIVE_LDFLAGS, [$TCN_OPENSSL_LIBS]) - TCN_ADDTO(CFLAGS, [-DHAVE_OPENSSL]) + APR_ADDTO(TCNATIVE_PRIV_INCLUDES, [$TCN_OPENSSL_INC]) + APR_ADDTO(TCNATIVE_LDFLAGS, [$TCN_OPENSSL_LIBS]) + APR_ADDTO(CFLAGS, [-DHAVE_OPENSSL]) fi -TCN_ADDTO(LDFLAGS, [$LD_FLAGS_STATIC]) +APR_ADDTO(LDFLAGS, [$LD_FLAGS_STATIC]) ]) diff --git a/openssl-dynamic/src/main/native-package/vs2010.vcxproj b/openssl-dynamic/src/main/native-package/vs2010.vcxproj index abdec307b..8658b90a2 100644 --- a/openssl-dynamic/src/main/native-package/vs2010.vcxproj +++ b/openssl-dynamic/src/main/native-package/vs2010.vcxproj @@ -79,7 +79,7 @@ - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) + $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(APR_INCLUDE_DIR);$(APR_INCLUDE_DIR)\arch\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) MaxSpeed true Speed @@ -96,8 +96,8 @@ Cdecl - Psapi.lib;Shlwapi.lib;Ws2_32.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) - $(OPENSSL_LIB_DIR);%(AdditionalLibraryDirectories) + Psapi.lib;Shlwapi.lib;Ws2_32.lib;libapr-1.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) + $(OPENSSL_LIB_DIR);$(APR_LIB_DIR);%(AdditionalLibraryDirectories) true Windows true @@ -107,7 +107,7 @@ - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) + $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(APR_INCLUDE_DIR);$(APR_INCLUDE_DIR)\arch\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) MaxSpeed true Speed @@ -124,8 +124,8 @@ Cdecl - Psapi.lib;Shlwapi.lib;Ws2_32.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) - $(OPENSSL_LIB_DIR);%(AdditionalLibraryDirectories) + Psapi.lib;Shlwapi.lib;Ws2_32.lib;libapr-1.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) + $(OPENSSL_LIB_DIR);$(APR_LIB_DIR);%(AdditionalLibraryDirectories) true Windows true @@ -135,7 +135,7 @@ - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) + $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(APR_INCLUDE_DIR);$(APR_INCLUDE_DIR)\arch\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) Disabled Speed WIN32_LEAN_AND_MEAN;WIN32;_DEBUG;_WINDOWS;HAVE_OPENSSL;%(PreprocessorDefinitions) @@ -152,8 +152,8 @@ Cdecl - Psapi.lib;Shlwapi.lib;Ws2_32.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) - $(OPENSSL_LIB_DIR);%(AdditionalLibraryDirectories) + Psapi.lib;Shlwapi.lib;Ws2_32.lib;libapr-1.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) + $(OPENSSL_LIB_DIR);$(APR_LIB_DIR);%(AdditionalLibraryDirectories) true Windows MachineX86 @@ -161,7 +161,7 @@ - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) + $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(APR_INCLUDE_DIR);$(APR_INCLUDE_DIR)\arch\win32;$(OPENSSL_INCLUDE_DIR);$(ProjectDir)\src\windows;%(AdditionalIncludeDirectories) Disabled Speed WIN32_LEAN_AND_MEAN;WIN64;_DEBUG;_WINDOWS;HAVE_OPENSSL;%(PreprocessorDefinitions) @@ -178,8 +178,8 @@ Cdecl - Psapi.lib;Shlwapi.lib;Ws2_32.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) - $(OPENSSL_LIB_DIR);%(AdditionalLibraryDirectories) + Psapi.lib;Shlwapi.lib;Ws2_32.lib;libapr-1.lib;libssl.lib;libcrypto.lib;%(AdditionalDependencies) + $(OPENSSL_LIB_DIR);$(APR_LIB_DIR);%(AdditionalLibraryDirectories) true Windows MachineX64 @@ -196,10 +196,6 @@ - - - - diff --git a/openssl-static/pom.xml b/openssl-static/pom.xml index 90f9d8ecc..0352b5966 100644 --- a/openssl-static/pom.xml +++ b/openssl-static/pom.xml @@ -27,7 +27,7 @@ Netty/TomcatNative [OpenSSL - Static] A Mavenized fork of Tomcat Native which incorporates various patches. This artifact is statically linked - to OpenSSL. + to OpenSSL and Apache APR. @@ -66,6 +66,7 @@ maven-bundle-plugin + ${aprVersion} ${opensslVersion} @@ -157,7 +158,7 @@ - + org.fusesource.hawtjni hawtjni-maven-plugin @@ -180,6 +181,7 @@ ${macOsxDeploymentTarget} --with-ssl=${opensslHome} + --with-apr=${aprHome} --with-static-libs --libdir=${project.build.directory}/native-build/target/lib diff --git a/patches/apr_crypt.patch b/patches/apr_crypt.patch new file mode 100644 index 000000000..9cb4f976c --- /dev/null +++ b/patches/apr_crypt.patch @@ -0,0 +1,10 @@ +--- configure.in.old 2023-01-09 14:22:19 ++++ configure.in 2023-01-09 14:22:43 +@@ -729,7 +729,6 @@ + AC_SEARCH_LIBS(gethostbyname, nsl) + AC_SEARCH_LIBS(gethostname, nsl) + AC_SEARCH_LIBS(socket, socket) +- AC_SEARCH_LIBS(crypt, crypt ufc) + AC_CHECK_LIB(truerand, main) + AC_SEARCH_LIBS(modf, m) + ;; diff --git a/pom.xml b/pom.xml index 1bc168696..11aaddd2c 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,8 @@ ${project.build.directory}/native-lib-only ${project.build.directory}/native-jar-work ${os.detected.name}_${os.detected.arch} + 1.7.4 + fc648de983f3a2a6c9e78dea1f180639bd2fad6c06d556d4367a701fe5c35577 chromium-stable + + + + + + + + + @@ -480,6 +495,240 @@ + + + build-apr-windows + + + windows + + + + + 1.6.5 + 70dcf9102066a2ff2ffc47e93c289c8e54c95d8dda23b503f9e61bb0cbd2d105 + + + + + maven-antrun-plugin + + + source-apr + generate-sources + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + build-apr + compile + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + build-apr-linux-mac + + + !windows + + + + + + maven-antrun-plugin + + + source-apr-linux-mac + generate-sources + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + build-apr-linux-mac + compile + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +