o
    ¯bû  ã                   @   sº   d Z ddlZddlmZ ddlmZ ddlmZmZ dZ	dZ
G dd	„ d	eƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZG dd„ dƒZG dd„ dejƒZg d¢ZdS )z 
Ident protocol implementation.
é    N)Údefer)Úbasic)ÚfailureÚlogé   iÿÿ  c                   @   s"   e Zd ZdZdZdefdd„ZdS )Ú
IdentErrorz;
    Can't determine connection owner; reason unknown.
    zUNKNOWN-ERRORÚreturnc                 C   s   | j S ©N)ÚidentDescription©Úself© r   ú9/usr/lib/python3/dist-packages/twisted/protocols/ident.pyÚ__str__   ó   zIdentError.__str__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   Ústrr   r   r   r   r   r      s    r   c                   @   ó   e Zd ZdZdZdS )ÚNoUserz�
    The connection specified by the port pair is not currently in use or
    currently not owned by an identifiable entity.
    zNO-USERN©r   r   r   r   r
   r   r   r   r   r      ó    r   c                   @   r   )ÚInvalidPorta  
    Either the local or foreign port was improperly specified. This should
    be returned if either or both of the port ids were out of range (TCP
    port numbers are from 1-65535), negative integers, reals or in any
    fashion not recognized as a non-negative integer.
    zINVALID-PORTNr   r   r   r   r   r   '   s    r   c                   @   r   )Ú
HiddenUserz…
    The server was able to identify the user of this port, but the
    information was not returned at the request of the user.
    zHIDDEN-USERNr   r   r   r   r   r   2   r   r   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚIdentServeraá  
    The Identification Protocol (a.k.a., "ident", a.k.a., "the Ident
    Protocol") provides a means to determine the identity of a user of a
    particular TCP connection. Given a TCP port number pair, it returns a
    character string which identifies the owner of that connection on the
    server's system.

    Server authors should subclass this class and override the lookup method.
    The default implementation returns an UNKNOWN-ERROR response for every
    query.
    c                 C   s¬   |  d¡}t|ƒdkr|  ¡  d S z	tt|ƒ\}}W n ty(   |  ¡  Y d S w t|  kr3tkrIn nt|  kr?tkrIn n|  ||¡ d S |  	t
 tƒ ¡||¡ d S )Nú,é   )ÚsplitÚlenÚinvalidQueryÚmapÚintÚ
ValueErrorÚ	_MIN_PORTÚ	_MAX_PORTÚ
validQueryÚ	_ebLookupr   ÚFailurer   )r   ÚlineÚpartsÚportOnServerÚportOnClientr   r   r   ÚlineReceivedH   s   
ÿÿzIdentServer.lineReceivedc                 C   s   | j  ¡  d S r	   )Ú	transportÚloseConnectionr   r   r   r   r!   \   s   zIdentServer.invalidQueryc                 C   sL   | j  ¡ j|f}| j  ¡ j|f}t | j||¡ | j||¡ 	| j
||¡ dS )zß
        Called when a valid query is received to look up and deliver the
        response.

        @param portOnServer: The server port from the query.
        @param portOnClient: The client port from the query.
        N)r/   ÚgetHostÚhostÚgetPeerr   ÚmaybeDeferredÚlookupÚaddCallbackÚ	_cbLookupÚ
addErrbackr(   )r   r,   r-   Ú
serverAddrÚ
clientAddrr   r   r   r'   _   s   ÿzIdentServer.validQueryc                 C   s"   |\}}|   d||||f ¡ d S )Nz%d, %d : USERID : %s : %s)ÚsendLine)r   ÚresultÚsportÚcportÚsysNameÚuserIdr   r   r   r7   m   s   zIdentServer._cbLookupc                 C   sL   |  t¡r|  d|||jf ¡ d S t |¡ |  d||t|jƒf ¡ d S )Nz%d, %d : ERROR : %s)Úcheckr   r;   Úvaluer   Úerr)r   r   r=   r>   r   r   r   r(   q   s   

ÿzIdentServer._ebLookupc                 C   ó   t ƒ ‚)aq  
        Lookup user information about the specified address pair.

        Return value should be a two-tuple of system name and username.
        Acceptable values for the system name may be found online at::

            U{http://www.iana.org/assignments/operating-system-names}

        This method may also raise any IdentError subclass (or IdentError
        itself) to indicate user information will not be provided for the
        given query.

        A Deferred may also be returned.

        @param serverAddress: A two-tuple representing the server endpoint
        of the address being queried.  The first element is a string holding
        a dotted-quad IP address.  The second element is an integer
        representing the port.

        @param clientAddress: Like I{serverAddress}, but represents the
        client endpoint of the address being queried.
        ©r   )r   ÚserverAddressÚclientAddressr   r   r   r5   z   s   zIdentServer.lookupN)
