diff --git a/CHANGELOG.md b/CHANGELOG.md index fa6d698f6..9b6a078e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Redis: "Required (skip verify)" SSL mode now actually skips certificate verification, matching `redis-cli --tls --insecure`. Previously every mode performed verification because of a phantom dictionary key the app never wrote. Connections to Upstash Redis and similar endpoints with untrusted CAs work (#1247). - MSSQL: SSL mode finally affects the connection. `Disabled` / `Preferred` / `Required` / `Verify CA` / `Verify Identity` map to FreeTDS `off` / `request` / `require` / `require` / `require` via `DBSETENCRYPT`. Previously the setting was read and silently ignored. - MongoDB: "Required" and "Verify CA" pass the right libmongoc flags (`tlsAllowInvalidCertificates`, `tlsAllowInvalidHostnames`) so connections to self-signed or untrusted-CA servers stop failing on those paths. +- MongoDB: connecting no longer crashes with `dispatch_sync called on queue already owned by current thread` when the server version cache is cold (#1249). +- MongoDB: TLS handshake to Atlas no longer fails with `internal error (-9838)` on macOS 26. libmongoc is rebuilt with OpenSSL 3.4.3 instead of Apple Secure Transport; the previous backend hit a peer-side `internal_error` alert during TLS 1.3 negotiation with Atlas clusters. +- MongoDB: importing a connection URL without a database path no longer fails with Unauthorized when the user lacks `listDatabases` privilege on `admin`. `listDatabases` now passes `authorizedDatabases: true` so Atlas users restricted to one database see that database; if the call still fails, the connection stays open with no default database selected. - MySQL: CA certificate is no longer loaded when the user picked a mode that skips verification, matching PostgreSQL. ## [0.40.3] - 2026-05-13 diff --git a/Libs/checksums.sha256 b/Libs/checksums.sha256 index dc4ad15ad..0b743b9da 100644 --- a/Libs/checksums.sha256 +++ b/Libs/checksums.sha256 @@ -1,7 +1,7 @@ -36e3a521b8da03bafd0f943c4f3b21c8c573bf9d640c6c9e764c0c3632672849 Libs/libbson_arm64.a -b7716e3f295a54feee85c8771332505be2f9a4a430a088d476d60e358d737c9e Libs/libbson_universal.a -1e502e7fb4edc79639140e18d433a1ed1be2931162daecee71a74d09e9f4c550 Libs/libbson_x86_64.a -b7716e3f295a54feee85c8771332505be2f9a4a430a088d476d60e358d737c9e Libs/libbson.a +6c16abade13041111a9551245043b195aa27ce79ce0ab32113962e762f63485f Libs/libbson_arm64.a +9b7d7abb13b36a4856fd8b4a6cc2a2b312c1bb1815ae9891cc30fe605badeb3c Libs/libbson_universal.a +adb2ade8531660c846df3dab6cafc0a6ba15bf4a9d0ae0a1bc8edaca98bf1ffa Libs/libbson_x86_64.a +9b7d7abb13b36a4856fd8b4a6cc2a2b312c1bb1815ae9891cc30fe605badeb3c Libs/libbson.a 8d7e31145470a339f4f57930831936db30412393a339598deece6f650214865a Libs/libcassandra_arm64.a 9bfd7d7cb4a7ee9823b4c5141e942a8534de63395983388722dc7c98e5d7731e Libs/libcassandra_universal.a 7f1d058c77b66273db2b3867103c19f62ed0518fb38611b178ce04029213d5d8 Libs/libcassandra_x86_64.a @@ -26,10 +26,10 @@ b777f7a42766fb08c8e67b2310c67d2d463d77d3554c6092221c3352778622b2 Libs/libmariad 5326ed729b287ae5dbbcf073aaa70dce29a73c7431e446d5958271af19dac8d8 Libs/libmariadb_universal.a 4f7bbb3d73be178d4211c3bd5b2726b4a12db8b808eaa5212bf8e9eb3c570814 Libs/libmariadb_x86_64.a 5326ed729b287ae5dbbcf073aaa70dce29a73c7431e446d5958271af19dac8d8 Libs/libmariadb.a -9f4c87916ef65eae43b19d7568dc4fd4dffd884dc0cae15913b90965293339a7 Libs/libmongoc_arm64.a -0d7ddc82dc7327a4b5187ffbc68a1419b5e5ff7b2be7b927e16793eef4d34303 Libs/libmongoc_universal.a -635705c7dc8d689efdee5ec1bd8a8cbd0d09ae20db0869480271a293d492de50 Libs/libmongoc_x86_64.a -0d7ddc82dc7327a4b5187ffbc68a1419b5e5ff7b2be7b927e16793eef4d34303 Libs/libmongoc.a +06268890fb365085d7f093b6941c507fb8f7fa2754fb22c62331ba8e8ae2068a Libs/libmongoc_arm64.a +b063818886170377f6cd1de714157032e3948e8a9616d3488a503423d8045053 Libs/libmongoc_universal.a +51b08ff457246e3032f1a13306f0e540658e91b1c560a7251ce5087a2ff17be0 Libs/libmongoc_x86_64.a +b063818886170377f6cd1de714157032e3948e8a9616d3488a503423d8045053 Libs/libmongoc.a 5dbf2cb5ef37d8adbf607db82461b36a3fd7037c11d891383e6e918378a33d78 Libs/libpgcommon_arm64.a 3ca491a723b9d9dfc13b815659b44a82253b540dd6b115f03ac68c5154ec26db Libs/libpgcommon_universal.a 4bfad7376aefa866d1ed0b7e54966ec6c9d70dcfed928e1311c20321bf08881c Libs/libpgcommon_x86_64.a diff --git a/Plugins/MongoDBDriverPlugin/CLibMongoc/include/mongoc/mongoc-config.h b/Plugins/MongoDBDriverPlugin/CLibMongoc/include/mongoc/mongoc-config.h index 38314f8b7..9bf0f0a4d 100644 --- a/Plugins/MongoDBDriverPlugin/CLibMongoc/include/mongoc/mongoc-config.h +++ b/Plugins/MongoDBDriverPlugin/CLibMongoc/include/mongoc/mongoc-config.h @@ -78,7 +78,7 @@ * MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are * compiled with Native SSL support on Darwin */ -#define MONGOC_ENABLE_SSL_SECURE_TRANSPORT 1 +#define MONGOC_ENABLE_SSL_SECURE_TRANSPORT 0 #if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1 # undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT @@ -89,7 +89,7 @@ * MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are * compiled with Native Crypto support on Darwin */ -#define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 1 +#define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 0 #if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO @@ -111,7 +111,7 @@ * MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are * compiled with OpenSSL support. */ -#define MONGOC_ENABLE_SSL_OPENSSL 0 +#define MONGOC_ENABLE_SSL_OPENSSL 1 #if MONGOC_ENABLE_SSL_OPENSSL != 1 # undef MONGOC_ENABLE_SSL_OPENSSL @@ -122,7 +122,7 @@ * MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are * compiled with OpenSSL support. */ -#define MONGOC_ENABLE_CRYPTO_LIBCRYPTO 0 +#define MONGOC_ENABLE_CRYPTO_LIBCRYPTO 1 #if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO @@ -164,7 +164,7 @@ /* * Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data */ -#define MONGOC_HAVE_ASN1_STRING_GET0_DATA 0 +#define MONGOC_HAVE_ASN1_STRING_GET0_DATA 1 #if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1 # undef MONGOC_HAVE_ASN1_STRING_GET0_DATA diff --git a/Plugins/MongoDBDriverPlugin/MongoDBCapabilities.swift b/Plugins/MongoDBDriverPlugin/MongoDBCapabilities.swift index 945fc105d..0805bc8d1 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBCapabilities.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBCapabilities.swift @@ -15,6 +15,10 @@ struct MongoDBCapabilities: Sendable, Equatable { major > 3 || (major == 3 && minor >= 4) } + var supportsAuthorizedDatabases: Bool { + major >= 4 + } + static func parse(_ version: String?) -> MongoDBCapabilities { guard let version else { return .unknown } let parts = version.split(separator: ".") diff --git a/Plugins/MongoDBDriverPlugin/MongoDBConnection.swift b/Plugins/MongoDBDriverPlugin/MongoDBConnection.swift index 485b7c4c0..198828edc 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBConnection.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBConnection.swift @@ -38,7 +38,9 @@ extension MongoDBError: PluginDriverError { /// Thread-safe MongoDB connection using libmongoc. /// All blocking C calls are dispatched to a dedicated serial queue. -/// Uses `queue.async` + continuations (never `queue.sync`) to prevent deadlocks. +/// Async entry points use `queue.async` + continuations. Synchronous entry points +/// detect on-queue re-entry via `queueKey` and call sync helpers directly to +/// avoid `dispatch_sync` deadlocks when an on-queue block re-enters a public API. final class MongoDBConnection: @unchecked Sendable { // MARK: - Properties @@ -50,6 +52,7 @@ final class MongoDBConnection: @unchecked Sendable { private var client: OpaquePointer? #endif + private static let queueKey = DispatchSpecificKey() private let queue = DispatchQueue(label: "com.TablePro.mongodb", qos: .userInitiated) private let host: String private let port: Int @@ -133,6 +136,11 @@ final class MongoDBConnection: @unchecked Sendable { self.authMechanism = authMechanism self.replicaSet = replicaSet self.extraUriParams = extraUriParams + queue.setSpecific(key: Self.queueKey, value: ObjectIdentifier(self)) + } + + private var isOnQueue: Bool { + DispatchQueue.getSpecific(key: Self.queueKey) == ObjectIdentifier(self) } deinit { @@ -416,7 +424,7 @@ final class MongoDBConnection: @unchecked Sendable { stateLock.unlock() #if canImport(CLibMongoc) - let version = queue.sync { fetchServerVersionSync() } + let version = isOnQueue ? fetchServerVersionSync() : queue.sync { fetchServerVersionSync() } stateLock.lock() _cachedServerVersion = version stateLock.unlock() @@ -1044,9 +1052,14 @@ private extension MongoDBConnection { try checkCancelled() let caps = MongoDBCapabilities.parse(serverVersion()) - let commandJSON = caps.supportsListDatabasesNameOnly - ? "{\"listDatabases\": 1, \"nameOnly\": true}" - : "{\"listDatabases\": 1}" + var fields = ["\"listDatabases\": 1"] + if caps.supportsListDatabasesNameOnly { + fields.append("\"nameOnly\": true") + } + if caps.supportsAuthorizedDatabases { + fields.append("\"authorizedDatabases\": true") + } + let commandJSON = "{\(fields.joined(separator: ", "))}" guard let command = jsonToBson(commandJSON) else { throw MongoDBError(code: 0, message: "Failed to create listDatabases command") } diff --git a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift index 5a96fef39..be8de0885 100644 --- a/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift +++ b/Plugins/MongoDBDriverPlugin/MongoDBPluginDriver.swift @@ -85,8 +85,7 @@ final class MongoDBPluginDriver: PluginDatabaseDriver, @unchecked Sendable { let dbs = try await conn.listDatabases() currentDb = dbs.first { !Self.systemDatabases.contains($0) } ?? dbs.first ?? "" } catch { - conn.disconnect() - throw error + Self.logger.warning("listDatabases failed during connect, continuing without default database: \(error.localizedDescription, privacy: .public)") } } diff --git a/TablePro.xcodeproj/project.pbxproj b/TablePro.xcodeproj/project.pbxproj index 04658e085..598689645 100644 --- a/TablePro.xcodeproj/project.pbxproj +++ b/TablePro.xcodeproj/project.pbxproj @@ -2871,8 +2871,14 @@ ); INFOPLIST_FILE = Plugins/MongoDBDriverPlugin/Info.plist; INFOPLIST_KEY_NSPrincipalClass = "$(PRODUCT_MODULE_NAME).MongoDBPlugin"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Libs"; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/../Frameworks", + "$(PROJECT_DIR)/Libs/dylibs", + ); + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/Libs", + "$(PROJECT_DIR)/Libs/dylibs", + ); MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( @@ -2880,10 +2886,8 @@ "$(PROJECT_DIR)/Libs/libmongoc.a", "-force_load", "$(PROJECT_DIR)/Libs/libbson.a", - "-framework", - Security, - "-framework", - CoreFoundation, + "-lssl.3", + "-lcrypto.3", "-lresolv", "-lz", ); @@ -2913,8 +2917,14 @@ ); INFOPLIST_FILE = Plugins/MongoDBDriverPlugin/Info.plist; INFOPLIST_KEY_NSPrincipalClass = "$(PRODUCT_MODULE_NAME).MongoDBPlugin"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Libs"; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/../Frameworks", + "$(PROJECT_DIR)/Libs/dylibs", + ); + LIBRARY_SEARCH_PATHS = ( + "$(PROJECT_DIR)/Libs", + "$(PROJECT_DIR)/Libs/dylibs", + ); MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( @@ -2922,10 +2932,8 @@ "$(PROJECT_DIR)/Libs/libmongoc.a", "-force_load", "$(PROJECT_DIR)/Libs/libbson.a", - "-framework", - Security, - "-framework", - CoreFoundation, + "-lssl.3", + "-lcrypto.3", "-lresolv", "-lz", ); diff --git a/scripts/build-libmongoc.sh b/scripts/build-libmongoc.sh index e897f4ef7..d4092c39b 100755 --- a/scripts/build-libmongoc.sh +++ b/scripts/build-libmongoc.sh @@ -1,7 +1,6 @@ #!/bin/bash set -eo pipefail -# Run a command silently, showing output only on failure. run_quiet() { local logfile logfile=$(mktemp) @@ -13,17 +12,19 @@ run_quiet() { rm -f "$logfile" } -# Build static libmongoc and libbson for TablePro +# Build static libmongoc + libbson for TablePro # # Produces architecture-specific and universal static libraries in Libs/: # libbson_arm64.a, libbson_x86_64.a, libbson_universal.a # libmongoc_arm64.a, libmongoc_x86_64.a, libmongoc_universal.a # -# Uses macOS SecureTransport (ENABLE_SSL=DARWIN) for TLS so that -# certificate verification uses the system Keychain automatically. -# Note: SecureTransport is deprecated by Apple but still functional on -# macOS 14+. It supports TLS 1.2 (no 1.3). MongoDB Atlas accepts TLS 1.2. -# libmongoc does not support Network.framework as a TLS backend. +# TLS backend: OpenSSL (ENABLE_SSL=OPENSSL). The previous Secure Transport +# build broke TLS handshakes against MongoDB Atlas on macOS 26 with +# errSSLPeerInternalError (-9838). OpenSSL handshakes succeed and TablePro +# already bundles OpenSSL 3 dylibs for Redis/MSSQL/MySQL. +# +# OpenSSL is rebuilt from source for each arch with the correct deployment +# target instead of relying on Homebrew or system OpenSSL. # # All libraries are built with MACOSX_DEPLOYMENT_TARGET=14.0 to match # the app's minimum deployment target. @@ -33,12 +34,13 @@ run_quiet() { # # Prerequisites: # - Xcode Command Line Tools -# - CMake (brew install cmake) -# - curl (for downloading source tarballs) +# - CMake 3.15+ (brew install cmake) +# - curl DEPLOY_TARGET="14.0" MONGOC_VERSION="1.28.1" MONGOC_SHA256="a93259840f461b28e198311e32144f5f8dc9fbd74348029f2793774d781bb7da" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/openssl-version.sh" ARCH="${1:-both}" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -47,7 +49,7 @@ LIBS_DIR="$PROJECT_DIR/Libs" BUILD_DIR="$(mktemp -d)" NCPU=$(sysctl -n hw.ncpu) -echo "🔧 Building static libmongoc $MONGOC_VERSION (SecureTransport)" +echo "🔧 Building static libmongoc $MONGOC_VERSION + OpenSSL $OPENSSL_VERSION" echo " Deployment target: macOS $DEPLOY_TARGET" echo " Architecture: $ARCH" echo " Build dir: $BUILD_DIR" @@ -62,6 +64,12 @@ trap cleanup EXIT download_sources() { echo "📥 Downloading source tarballs..." + if [ ! -f "$BUILD_DIR/openssl-$OPENSSL_VERSION.tar.gz" ]; then + curl -fSL "https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz" \ + -o "$BUILD_DIR/openssl-$OPENSSL_VERSION.tar.gz" + fi + echo "$OPENSSL_SHA256 $BUILD_DIR/openssl-$OPENSSL_VERSION.tar.gz" | shasum -a 256 -c - + if [ ! -f "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION.tar.gz" ]; then curl -fSL "https://github.com/mongodb/mongo-c-driver/releases/download/$MONGOC_VERSION/mongo-c-driver-$MONGOC_VERSION.tar.gz" \ -o "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION.tar.gz" @@ -71,19 +79,54 @@ download_sources() { echo "✅ Sources downloaded" } +build_openssl() { + local arch=$1 + local prefix="$BUILD_DIR/install-openssl-$arch" + + echo "" + echo "🔨 Building OpenSSL $OPENSSL_VERSION for $arch..." + + rm -rf "$BUILD_DIR/openssl-$OPENSSL_VERSION-$arch" + mkdir -p "$BUILD_DIR/openssl-$OPENSSL_VERSION-$arch" + tar xzf "$BUILD_DIR/openssl-$OPENSSL_VERSION.tar.gz" -C "$BUILD_DIR/openssl-$OPENSSL_VERSION-$arch" --strip-components=1 + + cd "$BUILD_DIR/openssl-$OPENSSL_VERSION-$arch" + + local target + if [ "$arch" = "arm64" ]; then + target="darwin64-arm64-cc" + else + target="darwin64-x86_64-cc" + fi + + MACOSX_DEPLOYMENT_TARGET=$DEPLOY_TARGET \ + run_quiet ./Configure \ + "$target" \ + no-shared \ + no-tests \ + no-apps \ + no-docs \ + --prefix="$prefix" \ + -mmacosx-version-min=$DEPLOY_TARGET + + run_quiet make -j"$NCPU" + run_quiet make install_sw + + echo "✅ OpenSSL $arch: $(ls -lh "$prefix/lib/libssl.a" | awk '{print $5}') (libssl) $(ls -lh "$prefix/lib/libcrypto.a" | awk '{print $5}') (libcrypto)" +} + build_mongoc() { local arch=$1 + local openssl_prefix="$BUILD_DIR/install-openssl-$arch" local prefix="$BUILD_DIR/install-mongoc-$arch" echo "" - echo "🔨 Building libmongoc (mongo-c-driver $MONGOC_VERSION) for $arch..." + echo "🔨 Building libmongoc $MONGOC_VERSION for $arch (OpenSSL backend)..." - # Extract fresh copy for this arch rm -rf "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION-$arch" mkdir -p "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION-$arch" tar xzf "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION.tar.gz" -C "$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION-$arch" --strip-components=1 - # Patch deprecated cmake_policy(SET CMP0042 OLD) for CMake 4.x compatibility local src_root="$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION-$arch" sed -i '' 's/cmake_policy (SET CMP0042 OLD)/cmake_policy (SET CMP0042 NEW)/' "$src_root/src/libbson/CMakeLists.txt" 2>/dev/null || true sed -i '' 's/cmake_policy(SET CMP0042 OLD)/cmake_policy(SET CMP0042 NEW)/' "$src_root/src/libbson/CMakeLists.txt" 2>/dev/null || true @@ -92,10 +135,15 @@ build_mongoc() { sed -i '' 's/cmake_policy (SET CMP0042 OLD)/cmake_policy (SET CMP0042 NEW)/' "$src_root/CMakeLists.txt" 2>/dev/null || true sed -i '' 's/cmake_policy(SET CMP0042 OLD)/cmake_policy(SET CMP0042 NEW)/' "$src_root/CMakeLists.txt" 2>/dev/null || true - local build_dir="$BUILD_DIR/mongo-c-driver-$MONGOC_VERSION-$arch/cmake-build" + local build_dir="$src_root/cmake-build" mkdir -p "$build_dir" cd "$build_dir" + local openssl_lib_dir="$openssl_prefix/lib" + if [ -f "$openssl_prefix/lib64/libssl.a" ]; then + openssl_lib_dir="$openssl_prefix/lib64" + fi + run_quiet env MACOSX_DEPLOYMENT_TARGET=$DEPLOY_TARGET \ cmake .. \ -DCMAKE_INSTALL_PREFIX="$prefix" \ @@ -103,6 +151,7 @@ build_mongoc() { -DCMAKE_OSX_ARCHITECTURES="$arch" \ -DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOY_TARGET" \ -DCMAKE_C_FLAGS="-mmacosx-version-min=$DEPLOY_TARGET" \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DENABLE_STATIC=ON \ -DENABLE_SHARED=OFF \ -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF \ @@ -110,9 +159,13 @@ build_mongoc() { -DENABLE_SRV=ON \ -DENABLE_ZLIB=SYSTEM \ -DENABLE_ZSTD=OFF \ - -DENABLE_SSL=DARWIN \ + -DENABLE_SSL=OPENSSL \ -DENABLE_TESTS=OFF \ - -DENABLE_EXAMPLES=OFF + -DENABLE_EXAMPLES=OFF \ + -DOPENSSL_ROOT_DIR="$openssl_prefix" \ + -DOPENSSL_INCLUDE_DIR="$openssl_prefix/include" \ + -DOPENSSL_SSL_LIBRARY="$openssl_lib_dir/libssl.a" \ + -DOPENSSL_CRYPTO_LIBRARY="$openssl_lib_dir/libcrypto.a" run_quiet cmake --build . --parallel "$NCPU" run_quiet cmake --install . @@ -126,7 +179,6 @@ install_libs() { echo "📦 Installing $arch libraries to Libs/..." - # Find the actual lib directory (may be lib/ or lib64/) local lib_dir="$prefix/lib" if [ -f "$prefix/lib64/libmongoc-static-1.0.a" ]; then lib_dir="$prefix/lib64" @@ -143,14 +195,11 @@ install_headers() { echo "📦 Installing libmongoc headers..." - # Find the actual include directory local inc_dir="$prefix/include" - # Install mongoc headers mkdir -p "$dest/mongoc" cp "$inc_dir/libmongoc-1.0/mongoc/"*.h "$dest/mongoc/" - # Install bson headers mkdir -p "$dest/bson" cp "$inc_dir/libbson-1.0/bson/"*.h "$dest/bson/" @@ -173,12 +222,32 @@ create_universal() { build_for_arch() { local arch=$1 + build_openssl "$arch" build_mongoc "$arch" install_libs "$arch" - # Install headers once (they're arch-independent) - if [ ! -f "$PROJECT_DIR/Plugins/MongoDBDriverPlugin/CLibMongoc/include/mongoc/mongoc.h" ]; then - install_headers "$arch" + install_headers "$arch" +} + +verify_tls_backend() { + echo "" + echo "🔍 Verifying TLS backend in built libraries..." + local lib="$LIBS_DIR/libmongoc_arm64.a" + [ -f "$lib" ] || lib="$LIBS_DIR/libmongoc_x86_64.a" + [ -f "$lib" ] || { echo " ⚠️ no libmongoc_*.a found"; return; } + + local symbols + symbols=$(nm "$lib" 2>/dev/null || true) + if echo "$symbols" | grep -q "_SSL_CTX_new"; then + echo " ✅ libmongoc references OpenSSL symbols (SSL_CTX_new)" + else + echo " ❌ libmongoc does NOT reference OpenSSL symbols" + exit 1 + fi + if echo "$symbols" | grep -qE "_SSLHandshake|_SSLCreateContext"; then + echo " ❌ libmongoc still references Secure Transport symbols" + exit 1 fi + echo " ✅ libmongoc has no Secure Transport references" } verify_deployment_target() { @@ -208,7 +277,6 @@ verify_deployment_target() { fi } -# Main mkdir -p "$LIBS_DIR" download_sources @@ -230,6 +298,7 @@ case "$ARCH" in ;; esac +verify_tls_backend verify_deployment_target echo ""