o
    js                     @   sR  d dl Z d dlmZmZ d dlZd dlmZ d dlmZ ddl	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d d	lm Z m!Z!m"Z"m#Z# d d
l$m%Z%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z: d dl;m<Z< G dd dZ=dS )    N)ListDict)logger)MSLDAPClientStatus   )MSLDAPTarget)LDAPMessageBindRequest
protocolOpAuthenticationChoiceSaslCredentialsSearchRequestAttributeDescriptionFilterFiltersControlsControlSearchControlValue
AddRequestModifyRequest
DelRequestExtendedRequestExtendedResponse)calcualte_length)convert_resultconvert_attributesencode_attributesencode_changes)escape_filter_charsquery_syntax_converter)get_auth_context)LDAPPacketizer)UniProto)LDAPBindExceptionLDAPAddExceptionLDAPModifyExceptionLDAPDeleteExceptionLDAPSearchException)sha256)	UniClient)asyauthProtocol)UniCredential)ISC_REQc                   @   s`  e Zd Zd>dedefddZdd Zdd	 Zd
d Zde	e
ef fddZdefddZdd Zdd Zdd Zdd Zdd Zdd Zde
de	e
ef fd d!Zd>de
d"e	e
ef d#ee fd$d%Zde
fd&d'Zd?d,e
d-e
dee d.ed/ed0ed1ed2ed#ee d3efd4d5Zd@d,e
d-e
dee d.ed/ed6ed1ed2ed#ee d7efd8d9Zd:d; Zd<d= ZdS )AMSLDAPClientConnectionNtarget
credentialc                 C   s   || _ || _|d ur|| _nt| j| _d| _d| _d| _d| _d| _d | _	d | _
d | _tj| _d | _d| _i | _i | _d| _d | _d| _d| _d| _| jjtjkrWd| _d S d S )NFr   T)r.   r/   authr    	connectedbind_okis_anon&_MSLDAPClientConnection__sign_messages)_MSLDAPClientConnection__encrypt_messagesnetworkconnection_closed_evthandle_incoming_taskr   RUNNINGstatus	lasterror
message_idmessage_tablemessage_table_notifyencryption_sequence_countercb_data_disable_channel_binding_disable_signing_null_channel_bindingprotocolr*   NONE)selfr.   r/   r0    rG   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/msldap/connection.py__init__   s4   
zMSLDAPClientConnection.__init__c                    s   | S NrG   rF   rG   rG   rH   
__aenter__<   s   z!MSLDAPClientConnection.__aenter__c                    s   t j|  ddI d H  d S )Nr   timeout)asynciowait_for
disconnect)rF   exc_typeexc	tracebackrG   rG   rH   	__aexit__?   s   z MSLDAPClientConnection.__aexit__c              
      s  z5z| j  2 z3 d H W }|d u r td| jdu rl| jdu rI|dd  }z| j|dI d H \}}|d ur;|W n/   dd l}|   | jdu rl|dd  }z| j	|I d H }W n   dd l}|   t
|}t|}g }||krt|}|| n$t|dkrt
|}t|d | }|| ||d  }t|dks|d d j}|| jvrg | j|< | j| | || jvrt | j|< | j|   q	6 td tjy   tj| _Y W | jd ur| j  tj| _d S  ty% }	 z!tj| _|	| _| jD ]}
|	g| j|
< | j|
   q
W Y d }	~	nd }	~	ww W | jd ur2| j  tj| _d S | jd urC| j  tj| _w )NT   r   	messageIDzConnection closed!)r6   readr2   r5   r0   decryptrT   	print_excr4   unsignr   lenr   loadappendnativer=   extendr>   rO   Eventset	ExceptionCancelledErrorr   STOPPEDr:   r7   ERRORr;   )rF   message_dataerrrT   msg_lenmsg_total_lenmessagesmessager<   emsgidrG   rG   rH   __handle_incomingB   s   6







8






z(MSLDAPClientConnection.__handle_incomingrl   c                    s   | j }|  j d7  _ ||d< t| }| jdu rk| jdu rD| j|| jI d H \}}|| }t|j	dddd| }|  jd7  _n'| j
du rk| j|| jI d H }|| }t|j	dddd| }|  jd7  _t | j|< | j|I d H  |S )Nr   rW   TrV   bigF)	byteordersigned)r<   r   dumpr2   r5   r0   encryptr?   r\   to_bytesr4   signrO   ra   r>   r6   write)rF   rl   curr_msg_idrg   	signaturerG   rG   rH   send_message   s&   


z#MSLDAPClientConnection.send_messager<   c                    sX   || j vrtd|  d S | j |  I d H  | j| }g | j|< | j |   |S )NzARequested message id %s which is not in the message notify table!)r>   r   debugwaitr=   clear)rF   r<   rk   rG   rG   rH   recv_message   s   


z#MSLDAPClientConnection.recv_messagec                 C   sL   z| j  }|d ur| }W d|iS W d|iS    t  d }Y d|iS )N	ntlm_data)r0   get_extra_infoto_dictrT   rZ   )rF   r   rG   rG   rH   r      s   

z%MSLDAPClientConnection.get_extra_infoc              
      s   z_t d t | _t }t| j|}tj|	 | jj
dI dH | _| jjtjkrM| jdu rM| jdu r?dtd  | _n| j }dt|  | _t|  | _tj| _t d W d	S  tyv } z
d|fW  Y d}~S d}~ww )
a  
		Connects to the remote server. Establishes the session, but doesn't perform binding.
		This function MUST be called first before the `bind` operation.

		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		zConnecting!rM   NFTs   tls-server-end-point:    zConnection succsessful!TN)r   r{   rO   ra   r7   r!   r)   r.   rP   connectrN   r6   rD   r"   CLIENT_SSL_TCPrA   rC   r(   digestr@   get_peer_certificatecreate_task(_MSLDAPClientConnection__handle_incomingr8   r   	CONNECTEDr:   rc   )rF   
packetizerclientcertdatarm   rG   rG   rH   r      s(   




zMSLDAPClientConnection.connectc                    sl   t d d| _| jdur| j  | jdur(| j I dH  tdI dH  | j	dur4| j	
  dS dS )zC
		Tears down the connection.

		:return: Nothing
		:rtype: None
		zDisconnecting!FNr   )r   r{   r2   r7   rb   r6   closerO   sleepr8   cancelrK   rG   rG   rH   rQ      s   




z!MSLDAPClientConnection.disconnectc                 C   sj   t d d| _tj| _| jjtj	tj
tjfv r1| j | _| j | _| js*| jr3d| jj_dS dS dS )z{
		Internal function invoked after bind finished. 
		Instructs the network layer that upcoming messages might be wrapped
		zBIND Success!TFN)r   r{   r2   r   r9   r:   r/   rD   r*   NTLMKERBEROSSICILYr0   signing_neededr4   encryption_neededr5   r6   r   is_plain_msgrK   rG   rG   rH   __bind_success   s   
z%MSLDAPClientConnection.__bind_successc              
      s  | j tjkrtdtd z| jjtj	kr|t
jt
jB t
jB }| jjtjkr-t
j}| jdu r5t
j}td|  | jjd| j || jdI dH \}}}|durYd|fW S ddi}d	d
 t|d}dt|i}dt|i}| |I dH }	| |	I dH }
|
d }
t|
trd|
fW S |
j}
|
d d dkrdt|
d d |
d d fW S d|i}d	d
 t|d}dt|i}dt|i}| |I dH }	| |	I dH }
|
d }
t|
trd|
fW S |
j}
|
d d dkrdt|
d d |
d d fW S | jj|
d d | j | jdI dH \}}}|dur d|fW S d|i}d	d
 t|d}dt|i}dt|i}| |I dH }	| |	I dH }
|
d }
t|
trYd|
fW S |
j}
|
d d dkrudt|
d d |
d d fW S |   W dS | jjtj krd}| jj!dkr| jj! }d}| jj"dkr| jj" }|dkrd| _#d|i}d	|t|d}dt|i}dt|i}| |I dH }	| |	I dH }
|
d }
t|
trd|
fW S |
j}
|
d d dkr|   W dS dt|
d d |
d d fW S | jjtj$tj%fv rd}	 z:t
jt
jB t
jB }| jjtjkr't
j}| jdu r0t
j}| jj|| j| j |dI dH \}}}|durK|W n tyd } zd|fW  Y d}~W S d}~ww d |d}dt&|i}d	dt|d}dt|i}dt|i}| |I dH }	| |	I dH }
|
d }
t|
trd|
fW S |
j}
|
d d dkrd|
d v r| jj|
d d | j| j |dI dH \}}}|durd|fW S | j' du s| j( du r| j) | _*|   W dS |
d d dkr|
d d }qdt|
d d |
d d fW S | jjtj+kr| jjtjkr/|   W dS | jjtj,kr| - I dH \}}|durJd|fW S dd  i}dt&|i}d	dt|d}dt|i}dt|i}| |I dH }	| |	I dH }
t|
d trd|
d fW S |
d jd }|d dkrdt|d |d fW S |   W dS dtd!| jjj. fW S td"| jjj.  ty } z| / I dH  d|fW  Y d}~S d}~ww )#z
		Performs the bind operation.
		This is where the authentication happens. Remember to call `connect` before this function!

		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		z*Connect to the LDAP server before binding.zBIND in progress...TzSICILY bind with flags: %sN)spnflagsr@   sicily_discor      r   )versionnameauthenticationbindRequestr
   r   F
resultCodesuccessdiagnosticMessagesicily_nego	matchedDN)r   r@   sicily_respr   simple)r@   r   r   z
GSS-SPNEGO)	mechanismcredentialssaslserverSaslCredssaslBindInProgressr   EXTERNALzNot implemented: %sz)Not implemented authentication method: %s)0r:   r   r   rc   r   r{   r/   rD   r*   r   r,   
CONNECTIONCONFIDENTIALITY	INTEGRITYr.   r"   r   rB   r0   authenticateto_target_stringr@   encoder   r	   r
   rz   r~   
isinstancer_   r#   %_MSLDAPClientConnection__bind_successSIMPLEsecretusernamer3   r   r   r   r   r   get_seq_numberr?   SSL
CLIENT_TCPstarttlsr   rQ   )rF   r   datato_continuerh   r0   bindreqbrmsgmsg_idrespwuser	challengerm   r   _resprG   rG   rH   bind  s  

(








.








(

0

 



zMSLDAPClientConnection.bindc              
      s*  zyddi}dt |i}dt|i}| |I d H }| |I d H }t|d tr0d|d fW S |d jd }|d dkrIdt|d |d	 fW S | j	  t
dI d H  | j| jtjI d H  t
|  | _tj| _t
dI d H  W d
S  ty } zt| d|fW  Y d }~S d }~ww )NrequestNames   1.3.6.1.4.1.1466.20037extendedReqr
   r   Fr   r   r   r   )r   r
   rz   r~   r   rc   r_   r#   r8   r   rO   r   r6   wrap_sslr.   get_ssl_contextsslPROTOCOL_TLS_CLIENTr   r   r   r   r:   print)rF   extr   r   r   r   r   rm   rG   rG   rH   r     s8   
zMSLDAPClientConnection.starttlsentry
attributesc              
      s   zg|  t|d}t| dt|i}dt|i}| |I dH }| |I dH }t|d t	r:d|d fW S |D ])}|d j
}	|j}|	dkre|d d d	kredt||d d |d d
 f  W S q<W dS  t	y~ }
 z
d|
fW  Y d}
~
S d}
~
ww )a:  
		Performs the add operation.
		
		:param entry: The DN of the object to be added
		:type entry: str
		:param attributes: Attributes to be used in the operation
		:type attributes: dict
		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		)r   r   
addRequestr
   Nr   FaddResponser   r   r   r   )r   r   r   r{   r   r
   rz   r~   r   rc   r   r_   r$   )rF   r   r   reqr   r   r   resultsrl   msg_typerm   rG   rG   rH   add*  s8   



zMSLDAPClientConnection.addchangescontrolsc              
      s  zj|  t|d}dt|i}dt|i}|dur||d< | |I dH }| |I dH }t|d tr=d|d fW S |D ])}	|	d j}
|	j	}	|
dkrh|	d d	 d
krhdt
||	d d	 |	d d f  W S q?W dS  ty } z
d|fW  Y d}~S d}~ww )a  
		Performs the modify operation.
		
		:param entry: The DN of the object whose attributes are to be modified
		:type entry: str
		:param changes: Describes the changes to be made on the object. Must be a dictionary of the following format: {'attribute': [('change_type', [value])]}
		:type changes: dict
		:param controls: additional controls to be passed in the query
		:type controls: List[class:`Control`] 
		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		)objectr   modifyRequestr
   Nr   r   FmodifyResponser   r   r   r   )r   r   r   r
   rz   r~   r   rc   r   r_   r%   )rF   r   r   r   r   r   r   r   r   rl   r   rm   rG   rG   rH   modifyR  s:   


zMSLDAPClientConnection.modifyc           	   
      s   z[dt | i}dt|i}| |I dH }| |I dH }t|d tr.d|d fW S |D ])}|d j}|j}|dkrY|d d dkrYdt	||d d |d d	 f  W S q0W d
S  tyr } z
d|fW  Y d}~S d}~ww )z
		Performs the delete operation.
		
		:param entry: The DN of the object to be deleted
		:type entry: str
		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		
delRequestr
   Nr   FdelResponser   r   r   r   )
r   r   r
   rz   r~   r   rc   r   r_   r&   )	rF   r   r   r   r   r   rl   r   rm   rG   rG   rH   delete}  s0   	


zMSLDAPClientConnection.delete     Fr   basequerysearch_scope
size_limit
types_onlyderefAliases	timeLimitreturn_donec              
   C  sX  | j tjkrdtdfV  dS | j tjkrdtdfV  dS zt|du r&d}t|}| |||||||d}dt|i}dt|i}|	durK|	|d< | 	|I dH }	 | 
|I dH }|D ]1}|d j}|j}|d
krw|
d	u ru|dfV   n|dkr|q^|
d	u r|dfV  q^t|d dfV  q^qSW dS  ty } zd|fV  W Y d}~dS d}~ww )a`  
		Performs the search operation.
		
		:param base: base tree on which the search should be performed
		:type base: str
		:param query: filter query that defines what should be searched for
		:type query: str
		:param attributes: a list of attributes to be included in the response
		:type attributes: List[bytes]
		:param search_scope: Specifies the search operation's scope. Default: 2 (Subtree)
		:type search_scope: int
		:param types_only: indicates whether the entries returned should include attribute types only or both types and values. Default: False (both)
		:type types_only: bool
		:param size_limit: Size limit of result elements per query. Default: 1000
		:type size_limit: int
		:param derefAliases: Specifies the behavior on how aliases are dereferenced. Default: 0 (never)
		:type derefAliases: int
		:param timeLimit: Maximum time the search should take. If time limit reached the server SHOULD return an error
		:type timeLimit: int
		:param controls: additional controls to be passed in the query
		:type controls: List[class:`Control`]
		:param return_done: Controls wether the final 'done' LDAP message should be returned, or just the actual results
		:type return_done: bool

		:return: Async generator which yields (`LDAPMessage`, None) tuple on success or (None, `Exception`) on error
		:rtype: Iterator[(:class:`LDAPMessage`, :class:`Exception`)]
		NConnected, but not bound.5Connection not running! Probably encountered an erroriX  