r   r   r   r   r.   r!   r'   r7   r(   r5   r   r   r   r   r   ;   s    	r   c                   @   sx   e Zd ZdZdZzddlmZ efdd„Z[W n ey%   ddd„ZY nw d	d
„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )ÚProcServerMixinzDImplements lookup() to grab entries for responses from /proc/net/tcpÚLINUXr   )Úgetpwuidc                 C   s   ||ƒd S ©Nr   r   ©r   ÚuidrJ   r   r   r   ÚgetUsernameœ   s   zProcServerMixin.getUsernameNc                 C   rD   r	   rE   rL   r   r   r   rN   ¢   r   c                 c   sL   � t dƒ�}| ¡  |D ]}| ¡ V  qW d   ƒ d S 1 sw   Y  d S )Nz/proc/net/tcp)ÚopenÚreadlineÚstrip)r   ÚfÚLr   r   r   Úentries¥   s   €
ÿ"þzProcServerMixin.entriesc                 C   s&   d  ttt dt dt|dƒ¡¡ƒ¡S )NÚ.Ú4Bz=Lé   )Újoinr"   r   ÚstructÚunpackÚpackr#   )r   Úhexstrr   r   r   ÚdottedQuadFromHexString«   s   ÿz'ProcServerMixin.dottedQuadFromHexStringc                 C   s*   |  d¡\}}|  |¡}t|dƒ}||fS )Nú:rW   )r   r]   r#   )r   ÚpackedÚaddrÚportr   r   r   ÚunpackAddress°   s   

zProcServerMixin.unpackAddressc                 C   sN   |  ¡  ¡ }|  |d ¡\}}|  |d ¡\}}t|d ƒ}||f||f|fS )Nr   r   é   )rQ   r   rb   r#   )r   r*   r+   Ú	localAddrÚ	localPortÚ
remoteAddrÚ
remotePortrM   r   r   r   Ú	parseLine¶   s
   zProcServerMixin.parseLinec                 C   sP   |   ¡ D ] }|  |¡\}}}||kr$|d |d kr$| j|  |¡f  S qtƒ ‚)Nr   )rT   rh   ÚSYSTEM_NAMErN   r   )r   rF   rG   Úentrd   rf   rM   r   r   r   r5   ½   s   €zProcServerMixin.lookupr	   )r   r   r   r   ri   ÚpwdrJ   rN   ÚImportErrorrT   r]   rb   rh   r5   r   r   r   r   rH   ”   s    þrH   c                   @   s@   e Zd ZeeeefZdd„ Zdd„ Z	dd„ Z
dd„ Zd	d
„ ZdS )ÚIdentClientc                 C   s
   g | _ d S r	   )Úqueriesr   r   r   r   Ú__init__Ê   s   
zIdentClient.__init__c                 C   sR   | j  t ¡ ||f¡ t| j ƒdkr| j d d S |  d||f ¡ | j d d S )zK
        Lookup user information about the specified address pair.
        r   éÿÿÿÿr   ú%d, %d)rn   Úappendr   ÚDeferredr    r;   )r   r,   r-   r   r   r   r5   Í   s
   zIdentClient.lookupc                 C   sl   | j st d|›�¡ d S | j  d¡\}}}|  ||¡ | j r4|  d| j d d | j d d f ¡ d S d S )NzUnexpected server response: r   rq   r   r   )rn   r   ÚmsgÚpopÚparseResponser;   )r   r*   ÚdÚ_r   r   r   r.   Ø   s   *ÿzIdentClient.lineReceivedc                 C   s(   | j D ]}|d  t|ƒ¡ qg | _ d S rK   )rn   Úerrbackr   )r   ÚreasonÚqr   r   r   ÚconnectionLostá   s   

zIdentClient.connectionLostc                 C   s’   |  dd¡}t|ƒdkr| t|ƒ¡ d S ttj|ƒ\}}}|dkr@| jD ]}|j|kr6| ||ƒ¡  d S q%| t|ƒ¡ d S | 	||f¡ d S )Nr^   r   é   ÚERROR)
r   r    ry   r   r"   r   rQ   Ú
errorTypesr
   Úcallback)r   Údeferredr*   r+   ÚportsÚtypeÚaddInfoÚetr   r   r   rv   æ   s   

þzIdentClient.parseResponseN)r   r   r   r   r   r   r   r   ro   r5   r.   r|   rv   r   r   r   r   rm   Æ   s    	rm   )r   r   r   r   r   rm   rH   )r   rY   Útwisted.internetr   Útwisted.protocolsr   Útwisted.pythonr   r   r%   r&   Ú	Exceptionr   r   r   r   ÚLineOnlyReceiverr   rH   rm   Ú__all__r   r   r   r   Ú<module>   s   		Y20