diff --git a/changelog/57787.fixed b/changelog/57787.fixed new file mode 100644 index 000000000000..ebb11c3a26ad --- /dev/null +++ b/changelog/57787.fixed @@ -0,0 +1 @@ +Adds a fix so salt can run on the latest macOS version Big Sur. diff --git a/salt/utils/rsax931.py b/salt/utils/rsax931.py index c60ef6ba0ed3..7fa979bd8532 100644 --- a/salt/utils/rsax931.py +++ b/salt/utils/rsax931.py @@ -9,6 +9,7 @@ import ctypes.util import glob import os +import platform import sys # Import 3rd-party libs @@ -29,7 +30,25 @@ def _find_libcrypto(): Find the path (or return the short name) of libcrypto. """ if sys.platform.startswith("win"): - lib = str("libeay32") + lib = "libeay32" + elif salt.utils.platform.is_darwin(): + # will look for several different location on the system, + # Search in the following order. salts pkg, homebrew, macports, finnally + # system. + # look in salts pkg install location. + lib = glob.glob("/opt/salt/lib/libcrypto.dylib") + # Find library symlinks in Homebrew locations. + lib = lib or glob.glob("/usr/local/opt/openssl/lib/libcrypto.dylib") + lib = lib or glob.glob("/usr/local/opt/openssl@*/lib/libcrypto.dylib") + # look in macports. + lib = lib or glob.glob("/opt/local/lib/libcrypto.dylib") + # check if 10.15, regular libcrypto.dylib is just a false pointer. + if platform.mac_ver()[0].split(".")[:2] == ["10", "15"]: + lib = lib or glob.glob("/usr/lib/libcrypto.*.dylib") + lib = list(reversed(sorted(lib))) + # last but not least all the other macOS versions should work here. + # including Big Sur. + lib = lib[0] if lib else "/usr/lib/libcrypto.dylib" elif getattr(sys, "frozen", False) and salt.utils.platform.is_smartos(): lib = glob.glob(os.path.join(os.path.dirname(sys.executable), "libcrypto.so*")) lib = lib[0] if lib else None @@ -53,18 +72,6 @@ def _find_libcrypto(): else: lib = glob.glob("/opt/freeware/lib/libcrypto.so*") lib = lib[0] if lib else None - elif salt.utils.platform.is_darwin(): - # Find versioned libraries in system locations, being careful - # to avoid the unversioned stub which is no longer permitted. - lib = glob.glob("/usr/lib/libcrypto.*.dylib") - if lib: - # Sort so as to prefer the newest version. - lib = list(reversed(sorted(lib))) - else: - # Find library symlinks in Homebrew locations. - lib = glob.glob("/usr/local/opt/openssl/lib/libcrypto.dylib") - lib = lib or glob.glob("/usr/local/opt/openssl@*/lib/libcrypto.dylib") - lib = lib[0] if lib else None if not lib: raise OSError("Cannot locate OpenSSL libcrypto") return lib diff --git a/tests/unit/utils/test_rsax931.py b/tests/unit/utils/test_rsax931.py index 85d5e4e32f7d..311d3d6694e4 100644 --- a/tests/unit/utils/test_rsax931.py +++ b/tests/unit/utils/test_rsax931.py @@ -11,6 +11,7 @@ import fnmatch import glob import os +import platform import sys import salt.utils.platform @@ -174,16 +175,43 @@ def test_find_libcrypto_aix(self): ) @skipIf(not salt.utils.platform.is_darwin(), "Host OS is not Darwin-like or macOS.") - def test_find_libcrypto_darwin(self): + @patch.object(platform, "mac_ver", lambda: ("10.14.2", (), "")) + @patch.object(glob, "glob", lambda _: []) + def test_find_libcrypto_with_system_and_not_catalina(self): """ - Test _find_libcrypto on a Darwin-like or macOS host. + Test _find_libcrypto on a Catalina-like macOS host, simulate + not finding any other libcryptos and just defaulting to system. """ lib_path = _find_libcrypto() passed = False for i in ( + "/opt/salt/lib/libcrypto.dylib", + "/usr/local/opt/openssl/lib/libcrypto.dylib", + "/usr/local/opt/openssl@*/lib/libcrypto.dylib", + "/opt/local/lib/libcrypto.dylib", "/usr/lib/libcrypto.*.dylib", + ): + if fnmatch.fnmatch(lib_path, i): + passed = True + break + self.assertFalse(passed) + self.assertEqual(lib_path, "/usr/lib/libcrypto.dylib") + + @skipIf(not salt.utils.platform.is_darwin(), "Host OS is not Darwin-like or macOS.") + @patch.object(platform, "mac_ver", lambda: ("10.15.2", (), "")) + def test_find_libcrypto_darwin_catalina(self): + """ + Test _find_libcrypto on a Darwin-like macOS host where there isn't a + lacation returned by ctypes.util.find_library() + """ + lib_path = _find_libcrypto() + passed = False + for i in ( + "/opt/salt/lib/libcrypto.dylib", "/usr/local/opt/openssl/lib/libcrypto.dylib", "/usr/local/opt/openssl@*/lib/libcrypto.dylib", + "/opt/local/lib/libcrypto.dylib", + "/usr/lib/libcrypto.*.dylib", ): if fnmatch.fnmatch(lib_path, i): passed = True @@ -193,6 +221,7 @@ def test_find_libcrypto_darwin(self): @patch.object(ctypes.util, "find_library", lambda a: None) @patch.object(glob, "glob", lambda a: []) @patch.object(sys, "platform", "unknown") + @patch.object(salt.utils.platform, "is_darwin", lambda: False) def test_find_libcrypto_unsupported(self): """ Ensure that _find_libcrypto works correctly on an unsupported host OS.