baseObjectscoper   	sizeLimitr   	typesOnlyfilterr   searchRequestr
   r   TsearchResDonesearchResRef)r:   r   r   rc   r9   r   r   r   r
   rz   r~   r   r_   r   )rF   r   r   r   r   r   r   r   r   r   r   flt	searchreqr   r   r   r   rl   r   rm   rG   rG   rH   search  sZ   

zMSLDAPClientConnection.searchr   
rate_limitc                 C  s  | j tjkrdtdfV  dS | j tjkrdtdfV  dS zd}	 t|
I dH  tdt||d	 dg}|	durC|
|	 t|}| j|||||||||dd	
2 zh3 dH W \}}|durkd|fV   W dS d
|d v r|d d
 dkrt|d d
 |d d |d D ]%}|d dkrzt|d jd }W n ty } z|d}~ww  nqtdqVt|d dfV  qV6 |dkrW dS q# ty } zd|fV  W Y d}~dS d}~ww )ap  
		Paged search is the same as the search operation and uses it under the hood. Adds automatic control to read all results in a paged manner.
		
		:param base: base tree on which the search should be performed
		:type base: str
		:param query: filter query that defines what should be searched for
		:type query: str
		:param attributes: a list of attributes to be included in the response
		:type attributes: List[bytes]
		:param search_scope: Specifies the search operation's scope. Default: 2 (Subtree)
		:type search_scope: int
		:param types_only: indicates whether the entries returned should include attribute types only or both types and values. Default: False (both)
		:type types_only: bool
		:param size_limit: Size limit of result elements per query. Default: 1000
		:type size_limit: int
		:param derefAliases: Specifies the behavior on how aliases are dereferenced. Default: 0 (never)
		:type derefAliases: int
		:param timeLimit: Maximum time the search should take. If time limit reached the server SHOULD return an error
		:type timeLimit: int
		:param controls: additional controls to be passed in the query
		:type controls: dict
		:param rate_limit: time to sleep bwetween each query
		:type rate_limit: float
		:return: Async generator which yields (`dict`, None) tuple on success or (None, `Exception`) on error
		:rtype: Iterator[(:class:`dict`, :class:`Exception`)]
		Nr   r   r   Ts   1.2.840.113556.1.4.319)sizecookie)controlTypecontrolValue)r   r   r   r   r   r   r   r   r
   r   r   r   r   r   r   z+SearchControl missing from server response!)r:   r   r   rc   r9   rO   r   r   r   rs   r`   r   r   r'   r]   r_   r   )rF   r   r   r   r   r   r   r   r   r   r   r   ctrl_list_tempctrsr   rh   controlrm   rG   rG   rH   pagedsearch  s   	

5z"MSLDAPClientConnection.pagedsearchc                    s   | j tjkrd tdfS ddi}dt|i}dt|i}| |I d H }| |I d H }|d }t|tr:d |fS |j	d d dkrRd	t
|d d |d d
 fS |j	d d  d fS )Nr   r   s   1.3.6.1.4.1.4203.1.11.3r   r
   r   r   r   Fr   responseValue)r:   r   r9   rc   r   r
   rz   r~   r   r_   r#   decode)rF   r   r   r   r   r   rG   rG   rH   whoamiN  s$   


zMSLDAPClientConnection.whoamic              	      s   | j tjtjfvrd tdfS g d}dd i}dddd| jjd dt||d	}d
t	|i}dt
|i}| |I d H }| |I d H }|d }t|trTd |fS d|jd vr]dS t|jd d d fS )Nr   )s   subschemaSubentrys   dsServiceNames   namingContextss   defaultNamingContexts   schemaNamingContexts   configurationNamingContexts   rootDomainNamingContexts   supportedControls   supportedLDAPVersions   supportedLDAPPoliciess   supportedSASLMechanismss   dnsHostNames   ldapServiceNames
   serverNames   supportedCapabilitiespresentobjectClassr   r   r   Fr   r   r
   r   )NN)r:   r   r   r9   rc   r   r.   rN   r   r   r
   rz   r~   r   r_   r   )rF   r   filtr   r   r   r   r   rG   rG   rH   get_serverinfof  s0   

z%MSLDAPClientConnection.get_serverinforJ   )r   r   Fr   NNF)r   r   Fr   NNr   ) __name__
__module____qualname__r   r+   rI   rL   rU   r   r   strr   rz   intr~   r   r   rQ   r   r   r   r   r   r   r   r   bytesboolr   r  r  r	  rG   rG   rG   rH   r-      s,     N
  $(+<!<T\r-   )>rO   typingr   r   r   msldapr   msldap.commons.commonr   commons.targetr   msldap.protocol.messagesr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   msldap.protocol.utilsr   msldap.protocol.typeconversionr   r   r   r   msldap.protocol.queryr   r   msldap.commons.authbuilderr    msldap.network.packetizerr!   asysocks.unicomm.common.targetr"   msldap.commons.exceptionsr#   r$   r%   r&   r'   hashlibr(   asysocks.unicomm.clientr)   asyauth.common.constantsr*   asyauth.common.credentialsr+   asyauth.common.winapi.constantsr,   r-   rG   rG   rG   rH   <module>   s(    L