17 | 17 |
from asysocks.unicomm.common.target import UniProto
|
18 | 18 |
from msldap.commons.exceptions import LDAPBindException, LDAPAddException, LDAPModifyException, LDAPDeleteException
|
19 | 19 |
from hashlib import sha256
|
20 | |
from minikerberos.gssapi.channelbindings import ChannelBindingsStruct
|
21 | 20 |
from asysocks.unicomm.client import UniClient
|
22 | 21 |
from asyauth.common.constants import asyauthProtocol
|
23 | 22 |
from asyauth.common.credentials import UniCredential
|
|
23 |
from asyauth.common.winapi.constants import ISC_REQ
|
24 | 24 |
|
25 | 25 |
class MSLDAPClientConnection:
|
26 | 26 |
def __init__(self, target:MSLDAPTarget, credential:UniCredential, auth=None):
|
|
33 | 33 |
|
34 | 34 |
self.connected = False
|
35 | 35 |
self.bind_ok = False
|
|
36 |
self.is_anon = False
|
36 | 37 |
self.__sign_messages = False
|
37 | 38 |
self.__encrypt_messages = False
|
38 | 39 |
self.network = None
|
|
180 | 181 |
# now processing channel binding options
|
181 | 182 |
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
|
182 | 183 |
certdata = self.network.get_peer_certificate()
|
183 | |
cb_struct = ChannelBindingsStruct()
|
184 | |
cb_struct.application_data = b'tls-server-end-point:' + sha256(certdata).digest()
|
185 | |
|
186 | |
self.cb_data = cb_struct.to_bytes()
|
|
184 |
self.cb_data = b'tls-server-end-point:' + sha256(certdata).digest()
|
187 | 185 |
|
188 | 186 |
self.handle_incoming_task = asyncio.create_task(self.__handle_incoming())
|
189 | 187 |
logger.debug('Connection succsessful!')
|
|
233 | 231 |
logger.debug('BIND in progress...')
|
234 | 232 |
try:
|
235 | 233 |
if self.credential.protocol == asyauthProtocol.SICILY:
|
236 | |
|
237 | |
data, to_continue, err = await self.auth.authenticate(None, spn=self.target.to_target_string())
|
|
234 |
flags = ISC_REQ.CONNECTION|ISC_REQ.CONFIDENTIALITY|ISC_REQ.INTEGRITY
|
|
235 |
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
|
|
236 |
flags = ISC_REQ.CONNECTION
|
|
237 |
data, to_continue, err = await self.auth.authenticate(None, spn=self.target.to_target_string(), flags=flags, cb_data = self.cb_data)
|
238 | 238 |
if err is not None:
|
239 | 239 |
return None, err
|
240 | 240 |
|
|
288 | 288 |
res['protocolOp']['diagnosticMessage']
|
289 | 289 |
)
|
290 | 290 |
|
291 | |
data, to_continue, err = await self.auth.authenticate(res['protocolOp']['matchedDN'], spn=self.target.to_target_string())
|
|
291 |
data, to_continue, err = await self.auth.authenticate(res['protocolOp']['matchedDN'], spn=self.target.to_target_string(), cb_data = self.cb_data)
|
292 | 292 |
if err is not None:
|
293 | 293 |
return None, err
|
294 | 294 |
|
|
329 | 329 |
user = b''
|
330 | 330 |
if self.auth.username != None:
|
331 | 331 |
user = self.auth.username.encode()
|
332 | |
|
|
332 |
if user == b'':
|
|
333 |
self.is_anon = True
|
|
334 |
|
333 | 335 |
auth = {
|
334 | 336 |
'simple' : pw
|
335 | 337 |
}
|
|
363 | 365 |
challenge = None
|
364 | 366 |
while True:
|
365 | 367 |
try:
|
366 | |
data, to_continue, err = await self.auth.authenticate(challenge, cb_data = self.cb_data, spn=self.target.to_target_string())
|
|
368 |
flags = ISC_REQ.CONNECTION|ISC_REQ.CONFIDENTIALITY|ISC_REQ.INTEGRITY
|
|
369 |
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
|
|
370 |
flags = ISC_REQ.CONNECTION
|
|
371 |
|
|
372 |
data, to_continue, err = await self.auth.authenticate(challenge, cb_data = self.cb_data, spn=self.target.to_target_string(), flags=flags)
|
367 | 373 |
if err is not None:
|
368 | 374 |
raise err
|
369 | 375 |
except Exception as e:
|
|
394 | 400 |
res = res.native
|
395 | 401 |
if res['protocolOp']['resultCode'] == 'success':
|
396 | 402 |
if 'serverSaslCreds' in res['protocolOp']:
|
397 | |
data, _, err = await self.auth.authenticate(res['protocolOp']['serverSaslCreds'], cb_data = self.cb_data, spn=self.target.to_target_string())
|
|
403 |
data, _, err = await self.auth.authenticate(res['protocolOp']['serverSaslCreds'], cb_data = self.cb_data, spn=self.target.to_target_string(), flags=flags)
|
398 | 404 |
if err is not None:
|
399 | 405 |
return False, err
|
400 | 406 |
|
401 | |
self.encryption_sequence_counter = self.auth.get_seq_number()
|
|
407 |
if self.auth.encryption_needed() is True or self.auth.signing_needed() is True:
|
|
408 |
self.encryption_sequence_counter = self.auth.get_seq_number()
|
402 | 409 |
self.__bind_success()
|
403 | 410 |
|
404 | 411 |
return True, None
|
|
772 | 779 |
#print('res')
|
773 | 780 |
#print(res)
|
774 | 781 |
return convert_attributes(res.native['protocolOp']['attributes']), None
|
775 | |
|
776 | |
|
777 | |
|
778 | |
|
779 | |
|
780 | |
|
781 | |
|
782 | |
|
783 | |
⏎
|