U
    
W[e                     @   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d	ddddddgZdS )z 
Ident protocol implementation.
    N)defer)basic)logfailure   i  c                   @   s   e Zd ZdZdZdd ZdS )
IdentErrorz;
    Can't determine connection owner; reason unknown.
    zUNKNOWN-ERRORc                 C   s   | j S N)identDescriptionself r   9/usr/lib/python3/dist-packages/twisted/protocols/ident.py__str__   s    zIdentError.__str__N)__name__
__module____qualname____doc__r	   r   r   r   r   r   r      s   r   c                   @   s   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      s   r   c                   @   s   e Zd ZdZdZdS )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                   @   s   e Zd ZdZdZdS )
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   s   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 |   nztt|\}}W n tk
rN   |   Y nVX t|  krdtkrn n&t|  kr|tkrn n| || n| 	t
t || d S )N,   )splitleninvalidQuerymapint
ValueError	_MIN_PORT	_MAX_PORT
validQuery	_ebLookupr   ZFailurer   )r   linepartsportOnServerportOnClientr   r   r   lineReceivedH   s    

0zIdentServer.lineReceivedc                 C   s   | j   d S r   )	transportZloseConnectionr
   r   r   r   r   X   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)   ZgetHostZhostZgetPeerr   ZmaybeDeferredlookupZaddCallback	_cbLookupZ
addErrbackr#   )r   r&   r'   Z
serverAddrZ
clientAddrr   r   r   r"   \   s        zIdentServer.validQueryc                 C   s"   |\}}|  d||||f  d S )Nz%d, %d : USERID : %s : %s)sendLine)r   resultsportcportZsysNameZuserIdr   r   r   r+   l   s    zIdentServer._cbLookupc                 C   sJ   | tr"| d|||jf  n$t| | d||t|jf  d S )Nz%d, %d : ERROR : %s)Zcheckr   r,   valuer   err)r   r   r.   r/   r   r   r   r#   q   s    

zIdentServer._ebLookupc                 C   s
   t  dS )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.
        Nr   )r   serverAddressclientAddressr   r   r   r*   y   s    zIdentServer.lookupN)
r   r   r   r   r(   r   r"   r+   r#   r*   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k
rJ   dd ZY nX dd	 Z	d
d Z
dd Zdd Zdd ZdS )ProcServerMixinzIImplements lookup() to grab entries for responses from /proc/net/tcp
    ZLINUXr   )getpwuidc                 C   s   ||d S Nr   r   )r   uidr6   r   r   r   getUsername   s    zProcServerMixin.getUsernamec                 C   s
   t  d S r   r2   )r   r8   r   r   r   r9      s    c              	   c   s4   t d"}|  |D ]}| V  qW 5 Q R X 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.Z4Bz=L   )joinr   strstructZunpackZpackr   )r   Zhexstrr   r   r   dottedQuadFromHexString   s    z'ProcServerMixin.dottedQuadFromHexStringc                 C   s*   | d\}}| |}t|d}||fS )N:rA   )r   rE   r   )r   ZpackedZaddrZportr   r   r   unpackAddress   s    

zProcServerMixin.unpackAddressc                 C   sN   |   }| |d \}}| |d \}}t|d }||f||f|fS )Nr   r      )r<   r   rG   r   )r   r$   r%   	localAddrZ	localPort
remoteAddrZ
remotePortr8   r   r   r   	parseLine   s
    zProcServerMixin.parseLinec                 C   sT   |   D ]@}| |\}}}||kr|d |d kr| j| |f  S qt d S )Nr   )r?   rK   SYSTEM_NAMEr9   r   )r   r3   r4   ZentrI   rJ   r8   r   r   r   r*      s
    zProcServerMixin.lookupN)r   r   r   r   rL   pwdr6   r9   ImportErrorr?   rE   rG   rK   r*   r   r   r   r   r5      s   r5   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r2| j d d S | d||f  | j d d S )zK
        Lookup user information about the specified address pair.
        r   r   %d, %d)rP   appendr   ZDeferredr   r,   )r   r&   r'   r   r   r   r*      s
    zIdentClient.lookupc                 C   sf   | j std|f  nJ| j d\}}}| || | j rb| d| j d d | j d d f  d S )NzUnexpected server response: %rr   rS   r   r   )rP   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 r7   )rP   errbackr   )r   reasonqr   r   r   connectionLost   s    
zIdentClient.connectionLostc                 C   s   | dd}t|dkr(|t| nbttj|\}}}|dkr|| jD ]"}|j|krH|||  d S qH|t| n|	||f d S )NrF   r      ZERROR)
r   r   rZ   r   r   rC   r<   
errorTypesr	   callback)r   Zdeferredr$   r%   ZportstypeZaddInfoZetr   r   r   rW      s    

zIdentClient.parseResponseN)r   r   r   r   r   r   r   r_   rQ   r*   r(   r]   rW   r   r   r   r   rO      s   
rO   )r   rD   Ztwisted.internetr   Ztwisted.protocolsr   Ztwisted.pythonr   r   r    r!   	Exceptionr   r   r   r   ZLineOnlyReceiverr   r5   rO   __all__r   r   r   r   <module>   s$   		Y45 