o
    j;                     @   s   d Z ddlmZmZmZ ddlZddlmZ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mZmZmZmZmZ dd
lmZmZ ddlmZ G dd deZdS )
    )ThreadLockEventN   )get_config_parameter
DIGEST_MD5)LDAPSSLConfigurationErrorLDAPStartTLSErrorLDAPOperationResult$LDAPSignatureVerificationFailedError)BaseStrategyRESPONSE_COMPLETE)LDAPMessage)loglog_enabledformat_ldap_messageERRORNETWORKEXTENDED)decoderdecode_message_fast)md5_hmacc                   @   s   e Zd ZdZG dd deZdd Zd ddZd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )!AsyncStrategyaU  
    This strategy is asynchronous. You send the request and get the messageId of the request sent
    Receiving data from socket is managed in a separated thread in a blocking mode
    Requests return an int value to indicate the messageId of the requested Operation
    You get the response with get_response, it has a timeout to wait for response to appear
    Connection.response will contain the whole LDAP response for the messageId requested in a dict form
    Connection.request will contain the result LDAP message in a dict form
    Response appear in strategy._responses dictionary
    c                   @   s    e Zd ZdZdd Zdd ZdS )z"AsyncStrategy.ReceiverSocketThreadzE
        The thread that actually manage the receiver socket
        c                 C   s   t |  || _td| _d S )NSOCKET_SIZE)r   __init__
connectionr   socket_sizeselfldap_connection r!   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/ldap3/strategy/asynchronous.pyr   8   s   
z+AsyncStrategy.ReceiverSocketThread.__init__c              
   C   s  d}d}d}d}d}d}d}d}|ri|rz
| j j| j}W n- ttjtfy2   | j jr0Y qY n tyL }	 zt	t
rGtt
dt|	| j   d}	~	ww t|dkr| j jtkr| j jr| j js|| }|dksk|r{t|dd d}|dd }d}|t|7 }||7 }||kr||d	 |d
  }
||d | }||d }|d|d	  }| j j}tt||| dd }|
|krtdtt|d d |  d |
  d d}||7 }d}n||7 }d}nd}t|}|dkst||k rd}nft||krg| j jr!| j j| t	tr!ttd|| j  | j jr6t |d| }| j j!"|}nt#j$|d| t% dd }| j j!&|}t|d }t	tr]ttd| j  t	t'rmtt'd| j t(|d |d dkr|d dkst)| j dr|d dkr| j j*j+r| j j*j+,| j  n2d| j _-t	t
