diff --git a/python3/smb/SMBConnection.py b/python3/smb/SMBConnection.py index 99d5ada..91f5b72 100644 --- a/python3/smb/SMBConnection.py +++ b/python3/smb/SMBConnection.py @@ -28,6 +28,7 @@ def __init__(self, username, password, my_name, remote_name, domain = '', use_nt Create a new SMBConnection instance. *username* and *password* are the user credentials required to authenticate the underlying SMB connection with the remote server. + *password* can be a string or a callable returning a string. File operations can only be proceeded after the connection has been authenticated successfully. Note that you need to call *connect* method to actually establish the SMB connection to the remote server and perform authentication. diff --git a/python3/smb/base.py b/python3/smb/base.py index e9dd621..f8268d5 100644 --- a/python3/smb/base.py +++ b/python3/smb/base.py @@ -58,7 +58,7 @@ class SMB(NMBSession): def __init__(self, username, password, my_name, remote_name, domain = '', use_ntlm_v2 = True, sign_options = SIGN_WHEN_REQUIRED, is_direct_tcp = False, smb_support_mask = SMB_SUPPORT_DEFAULTS): NMBSession.__init__(self, my_name, remote_name, is_direct_tcp = is_direct_tcp) self.username = username - self.password = password + self._password = password self.domain = domain self.sign_options = sign_options self.is_direct_tcp = is_direct_tcp @@ -112,7 +112,11 @@ def __init__(self, username, password, my_name, remote_name, domain = '', use_nt (self.use_ntlm_v2 and 'v2') or 'v1', (SUPPORT_EXTENDED_SECURITY and 'with') or 'without') - + @property + def password(self): + if callable(self._password): + return self._password() + return self._password # # NMBSession Methods # diff --git a/python3/tests/DirectSMBConnectionTests/test_auth.py b/python3/tests/DirectSMBConnectionTests/test_auth.py index 5b63a9c..29319a6 100644 --- a/python3/tests/DirectSMBConnectionTests/test_auth.py +++ b/python3/tests/DirectSMBConnectionTests/test_auth.py @@ -29,6 +29,20 @@ def test_NTLMv1_auth_SMB1(): conn3 = SMBConnection('INVALIDUSER', 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True) assert not conn3.connect(info['server_ip'], info['server_port']) +@with_setup(teardown = teardown_func) +def test_NTLMv1_auth_SMB1_callable_password(): + global conn, conn2, conn3 + smb_structs.SUPPORT_SMB2 = False + info = getConnectionInfo() + conn = SMBConnection(info['user'], lambda: info['password'], info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True) + assert conn.connect(info['server_ip'], info['server_port']) + + conn2 = SMBConnection(info['user'], lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True) + assert not conn2.connect(info['server_ip'], info['server_port']) + + conn3 = SMBConnection('INVALIDUSER', lambda: 'wrongPass', info['client_name'], info['server_name'], use_ntlm_v2 = False, is_direct_tcp = True) + assert not conn3.connect(info['server_ip'], info['server_port']) + @with_setup(teardown = teardown_func) def test_NTLMv2_auth_SMB1(): global conn