Improve OpenSSL library version detection #938

Closed
wfr wants to merge 2 commits from v0.6-openssl-compat-signed into v0.6
4 changed files with 80 additions and 7 deletions
Showing only changes of commit 0054b3cac5 - Show all commits

View File

@ -13,7 +13,7 @@ installed on your system.
Here's a list of dependencies needed for PyBitmessage
- python2.7
- python2-qt4 (python-qt4 on Debian/Ubuntu)
- openssl
- openssl 1.0
- (Fedora & Redhat only) openssl-compat-bitcoin-libs
##Running PyBitmessage

View File

@ -99,10 +99,10 @@ def check_openssl():
import re
if re.match(r'linux|darwin|freebsd', sys.platform):
try:
import ctypes.util
path = ctypes.util.find_library('ssl')
from pyelliptic.find_library_version import find_library_version
path = find_library_version('ssl', '1.0')
if path not in paths:
paths.append(path)
paths.insert(0, path)
except:
pass

View File

@ -0,0 +1,73 @@
#!/usr/bin/python2.7
# This function mimicks ctypes.util.find_library()
# but allows you to specify a desired library version.
# (c) 2017 Wolfgang Frisch
# based on https://github.com/python/cpython/blob/2.7/Lib/ctypes/util.py
import ctypes.util
import os
import re
import subprocess
import sys
def find_library_version(name, version=None):
"""
Try to find the desired version of a library, and return a pathname.
Fall back to ctypes.util.find_library() on platforms other than POSIX.
:param name: The library name without any prefix like lib,
suffix like .so, .dylib or version number.
:param version: The library version.
:return: Returns the filename or, if no library can be found, None.
"""
def _num_version(libname):
# "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
parts = libname.split(b".")
nums = []
try:
while parts:
nums.insert(0, int(parts.pop()))
except ValueError:
pass
return nums or [sys.maxint]
if "linux" in sys.platform:
ename = re.escape(name)
expr = r'lib%s\.so[.0-9]*.*? => \S*/(lib%s\.so[.0-9]*)' % (ename, ename)
null = open(os.devnull, 'wb')
try:
with null:
proc = subprocess.Popen(('/sbin/ldconfig', '-p'),
stdout=subprocess.PIPE,
stderr=null)
except OSError: # E.g. command not found
data = b''
else:
[data, _] = proc.communicate()
res = re.findall(expr, data)
if not res:
return None
res.sort(key=_num_version)
if version:
lst = filter(lambda x: x.split("so.")[-1].startswith(version), res)
if len(lst):
return lst[-1]
return res[-1]
else:
# fallback (unversioned)
return ctypes.util.find_library(name)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("example: %s crypto 1.0" % sys.argv[0])
else:
name = sys.argv[1]
version = sys.argv[2] if len(sys.argv) == 3 else None
print(find_library_version(name, version))
# vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap:

View File

@ -430,7 +430,7 @@ class _OpenSSL:
def loadOpenSSL():
global OpenSSL
from os import path, environ
from ctypes.util import find_library
from find_library_version import find_library_version
libdir = []
if getattr(sys,'frozen', None):
@ -456,7 +456,7 @@ def loadOpenSSL():
libdir.append('libcrypto.so')
libdir.append('libssl.so')
if 'linux' in sys.platform or 'darwin' in sys.platform or 'freebsd' in sys.platform:
libdir.append(find_library('ssl'))
libdir.append(find_library_version('ssl', '1.0'))
elif 'win32' in sys.platform or 'win64' in sys.platform:
libdir.append(find_library('libeay32'))
for library in libdir:
@ -467,4 +467,4 @@ def loadOpenSSL():
pass
raise Exception("Couldn't find and load the OpenSSL library. You must install it.")
loadOpenSSL()
loadOpenSSL()