rtt
d| j j-| j  t.| j j-d| j _-t	t
rtt
d| j j-| j  t/| j j-| j `0|dkrD| j j!j1; || j j!j2v r| j j!j2| 3| n|g| j j!j2|< |d dvr| j j!j2| 3t4 | j j!5| W d   n	1 sw   Y  | j j!j6r*| j j!7|| ||d }|r5dnd}| j j8s?|rAdnd}n#|d d krNd}nd!| j _-t	t
ratt
d| j j-| j  t/| j j-|s| j j!9  dS )"z
            Waits for data on socket, computes the length of the message and waits for enough bytes to decode the message
            Message are appended to strategy._responses
                Tr   z<%s> for <%s>N   big         zCSignature verification failed for the recieved LDAP message number z. Expected signature z	 but got .Fzreceived %d bytes via <%s>)asn1Spec	messageIDz received 1 ldap message via <%s>z!ldap message received via <%s>:%sz<<typeextendedRespresponseNamez1.3.6.1.4.1.1466.20037_awaiting_for_async_start_tlsresultzno Tls object defined in Serverzasynchronous StartTls failed)searchResEntrysearchResRefintermediateResponsez1.3.6.1.4.1.1466.20036z,unknown unsolicited notification from server):r   socketrecvr   OSErrorerrorAttributeErrorreceive_timeout	Exceptionr   r   r   strlensasl_mechanismr   _digest_md5_kissasl_in_progressint
from_bytesbytesfromhexr   r   hexr   compute_ldap_message_sizeusage_usageupdate_received_messager   fast_decoderr   strategydecode_response_fastr   decoder   decode_responser   r   hasattrservertls
_start_tls
last_errorr	   r
   r0   
async_lock
_responsesappendr   set_event_for_message
can_streamaccumulate_stream	listeningclose)r   unprocessedget_more_datalistendatasasl_total_bytes_recievedsasl_received_datasasl_next_packetsasl_buffer_lengthesasl_signaturesasl_sec_numkiscalculated_signaturelength	ldap_respdict_response
message_idr!   r!   r"   run=   s   4





*


	
hz&AsyncStrategy.ReceiverSocketThread.runN)__name__
__module____qualname____doc__r   rm   r!   r!   r!   r"   ReceiverSocketThread3   s    rr   c                 C   sP   t | | d| _d| _d| _d | _d | _d| _d | _t	 | _
t	 | _i | _d S )NF)r   r   syncno_real_dsapooledrU   	_requestsrX   receiverr   rT   
event_lock_eventsr   r!   r!   r"   r      s   
zAsyncStrategy.__init__Tc                 C   s   | j j t | _t | _t| || W d   n1 sw   Y  |rBz| j   W dS  tyA   d| j j	_
d| j j	_Y dS w dS )zV
        Open connection and start listen on the socket in a different thread
        N)r   connection_lockdictrU   rv   r   openrefresh_server_infor   rP   	_dsa_info_schema_info)r   reset_usageread_server_infor!   r!   r"   r|      s   

zAsyncStrategy.openc                 C   s8   | j j t|  W d   dS 1 sw   Y  dS )z9
        Close connection and stop socket thread
        N)r   rz   r   r[   r   r!   r!   r"   r[      s   
"zAsyncStrategy.closec                 C   sR   | j  || jvrt | j|< W d    d S W d    d S 1 s"w   Y  d S N)rx   ry   r   r   rl   r!   r!   r"   _add_event_for_message   s   
"z$AsyncStrategy._add_event_for_messagec                 C   sP   | j  || jvrt | j|< | j|   W d    d S 1 s!w   Y  d S r   )rx   ry   r   setr   r!   r!   r"   rW      s
   
"z#AsyncStrategy.set_event_for_messagec                 C   sL   | j  || jvrtd|| j| W  d    S 1 sw   Y  d S )Nz?Event for message[{}] should have been created before accessing)rx   ry   RuntimeErrorformatr   r!   r!   r"   _get_event_for_message   s
   
$z$AsyncStrategy._get_event_for_messagec                 C   &   d| j _d| j _d| j _| | |S )zB
        Clears connection.response and returns messageId
        Nr   responserequestr1   r   r   r!   r!   r"   post_send_search   
   
zAsyncStrategy.post_send_searchc                 C   r   )zC
        Clears connection.response and returns messageId.
        Nr   r   r!   r!   r"   post_send_single_response   r   z'AsyncStrategy.post_send_single_responsec                 C   s8   | j jst| j | _d| j _d| j_| j  dS dS )z-
        Start thread in daemon mode
        TN)r   rZ   r   rr   rw   daemonstartr   r!   r!   r"   _start_listen  s   zAsyncStrategy._start_listenc                 C   s^   |  |}||}|sdS | j| | j | j|W  d   S 1 s(w   Y  dS )z
        Performs the capture of LDAP response for this strategy
        The response is only complete after the event been set
        N)r   waitry   poprT   rU   )r   rl   timeouteventflagr!   r!   r"   _get_response  s   


$zAsyncStrategy._get_responsec                 C      t r   NotImplementedErrorr   r!   r!   r"   	receiving     zAsyncStrategy.receivingc                 C   r   r   r   r   r!   r!   r"   
get_stream   r   zAsyncStrategy.get_streamc                 C   r   r   r   )r   valuer!   r!   r"   
set_stream#  r   zAsyncStrategy.set_streamN)TT)rn   ro   rp   rq   r   rr   r   r|   r[   r   rW   r   r   r   r   r   r   r   r   r!   r!   r!   r"   r   '   s"     



r   ) rq   	threadingr   r   r   r5    r   r   core.exceptionsr	   r
   r   r   strategy.baser   r   protocol.rfc4511r   	utils.logr   r   r   r   r   r   
utils.asn1r   r   protocol.sasl.digestMd5r   r   r!   r!   r!   r"   <module>   s     