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