Author: Edd Barrett <vex...@gmail.com> Branch: Changeset: r79775:7a75425fd561 Date: 2015-09-22 16:55 +0100 http://bitbucket.org/pypy/pypy/changeset/7a75425fd561/
Log: Merged in detect_egd2 (pull request #333) Deal with platforms without RAND_egd(). diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -241,20 +241,26 @@ res = libssl_RAND_status() return space.wrap(res) - @unwrap_spec(path=str) - def RAND_egd(space, path): - """RAND_egd(path) -> bytes + if HAVE_OPENSSL_RAND_EGD: + @unwrap_spec(path=str) + def RAND_egd(space, path): + """RAND_egd(path) -> bytes - Queries the entropy gather daemon (EGD) on socket path. Returns number - of bytes read. Raises socket.sslerror if connection to EGD fails or - if it does provide enough data to seed PRNG.""" - with rffi.scoped_str2charp(path) as socket_path: - bytes = libssl_RAND_egd(socket_path) - if bytes == -1: - raise ssl_error(space, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG") - return space.wrap(bytes) + Queries the entropy gather daemon (EGD) on socket path. Returns number + of bytes read. Raises socket.sslerror if connection to EGD fails or + if it does provide enough data to seed PRNG.""" + with rffi.scoped_str2charp(path) as socket_path: + bytes = libssl_RAND_egd(socket_path) + if bytes == -1: + raise ssl_error(space, + "EGD connection failed or EGD did not return " + "enough data to seed the PRNG") + return space.wrap(bytes) + else: + # Dummy func for platforms missing RAND_egd(). Most likely LibreSSL. + @unwrap_spec(path=str) + def RAND_egd(space, path): + raise ssl_error(space, "RAND_egd unavailable") class _SSLSocket(W_Root): diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -36,7 +36,8 @@ assert isinstance(_ssl.OPENSSL_VERSION_INFO, tuple) assert len(_ssl.OPENSSL_VERSION_INFO) == 5 assert isinstance(_ssl.OPENSSL_VERSION, str) - assert 'openssl' in _ssl.OPENSSL_VERSION.lower() + lower_version = _ssl.OPENSSL_VERSION.lower() + assert 'openssl' in lower_version or "libressl" in lower_version assert isinstance(_ssl.ALERT_DESCRIPTION_ACCESS_DENIED, int) @@ -69,8 +70,9 @@ def test_sslwrap(self): import _ssl, _socket, sys, gc - if sys.platform == 'darwin' or 'freebsd' in sys.platform: - skip("hangs indefinitely on OSX & FreeBSD (also on CPython)") + if sys.platform == 'darwin' or 'freebsd' in sys.platform or \ + 'openbsd' in sys.platform: + skip("hangs indefinitely on OSX & BSD (also on CPython)") s = _socket.socket() if sys.version_info < (2, 7, 9): ss = _ssl.sslwrap(s, 0) diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -264,6 +264,9 @@ OPENSSL_NO_ECDH = True HAS_ALPN = OPENSSL_VERSION_NUMBER >= 0x1000200fL and not OPENSSL_NO_TLSEXT +HAVE_OPENSSL_RAND_EGD = rffi_platform.has('RAND_egd("/")', + '#include <openssl/rand.h>', + libraries=['ssl', 'crypto']) def external(name, argtypes, restype, **kw): kw['compilation_info'] = eci @@ -288,7 +291,8 @@ if HAVE_OPENSSL_RAND: ssl_external('RAND_add', [rffi.CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void) ssl_external('RAND_status', [], rffi.INT) - ssl_external('RAND_egd', [rffi.CCHARP], rffi.INT) + if HAVE_OPENSSL_RAND_EGD: + ssl_external('RAND_egd', [rffi.CCHARP], rffi.INT) ssl_external('SSL_CTX_new', [SSL_METHOD], SSL_CTX) ssl_external('SSL_get_SSL_CTX', [SSL], SSL_CTX) ssl_external('SSL_set_SSL_CTX', [SSL, SSL_CTX], SSL_CTX) diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -17,12 +17,15 @@ # # Helpers for simple cases -def eci_from_header(c_header_source, include_dirs=None): +def eci_from_header(c_header_source, include_dirs=None, libraries=None): if include_dirs is None: include_dirs = [] + if libraries is None: + libraries = [] return ExternalCompilationInfo( post_include_bits=[c_header_source], - include_dirs=include_dirs + include_dirs=include_dirs, + libraries=libraries, ) def getstruct(name, c_header_source, interesting_fields): @@ -75,9 +78,10 @@ CConfig._compilation_info_.includes = includes return configure(CConfig)['RESULT'] -def has(name, c_header_source, include_dirs=None): +def has(name, c_header_source, include_dirs=None, libraries=None): class CConfig: - _compilation_info_ = eci_from_header(c_header_source, include_dirs) + _compilation_info_ = \ + eci_from_header(c_header_source, include_dirs, libraries) HAS = Has(name) return configure(CConfig)['HAS'] diff --git a/rpython/rtyper/tool/test/test_rffi_platform.py b/rpython/rtyper/tool/test/test_rffi_platform.py --- a/rpython/rtyper/tool/test/test_rffi_platform.py +++ b/rpython/rtyper/tool/test/test_rffi_platform.py @@ -270,12 +270,34 @@ [("d_name", lltype.FixedSizeArray(rffi.CHAR, 1))]) assert dirent.c_d_name.length == 32 -def test_has(): +def test_has_0001(): assert rffi_platform.has("x", "int x = 3;") assert not rffi_platform.has("x", "") # has() should also not crash if it is given an invalid #include assert not rffi_platform.has("x", "#include <some/path/which/cannot/exist>") +def test_has_0002(): + assert rffi_platform.has("pow", "#include <math.h>", libraries=["m"]) + +def test_has_0003(): + """multiple libraries""" + assert rffi_platform.has("pow", "#include <math.h>", libraries=["m", "c"]) + +def test_has_0004(): + """bogus symbol name""" + assert not rffi_platform.has("pow", "#include <math.h>", + libraries=["boguslibname"]) + +def test_has_0005(): + """bogus symbol name and lib name""" + assert not rffi_platform.has("bogus_symbol_name", "#include <math.h>", + libraries=["boguslibname"]) + +def test_has_0006(): + """missing include""" + assert not rffi_platform.has("pow", "", libraries=["m"]) + + def test_verify_eci(): eci = ExternalCompilationInfo() rffi_platform.verify_eci(eci) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit