From ffccf9b705bcc74cffd326e16db8b8184feac9c5 Mon Sep 17 00:00:00 2001 From: deadjakk Date: Tue, 21 Nov 2023 17:43:16 -0700 Subject: [PATCH] Cleaned up/fixed the auto authenticate --- examples/GetUserSPNs.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/examples/GetUserSPNs.py b/examples/GetUserSPNs.py index c88b817d8e..2cb67afa3e 100755 --- a/examples/GetUserSPNs.py +++ b/examples/GetUserSPNs.py @@ -252,7 +252,7 @@ def outputTGS(self, ticket, oldSessionKey, sessionKey, username, spn, fd=None): except Exception as e: logging.error(str(e)) - def get_ldap_connection(self, protocol='ldap'): + def get_ldap_connection(self, protocol='ldap', valid=False): if self.__doKerberos is True: try: ldapConnection = ldap.LDAPConnection('%s://%s' % (protocol, self.__target), self.baseDN, self.__kdcIP) @@ -296,20 +296,28 @@ def get_ldap_connection(self, protocol='ldap'): connection = ldap3.Connection(server, user=ldapUser, password=self.__password, authentication=ldap3.NTLM) if not connection.bind(): - if connection.result['result'] == ldap3.core.results.RESULT_STRONGER_AUTH_REQUIRED and protocol == 'ldaps': - logging.warning('Authentication failed with ldaps, trying channel binding') - self.__ldap_channel_binding = True - self.get_ldap_connection(protocol='ldaps') - return get_ldap_connection() - elif connection.result['result'] == ldap3.core.results.RESULT_STRONGER_AUTH_REQUIRED and protocol == 'ldap': - logging.warning('Authentication failed with ldaps, trying ldaps') - self.get_ldap_connection(protocol='ldaps') - return get_ldap_connection() + if connection.result['result'] == ldap3.core.results.RESULT_INVALID_CREDENTIALS and valid is True\ + and protocol == 'ldaps' and self.__ldap_channel_binding is False: + logging.warning('Authentication failed with LDAPS, trying with channel binding') + self.__ldap_channel_binding = True + return self.get_ldap_connection(protocol='ldaps', valid=valid) + elif connection.result['result'] == ldap3.core.results.RESULT_STRONGER_AUTH_REQUIRED: + if protocol == 'ldaps' and self.__ldap_channel_binding is False: + logging.warning('Authentication failed with LDAPS, trying with channel binding') + self.__ldap_channel_binding = True + return self.get_ldap_connection(protocol='ldaps', valid=valid) + if protocol == 'ldap': + # setting this because we would not have received RESULT_STRONGER_AUTH_REQUIRED + # if the credentials were invalid. This is important because a lack of ldap channel binding + # in an environment that enforces it will often show up as a (misnomer) error RESULT_INVALID_CREDENTIALS + valid = True + logging.warning('Authentication failed with LDAP, trying LDAPS') + return self.get_ldap_connection(protocol='ldaps', valid=valid) else: - raise Exception('Failed to authenticate. Error: %s Code: %d' % (connection.result['message'], connection.result['result'])) + raise Exception('Failed to authenticate. Error: %s' + % ldap3.core.results.RESULT_CODES[connection.result['result']]) logging.info('Successfully authenticated') self.__root = server.info.other['defaultNamingContext'][0] - return connection def run(self):