diff --git a/src/core/IronPython.Modules/_ssl.cs b/src/core/IronPython.Modules/_ssl.cs index 8887134dd..7717c4068 100644 --- a/src/core/IronPython.Modules/_ssl.cs +++ b/src/core/IronPython.Modules/_ssl.cs @@ -70,8 +70,9 @@ public static class PythonSsl { public const string __doc__ = "Implementation module for SSL socket operations. See the socket module\nfor documentation."; public const int OPENSSL_VERSION_NUMBER = 9437184; public static readonly PythonTuple OPENSSL_VERSION_INFO = PythonTuple.MakeTuple(0, 0, 0, 0, 0); - public static readonly object _OPENSSL_API_VERSION = OPENSSL_VERSION_INFO; + public static readonly PythonTuple _OPENSSL_API_VERSION = OPENSSL_VERSION_INFO; public const string OPENSSL_VERSION = "OpenSSL 0.0.0 (.NET SSL)"; + public const string _DEFAULT_CIPHERS = "DEFAULT"; private static readonly List _asn1Objects = new List(); @@ -90,6 +91,7 @@ public static void PerformModuleReload(PythonContext/*!*/ context, PythonDiction context.EnsureModuleException("SSLSyscallError", sslError, dict, "SSLSyscallError", "ssl"); context.EnsureModuleException("SSLEOFError", sslError, dict, "SSLEOFError", "ssl"); context.EnsureModuleException("SSLWantReadError", sslError, dict, "SSLWantReadError", "ssl"); + context.EnsureModuleException("SSLCertVerificationError", [sslError, PythonExceptions.ValueError], typeof(PythonExceptions._OSError), dict, "SSLCertVerificationError", "ssl"); } #region Stubs for RAND functions @@ -116,7 +118,6 @@ public class _SSLContext { internal readonly X509Certificate2Collection _cert_store = new X509Certificate2Collection(); internal string _cafile; internal X509Certificate2 _cert; - private int _verify_mode = SSL_VERIFY_NONE; public _SSLContext(CodeContext context, int protocol) { if (protocol != PROTOCOL_SSLv2 && protocol != PROTOCOL_SSLv23 && protocol != PROTOCOL_SSLv3 && @@ -148,44 +149,39 @@ public void _set_npn_protocols(CodeContext context, IBufferProtocol protos) { // TODO } - public int options { - get; set; - } + public bool post_handshake_auth { get; set; } // TODO + + public int options { get; set; } public int verify_mode { - get { - return _verify_mode; - } + get; set { - if (_verify_mode != CERT_NONE && _verify_mode != CERT_OPTIONAL && _verify_mode != CERT_REQUIRED) { + if (value != CERT_NONE && value != CERT_OPTIONAL && value != CERT_REQUIRED) { throw PythonOps.ValueError("invalid value for verify_mode"); } // TODO: change this in 3.7 if (check_hostname && value == CERT_NONE) { throw PythonOps.ValueError("Cannot set verify_mode to CERT_NONE when check_hostname is enabled."); } - _verify_mode = value; + field = value; } - } + } = SSL_VERIFY_NONE; - public int protocol { - get; set; - } + public int protocol { get; set; } - private bool _check_hostname; public bool check_hostname { - get => _check_hostname; + get; set { // TODO: change this in 3.7 - if (value && _verify_mode != CERT_OPTIONAL && _verify_mode != CERT_REQUIRED) { + if (value && verify_mode != CERT_OPTIONAL && verify_mode != CERT_REQUIRED) { throw PythonOps.ValueError("check_hostname needs a SSL context with either CERT_OPTIONAL or CERT_REQUIRED"); } - _check_hostname = value; + field = value; } } public void set_default_verify_paths(CodeContext context) { - + // TODO } public void set_ecdh_curve(CodeContext context, [NotNone] string curve) { @@ -268,7 +264,8 @@ public void load_verify_locations(CodeContext context, object cafile = null, str } } - public object _wrap_socket(CodeContext context, PythonSocket.socket sock, bool server_side, string server_hostname = null) { + public object _wrap_socket(CodeContext context, PythonSocket.socket sock, bool server_side, string server_hostname = null, object owner = null, object session = null) { + // TODO: owner and session return new _SSLSocket(context, this, sock, server_side, server_hostname); } } @@ -1277,6 +1274,14 @@ private static Exception ErrorDecoding(CodeContext context, params object[] args public const int PROTOCOL_TLS_CLIENT = 16; public const int PROTOCOL_TLS_SERVER = 17; + public const int PROTO_MINIMUM_SUPPORTED = -2; + public const int PROTO_MAXIMUM_SUPPORTED = -1; + public const int PROTO_SSLv3 = 768; + public const int PROTO_TLSv1 = 769; + public const int PROTO_TLSv1_1 = 770; + public const int PROTO_TLSv1_2 = 771; + public const int PROTO_TLSv1_3 = 772; + public const int OP_ALL = unchecked((int)0x800003FF); public const int OP_CIPHER_SERVER_PREFERENCE = 0; // 0x400000; public const int OP_SINGLE_DH_USE = 0; // 0x100000; @@ -1314,6 +1319,12 @@ private static Exception ErrorDecoding(CodeContext context, params object[] args public const bool HAS_TLS_UNIQUE = false; public const bool HAS_TLSv1_3 = false; + public const bool HAS_SSLv2 = false; + public const bool HAS_SSLv3 = false; + public const bool HAS_TLSv1 = true; + public const bool HAS_TLSv1_1 = true; + public const bool HAS_TLSv1_2 = true; + private const int SSL_VERIFY_NONE = 0x00; private const int SSL_VERIFY_PEER = 0x01; private const int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02; diff --git a/src/core/IronPython/Modules/Builtin.cs b/src/core/IronPython/Modules/Builtin.cs index 833119b73..3ca0efeae 100644 --- a/src/core/IronPython/Modules/Builtin.cs +++ b/src/core/IronPython/Modules/Builtin.cs @@ -228,7 +228,12 @@ public static object compile(CodeContext/*!*/ context, [NotNone] string source, var sourceCodeKind = ValidateCompileMode(mode); if (source.Contains('\0')) { - throw PythonOps.TypeError("compile() expected string without null bytes"); +#if PYTHON_34 + throw PythonOps.TypeError("source code string cannot contain null bytes"); +#else + // TODO: SyntaxError in 3.11 + throw PythonOps.ValueError("source code string cannot contain null bytes"); +#endif } var sourceUnit = context.LanguageContext.CreateSnippet(source, sfilename, sourceCodeKind); diff --git a/tests/suite/stdlib/test_ssl.py b/tests/suite/stdlib/test_ssl.py index 317007d04..1ecce6738 100644 --- a/tests/suite/stdlib/test_ssl.py +++ b/tests/suite/stdlib/test_ssl.py @@ -35,7 +35,6 @@ def load_tests(loader, standard_tests, pattern): test.test_ssl.ContextTests('test_session_stats'), # AttributeError: 'SSLContext' object has no attribute 'session_stats' test.test_ssl.ContextTests('test_sni_callback'), # AttributeError: 'SSLContext' object has no attribute 'set_servername_callback' test.test_ssl.ContextTests('test_sni_callback_refcycle'), # AttributeError: 'SSLContext' object has no attribute 'set_servername_callback' - test.test_ssl.ContextTests('test_verify_mode'), # AssertionError: ValueError not raised test.test_ssl.SSLErrorTests('test_lib_reason'), # AttributeError: 'SSLContext' object has no attribute 'load_dh_params' test.test_ssl.SSLErrorTests('test_str'), # AssertionError: '[Errno 1] foo' != 'foo' test.test_ssl.ThreadedTests('test_dh_params'), # AttributeError: 'SSLContext' object has no attribute 'load_dh_params' diff --git a/tests/suite/test_ast.py b/tests/suite/test_ast.py index f9c98e08c..e49d655f7 100644 --- a/tests/suite/test_ast.py +++ b/tests/suite/test_ast.py @@ -1323,7 +1323,11 @@ def test_literal_eval_issue4907(self): self.assertEqual(ast.literal_eval('2j'), 2j) self.assertEqual(ast.literal_eval('10 + 2j'), 10 + 2j) self.assertEqual(ast.literal_eval('1.5 - 2j'), 1.5 - 2j) - self.assertEqual(ast.literal_eval('2 + (3 + 4j)'), 5 + 4j) + if sys.version_info >= (3, 7): + with self.assertRaises(ValueError): + ast.literal_eval('2 + (3 + 4j)') + else: + self.assertEqual(ast.literal_eval('2 + (3 + 4j)'), 5 + 4j) def test_literal_eval_cp35572(self): self.assertEqual(ast.literal_eval('-1'), -1) diff --git a/tests/suite/test_builtinfunc.py b/tests/suite/test_builtinfunc.py index ba179ffb9..b8eb00993 100644 --- a/tests/suite/test_builtinfunc.py +++ b/tests/suite/test_builtinfunc.py @@ -741,7 +741,7 @@ def write(self, data): sys.stdout = sys.__stdout__ for code in ["abc" + chr(0) + "def", chr(0) + "def", "def" + chr(0)]: - self.assertRaises(TypeError, compile, code, 'f', 'exec') + self.assertRaises(SyntaxError if sys.version_info >= (3, 11) else ValueError if sys.version_info >= (3, 5) else TypeError, compile, code, 'f', 'exec') def test_str_none(self): class foo(object): diff --git a/tests/suite/test_isinstance.py b/tests/suite/test_isinstance.py index 8f5170aa7..b656808b0 100644 --- a/tests/suite/test_isinstance.py +++ b/tests/suite/test_isinstance.py @@ -352,7 +352,7 @@ def test_kwargs_open(self): os.unlink(fname) def test_kwargs_primitives(self): - if sys.version_info >= (3,7): + if not is_cli and sys.version_info >= (3,7): # TODO: positional-only args (3.7) # starting with 3.7 these are no longer valid keyword arguments with self.assertRaises(TypeError): int(x=1) with self.assertRaises(TypeError): float(x=2)