5656 DEFAULT_SSL_CERT_FILE ,
5757 DEFAULT_SSL_CA_FILE ,
5858 DEFAULT_SSL_CIPHERS ,
59+ DEFAULT_SSL_PASSWORD ,
60+ DEFAULT_SSL_PASSWORD_FILE ,
5961 REQUEST_TYPE_OK ,
6062 REQUEST_TYPE_ERROR ,
6163 IPROTO_GREETING_SIZE ,
@@ -569,6 +571,8 @@ def __init__(self, host, port,
569571 ssl_cert_file = DEFAULT_SSL_CERT_FILE ,
570572 ssl_ca_file = DEFAULT_SSL_CA_FILE ,
571573 ssl_ciphers = DEFAULT_SSL_CIPHERS ,
574+ ssl_password = DEFAULT_SSL_PASSWORD ,
575+ ssl_password_file = DEFAULT_SSL_PASSWORD_FILE ,
572576 packer_factory = default_packer_factory ,
573577 unpacker_factory = default_unpacker_factory ):
574578 """
@@ -693,6 +697,15 @@ def __init__(self, host, port,
693697 suites the connection can use.
694698 :type ssl_ciphers: :obj:`str` or :obj:`None`, optional
695699
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+
696709 :param packer_factory: Request MessagePack packer factory.
697710 Supersedes :paramref:`~tarantool.Connection.encoding`. See
698711 :func:`~tarantool.request.packer_factory` for example of
@@ -754,6 +767,8 @@ def __init__(self, host, port,
754767 self .ssl_cert_file = ssl_cert_file
755768 self .ssl_ca_file = ssl_ca_file
756769 self .ssl_ciphers = ssl_ciphers
770+ self .ssl_password = ssl_password
771+ self .ssl_password_file = ssl_password_file
757772 self ._protocol_version = None
758773 self ._features = {
759774 IPROTO_FEATURE_STREAMS : False ,
@@ -884,21 +899,7 @@ def wrap_socket_ssl(self):
884899 context = ssl .SSLContext (ssl .PROTOCOL_TLSv1_2 )
885900
886901 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 )
902903 if self .ssl_ca_file :
903904 context .load_verify_locations (cafile = self .ssl_ca_file )
904905 context .verify_mode = ssl .CERT_REQUIRED
@@ -915,6 +916,60 @@ def password_raise_error():
915916 except Exception as e :
916917 raise SslError (e )
917918
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+
918973 def handshake (self ):
919974 """
920975 Process greeting with Tarantool server.
0 commit comments