56
56
DEFAULT_SSL_CERT_FILE ,
57
57
DEFAULT_SSL_CA_FILE ,
58
58
DEFAULT_SSL_CIPHERS ,
59
+ DEFAULT_SSL_PASSWORD ,
60
+ DEFAULT_SSL_PASSWORD_FILE ,
59
61
REQUEST_TYPE_OK ,
60
62
REQUEST_TYPE_ERROR ,
61
63
IPROTO_GREETING_SIZE ,
@@ -569,6 +571,8 @@ def __init__(self, host, port,
569
571
ssl_cert_file = DEFAULT_SSL_CERT_FILE ,
570
572
ssl_ca_file = DEFAULT_SSL_CA_FILE ,
571
573
ssl_ciphers = DEFAULT_SSL_CIPHERS ,
574
+ ssl_password = DEFAULT_SSL_PASSWORD ,
575
+ ssl_password_file = DEFAULT_SSL_PASSWORD_FILE ,
572
576
packer_factory = default_packer_factory ,
573
577
unpacker_factory = default_unpacker_factory ):
574
578
"""
@@ -693,6 +697,15 @@ def __init__(self, host, port,
693
697
suites the connection can use.
694
698
:type ssl_ciphers: :obj:`str` or :obj:`None`, optional
695
699
700
+ :param ssl_password: Password for decrypting
701
+ :paramref:`~tarantool.Connection.ssl_key_file`.
702
+ :type ssl_password: :obj:`str` or :obj:`None`, optional
703
+
704
+ :param ssl_password_file: File with password for decrypting
705
+ :paramref:`~tarantool.Connection.ssl_key_file`. Connection
706
+ tries every line from the file as a password.
707
+ :type ssl_password_file: :obj:`str` or :obj:`None`, optional
708
+
696
709
:param packer_factory: Request MessagePack packer factory.
697
710
Supersedes :paramref:`~tarantool.Connection.encoding`. See
698
711
:func:`~tarantool.request.packer_factory` for example of
@@ -754,6 +767,8 @@ def __init__(self, host, port,
754
767
self .ssl_cert_file = ssl_cert_file
755
768
self .ssl_ca_file = ssl_ca_file
756
769
self .ssl_ciphers = ssl_ciphers
770
+ self .ssl_password = ssl_password
771
+ self .ssl_password_file = ssl_password_file
757
772
self ._protocol_version = None
758
773
self ._features = {
759
774
IPROTO_FEATURE_STREAMS : False ,
@@ -884,21 +899,7 @@ def wrap_socket_ssl(self):
884
899
context = ssl .SSLContext (ssl .PROTOCOL_TLSv1_2 )
885
900
886
901
if self .ssl_cert_file :
887
- # If the password argument is not specified and a password is
888
- # required, OpenSSL’s built-in password prompting mechanism
889
- # will be used to interactively prompt the user for a password.
890
- #
891
- # We should disable this behaviour, because a python
892
- # application that uses the connector unlikely assumes
893
- # interaction with a human + a Tarantool implementation does
894
- # not support this at least for now.
895
- def password_raise_error ():
896
- raise SslError ("Password for decrypting the private " +
897
- "key is unsupported" )
898
- context .load_cert_chain (certfile = self .ssl_cert_file ,
899
- keyfile = self .ssl_key_file ,
900
- password = password_raise_error )
901
-
902
+ self ._ssl_load_cert_chain (context )
902
903
if self .ssl_ca_file :
903
904
context .load_verify_locations (cafile = self .ssl_ca_file )
904
905
context .verify_mode = ssl .CERT_REQUIRED
@@ -915,6 +916,60 @@ def password_raise_error():
915
916
except Exception as e :
916
917
raise SslError (e )
917
918
919
+ def _ssl_load_cert_chain (self , context ):
920
+ """
921
+ Decrypt and load SSL certificate and private key files.
922
+ Mimic Tarantool EE approach here: see `SSL commit`_.
923
+
924
+ :param context: SSL context.
925
+ :type context: :obj:`ssl.SSLContext`
926
+
927
+ :raise: :exc:`~tarantool.error.SslError`
928
+
929
+ :meta private:
930
+
931
+ .. _SSL commit: https://github.com/tarantool/tarantool-ee/commit/e1f47dd4adbc6657159c611298aad225883a536b
932
+ """
933
+
934
+ exc_list = []
935
+
936
+ if self .ssl_password is not None :
937
+ try :
938
+ context .load_cert_chain (certfile = self .ssl_cert_file ,
939
+ keyfile = self .ssl_key_file ,
940
+ password = self .ssl_password )
941
+ return
942
+ except Exception as e :
943
+ exc_list .append (e )
944
+
945
+
946
+ if self .ssl_password_file is not None :
947
+ with open (self .ssl_password_file ) as file :
948
+ for line in file :
949
+ try :
950
+ context .load_cert_chain (certfile = self .ssl_cert_file ,
951
+ keyfile = self .ssl_key_file ,
952
+ password = line .rstrip ())
953
+ return
954
+ except Exception as e :
955
+ exc_list .append (e )
956
+
957
+
958
+ try :
959
+ def password_raise_error ():
960
+ raise SslError ("Password prompt for decrypting the private " +
961
+ "key is unsupported, use ssl_password or " +
962
+ "ssl_password_file" )
963
+ context .load_cert_chain (certfile = self .ssl_cert_file ,
964
+ keyfile = self .ssl_key_file ,
965
+ password = password_raise_error )
966
+
967
+ return
968
+ except Exception as e :
969
+ exc_list .append (e )
970
+
971
+ raise SslError (exc_list )
972
+
918
973
def handshake (self ):
919
974
"""
920
975
Process greeting with Tarantool server.
0 commit comments