diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp index 9f7bd4003e62f..a76b253ffd837 100644 --- a/xbmc/interfaces/python/XBPython.cpp +++ b/xbmc/interfaces/python/XBPython.cpp @@ -553,6 +553,34 @@ void XBPython::Process() } } +bool XBPython::CheckCryptographyVersion() +{ + PyObject* cryptoMod{PyImport_ImportModule("cryptography")}; + if (!cryptoMod) + { + return true; + } + + PyObject* cryptoModDict{PyModule_GetDict(cryptoMod)}; + PyObject* versionPyString{PyDict_GetItemString(cryptoModDict, "__version__")}; + std::string version {PyString_AsString(versionPyString)}; + + Py_DECREF(cryptoMod); + + std::vector versionParts{StringUtils::Split(version, '.')}; + + // Python cryptography < 1.7 has issues with pyOpenSSL integration, leading to all sorts + // of weird bugs - check here to save on some troubleshooting + // https://github.com/pyca/pyopenssl/issues/542 + if (versionParts.size() < 2 || std::stoi(versionParts[0]) < 1 || (std::stoi(versionParts[0]) == 1 && std::stoi(versionParts[1]) < 7)) + { + CLog::Log(LOGERROR, "Python cryptography module version {} is too old, at least version 1.7 needed", version); + return false; + } + + return true; +} + bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker) { if (invoker == NULL) @@ -638,7 +666,14 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker) if (!(m_mainThreadState = PyThreadState_Get())) CLog::Log(LOGERROR, "Python threadstate is NULL."); + + bool cryptoOk = CheckCryptographyVersion(); PyEval_ReleaseLock(); + if (!cryptoOk) + { + Finalize(); + return false; + } m_bInitialized = true; } diff --git a/xbmc/interfaces/python/XBPython.h b/xbmc/interfaces/python/XBPython.h index 0c922fb71181e..c0466ce9dc5eb 100644 --- a/xbmc/interfaces/python/XBPython.h +++ b/xbmc/interfaces/python/XBPython.h @@ -102,6 +102,13 @@ class XBPython : void UnloadExtensionLibs(); private: + /** + * Check minimum required version of Python cryptography module + * + * If version is below 1.7, there could be random OpenSSL errors, see + * https://github.com/pyca/pyopenssl/issues/542#issuecomment-312968275 + */ + bool CheckCryptographyVersion(); void Finalize(); CCriticalSection m_critSection;