You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2022/07/06 21:19:48 UTC

[commons-crypto] branch master updated: Add code to allow macOS dlopen override

This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git


The following commit(s) were added to refs/heads/master by this push:
     new 760ccfd  Add code to allow macOS dlopen override
760ccfd is described below

commit 760ccfdd40ab1a80d72c8971ab505ec681f2ce62
Author: Sebb <se...@apache.org>
AuthorDate: Wed Jul 6 22:19:42 2022 +0100

    Add code to allow macOS dlopen override
---
 Makefile                                           |  6 +-
 .../org/apache/commons/crypto/utils/Utils.java     | 20 +++++++
 .../org/apache/commons/crypto/DynamicLoader.c      | 64 ++++++++++++++++++++++
 .../org/apache/commons/crypto/OpenSslInfoNative.c  |  7 +--
 .../apache/commons/crypto/cipher/OpenSslNative.c   |  4 +-
 .../commons/crypto/org_apache_commons_crypto.h     |  6 ++
 .../crypto/random/OpenSslCryptoRandomNative.c      |  4 +-
 7 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index 7fa3723..a839b95 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 include Makefile.common
 
 COMMONS_CRYPTO_OUT:=$(TARGET)/$(commons-crypto)-$(os_arch)
-COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpenSslCryptoRandomNative.o OpenSslNative.o OpenSslInfoNative.o)
+COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpenSslCryptoRandomNative.o OpenSslNative.o OpenSslInfoNative.o DynamicLoader.o)
 
 # Shorthand for local dependencies
 CRYPTO_H:=$(SRC_NATIVE)/org/apache/commons/crypto/org_apache_commons_crypto.h lib/include/config.h
@@ -62,6 +62,10 @@ $(COMMONS_CRYPTO_OUT)/OpenSslInfoNative.o : $(SRC_NATIVE)/org/apache/commons/cry
 	@mkdir -p $(@D)
 	$(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -DPROJECT_NAME='"$(PROJECT_NAME)"' -I"$(TARGET)/jni-classes" -c $< -o $@
 
+$(COMMONS_CRYPTO_OUT)/DynamicLoader.o : $(SRC_NATIVE)/org/apache/commons/crypto/DynamicLoader.c $(CRYPTO_H)
+	@mkdir -p $(@D)
+	$(CC) $(CFLAGS) -c $< -o $@
+
 $(COMMONS_CRYPTO_OUT)/$(LIBNAME): $(COMMONS_CRYPTO_OBJ)
 	$(CXX) $(CXXFLAGS) -o $@ $+ $(LINKFLAGS)
 	$(STRIP) $@
diff --git a/src/main/java/org/apache/commons/crypto/utils/Utils.java b/src/main/java/org/apache/commons/crypto/utils/Utils.java
index 90bcf48..d2d25bf 100644
--- a/src/main/java/org/apache/commons/crypto/utils/Utils.java
+++ b/src/main/java/org/apache/commons/crypto/utils/Utils.java
@@ -17,6 +17,7 @@
  */
 package org.apache.commons.crypto.utils;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -221,4 +222,23 @@ public final class Utils {
         return res;
     }
 
+    /*
+     * Override the default DLL name if jni.library.path is a valid directory
+     * @param name - the default name, passed from native code
+     * @return the updated library path
+     * This method is designed for use from the DynamicLoader native code.
+     * Although it could all be implemented in native code, this hook method
+     * makes maintenance easier.
+     * The code is intended for use with macOS where SIP makes it hard to override
+     * the environment variables needed to override the DLL search path. It also
+     * works for Linux, but is not (currently) used or needed for Windows.
+     * N.B. Do not change the method name or its signature!
+     */
+    static String libraryPath(final String name) {
+        final String override = System.getProperty("jni.library.path");
+        if (override != null && new File(override).isDirectory()) {
+            return new File(override, name).getPath();
+        }
+        return name;
+    }
 }
diff --git a/src/main/native/org/apache/commons/crypto/DynamicLoader.c b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
new file mode 100644
index 0000000..f64bb65
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/DynamicLoader.c
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+Shared code to load and unload the library.
+*/
+
+#include "org_apache_commons_crypto.h"
+
+#ifdef UNIX
+static void *openssl; // the cached pointer
+void *open_library(JNIEnv *env)
+#endif
+
+#ifdef WINDOWS
+static HMODULE openssl; // the cached pointer
+HMODULE open_library(JNIEnv *env)
+#endif
+
+{
+  if (!openssl) {
+    const char *libraryPath = COMMONS_CRYPTO_OPENSSL_LIBRARY;
+    jclass clazz = (*env)->FindClass(env, "org/apache/commons/crypto/utils/Utils");
+    if (clazz) {
+        jmethodID libraryPathFunc = (*env)->GetStaticMethodID(env, clazz, "libraryPath", "(Ljava/lang/String;)Ljava/lang/String;");
+        if (libraryPathFunc) {
+            jstring defaultLibrary = (*env)->NewStringUTF(env, COMMONS_CRYPTO_OPENSSL_LIBRARY);
+            jstring result = (jstring) (*env)->CallStaticObjectMethod(env, clazz, libraryPathFunc, defaultLibrary);
+            if (result) {
+                libraryPath = (*env)->GetStringUTFChars(env, result, NULL);
+            }
+        }
+    }
+#ifdef UNIX
+    openssl = dlopen(libraryPath, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+    // not necessary to provide override for Windows
+    openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+#endif
+
+  }
+  return openssl;
+}
+
+void close_library() {
+    openssl = NULL;
+}
diff --git a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
index 7d30c18..78cd410 100644
--- a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
+++ b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
@@ -83,11 +83,11 @@ static int load_library(JNIEnv *env)
 {
   char msg[100];
 #ifdef UNIX
-  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = open_library(env);
 #endif
 
 #ifdef WINDOWS
-  HMODULE openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+  HMODULE openssl = open_library(env);
 #endif
 
   if (!openssl) {
@@ -147,9 +147,6 @@ JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_OpenS
 JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_DLLName
   (JNIEnv *env, jclass clazz)
 {
-  if (!load_library(env)) {
-    return NULL;
-  }
   jstring answer = (*env)->NewStringUTF(env, COMMONS_CRYPTO_OPENSSL_LIBRARY);
   return answer;
 }
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
index 2204d0a..9905c7e 100644
--- a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
@@ -148,11 +148,11 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
 {
   char msg[1000];
 #ifdef UNIX
-  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = open_library(env);
 #endif
 
 #ifdef WINDOWS
-  HMODULE openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+  HMODULE openssl = open_library(env);
 #endif
 
   if (!openssl) {
diff --git a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
index 83f592f..1896bfb 100644
--- a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
+++ b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
@@ -62,6 +62,8 @@
     if ((*env)->ExceptionCheck(env)) return (ret); \
   }
 
+void close_library();
+
 /**
  * Unix definitions
  */
@@ -75,6 +77,8 @@
 #include <dlfcn.h>
 #include <jni.h>
 
+void *open_library(JNIEnv *env);
+
 /**
  * A helper function to dlsym a 'symbol' from a given library-handle.
  *
@@ -177,6 +181,8 @@ void *do_dlsym_fallback(JNIEnv *env, void *handle, const char *symbol, const cha
 #define snprintf(a, b ,c, d) _snprintf_s((a), (b), _TRUNCATE, (c), (d))
 #endif
 
+HMODULE open_library(JNIEnv *env);
+
 /* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
 #define LOAD_DYNAMIC_SYMBOL(func_type, func_ptr, env, handle, symbol) \
   if ((func_ptr = (func_type) do_dlsym(env, handle, symbol)) == NULL) { \
diff --git a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
index b9b810f..966685b 100644
--- a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
+++ b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
@@ -102,11 +102,11 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandom
 {
   char msg[1000];
 #ifdef UNIX
-  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = open_library(env);
 #endif
 
 #ifdef WINDOWS
-  HMODULE openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+  HMODULE openssl = open_library(env);
 #endif
 
   if (!openssl) {