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|ríz
| 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rÛtdtt |d¡ƒ d | ¡  d |
 ¡  d ƒ‚d}||7 }d}n||7 }d}nd}t |¡}|dksýt|ƒ|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�s‚t)| j dƒ�rÎ|d dk�r²| j j*j+�r™| j j*j+ ,| j ¡ n2d| j _-t	t
ƒ�r¬tt
d| j j-| j ƒ t.| j j-ƒ‚d| j _-t	t
ƒ�rÅt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     