U
    
W[@                     @   s   d Z ddlmZmZ ddlZddlZddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZmZmZ ddlmZ dd
dZG dd de	jZG dd deZG dd deZdS )z
Authoritative resolvers.
    )absolute_importdivisionN)dnserrorcommon)defer)failure)execfilenativeString_PY3)FilePath/tmp/twisted-names.serialc              	   C   s   t d}td}z4tj| sFt| d}||d  W 5 Q R X W 5 t| X t| d}| 	 \}}W 5 Q R X ||krt
|d pd}t| d}|d||f  W 5 Q R X |d	|f  }|S )
ay  
    Return a monotonically increasing (across program runs) integer.

    State is stored in the given file.  If it does not exist, it is
    created with rw-/---/--- permissions.

    @param filename: Path to a file that is used to store the state across
        program runs.
    @type filename: L{str}

    @return: a monotonically increasing number
    @rtype: L{str}
    z%Y%m%d   wz 0r   r   z%s %dz%02d)timestrftimeosumaskpathexistsopenwritereadlinesplitint)filenameserialofZ
serialFileZ
lastSerialZzoneID r!   9/usr/lib/python3/dist-packages/twisted/names/authority.py	getSerial   s    

r#   c                   @   sh   e Zd ZdZejejejfZej	ej
fZdZdZdd Zdd Zdd Zdd	d
ZdddZdd ZdS )FileAuthoritya  
    An Authority that is loaded from a file.

    @ivar _ADDITIONAL_PROCESSING_TYPES: Record types for which additional
        processing will be done.

    @ivar _ADDRESS_TYPES: Record types which are useful for inclusion in the
        additional section generated during additional processing.

    @ivar soa: A 2-tuple containing the SOA domain name as a L{bytes} and a
        L{dns.Record_SOA}.
    Nc                 C   s    t j|  | | i | _d S N)r   ResolverBase__init__loadFile_cache)selfr   r!   r!   r"   r'   O   s    
zFileAuthority.__init__c                 C   s
   || _ d S r%   )__dict__)r*   stater!   r!   r"   __setstate__U   s    zFileAuthority.__setstate__c              
   c   sn   || D ]`}|j | jkr|jjj}| j| dD ]2}|j| jkr4t	j
||jt	j|jpZ||ddV  q4qdS )aW  
        Find locally known information that could be useful to the consumer of
        the response and construct appropriate records to include in the
        I{additional} section of that response.

        Essentially, implement RFC 1034 section 4.3.2 step 6.

        @param answer: A L{list} of the records which will be included in the
            I{answer} section of the response.

        @param authority: A L{list} of the records which will be included in
            the I{authority} section of the response.

        @param ttl: The default TTL for records for which this is not otherwise
            specified.

        @return: A generator of L{dns.RRHeader} instances for inclusion in the
            I{additional} section.  These instances represent extra information
            about the records in C{answer} and C{authority}.
        r!   TauthN)type_ADDITIONAL_PROCESSING_TYPESZpayloadnamerecordsgetlowerTYPE_ADDRESS_TYPESr   RRHeaderINttl)r*   Zanswer	authorityr:   recordr2   recr!   r!   r"   _additionalRecordsY   s    
    z FileAuthority._additionalRecordsc                 C   s  g }g }g }g }t | jd j| jd j}	| j| }
|
r|
D ]}|jdk	rZ|j}n|	}|jt	j
kr| | jd  kr|t	j||jt	j||dd n4|j|ks|t	jkr|t	j||jt	j||dd |jt	jkrD|t	j||jt	j||dd qD|s|}| |||	}|r.|| n
|| |sp|sp|t	j| jd t	jt	j|| jd dd t|||fS t	|| jd rttt	|S ttt|S dS )a  
        Determine a response to a particular DNS query.

        @param name: The name which is being queried and for which to lookup a
            response.
        @type name: L{bytes}

        @param cls: The class which is being queried.  Only I{IN} is
            implemented here and this value is presently disregarded.
        @type cls: L{int}

        @param type: The type of records being queried.  See the types defined
            in L{twisted.names.dns}.
        @type type: L{int}

        @param timeout: All processing is done locally and a result is
            available immediately, so the timeout value is ignored.

        @return: A L{Deferred} that fires with a L{tuple} of three sets of
            response records (to comprise the I{answer}, I{authority}, and
            I{additional} sections of a DNS response) or with a L{Failure} if
            there is a problem processing the query.
        r   Nr   Fr.   T)maxsoaminimumexpirer3   r4   r5   r:   r6   r   NSappendr8   r9   ZALL_RECORDSCNAMEr>   extendSOAr   succeedZ_isSubdomainOffailr   FailureZAuthoritativeDomainErrorr   DomainError)r*   r2   clsr0   timeoutZcnamesresultsr;   Z
additionaldefault_ttlZdomain_recordsr<   r:   ZadditionalInformationr!   r!   r"   _lookupx   s    
                 
    zFileAuthority._lookup
   c           
      C   s  | j d  | krt| j d j| j d j}| j d jd k	rN| j d j}n|}tj| j d tjtj	|| j d ddg}| j
 D ]T\}}|D ]F}|jd k	r|j}	n|}	|jtjkr|tj||jtj	|	|dd qq||d  t|ddfS ttt|S )Nr   r   Tr.   r!   )r@   r5   r?   rA   rB   r:   r   r8   rG   r9   r3   itemsr6   rD   r   rH   rI   r   rJ   rK   )
r*   r2   rM   rO   Zsoa_ttlrN   kr   r=   r:   r!   r!   r"   
lookupZone   sB        
     zFileAuthority.lookupZonec                 C   sb   g g g   }}}|D ]B}|d r| |d d  | |d d  | |d d  q|||fS )Nr   r      )rF   )r*   rN   Zansr/   addresr!   r!   r"   _cbAllRecords   s    zFileAuthority._cbAllRecords)N)rQ   )__name__
__module____qualname____doc__r   rE   ZMXrC   r1   AZAAAAr7   r@   r3   r'   r-   r>   rP   rT   rX   r!   r!   r!   r"   r$   ;   s   
c
r$   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	PySourceAuthorityzC
    A FileAuthority that is built up from Python source code.
    c                 C   s|   |   i  }}t||| d|kr.td| i | _|d D ]:}t|d tjrV|| _| j|d 	 g 
|d  q<d S )NZzonezNo zone defined in r   r   )setupConfigNamespacer	   
ValueErrorr3   
isinstancer   Z
Record_SOAr@   
setdefaultr5   rD   )r*   r   glZrrr!   r!   r"   r(   	  s    zPySourceAuthority.loadFilec                    s    fddS )Nc                    s   |  ||fS r%   r!   )r2   argkwr0   r!   r"   <lambda>      z.PySourceAuthority.wrapRecord.<locals>.<lambda>r!   )r*   r0   r!   rg   r"   
wrapRecord  s    zPySourceAuthority.wrapRecordc                 C   sN   i }t j }dd |D D ],}tt |}| |}|||tdd  < q|S )Nc                 S   s   g | ]}| d r|qS )Record_)
startswith).0xr!   r!   r"   
<listcomp>  s     
 z:PySourceAuthority.setupConfigNamespace.<locals>.<listcomp>rk   )r   r+   Ziterkeysgetattrrj   len)r*   r   rR   r<   r0   r    r!   r!   r"   r_     s    


z&PySourceAuthority.setupConfigNamespaceN)rY   rZ   r[   r\   r(   rj   r_   r!   r!   r!   r"   r^     s   r^   c                   @   sH   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d Z
dS )BindAuthorityz
    An Authority that loads U{BIND zone files
    <https://en.wikipedia.org/wiki/Zone_file>}.

    Supports only C{$ORIGIN} and C{$TTL} directives.
    c                 C   sJ   t |}t| d | _| d}| |}| |}| | dS )z}
        Load records from C{filename}.

        @param filename: file to read from
        @type filename: L{bytes}
           .TN)	r   r
   basenameoriginZ
getContent
splitlinesstripCommentscollapseContinuations
parseLines)r*   r   fplinesr!   r!   r"   r(   ,  s    

zBindAuthority.loadFilec                 C   s   dd dd |D D S )z
        Strip comments from C{lines}.

        @param lines: lines to work on
        @type lines: iterable of L{bytes}

        @return: C{lines} sans comments.
        c                 s   s2   | ]*}| d dkr|p(|d| d  V  qdS )   ;N)find)rm   ar!   r!   r"   	<genexpr>G  s    z.BindAuthority.stripComments.<locals>.<genexpr>c                 S   s   g | ]}|  qS r!   )strip)rm   br!   r!   r"   ro   H  s    z/BindAuthority.stripComments.<locals>.<listcomp>r!   )r*   r{   r!   r!   r"   rw   >  s
    	zBindAuthority.stripCommentsc              
   C   s   g }d}|D ]}|dkrP| ddkr2|| q||d| d  d}q| ddkr|d  d|d| d  7  < d}q|d  d| 7  < qtddd	 |D S )
z
        Transform multiline statements into single lines.

        @param lines: lines to work on
        @type lines: iterable of L{bytes}

        @return: iterable of continuous lines
        r      (r}   Nr      )    c                 s   s   | ]}|  V  qd S r%   )r   )rm   liner!   r!   r"   r   f  s     z6BindAuthority.collapseContinuations.<locals>.<genexpr>)r~   rD   filter)r*   r{   rd   r,   r   r!   r!   r"   rx   N  s    	"z#BindAuthority.collapseContinuationsc                 C   s   d}| j }i | _|D ]p}|d dkr4t|d }q|d dkrJ|d }q|d dkr`tdq|d dkrvtd	q| ||| q|| _ d
S )zs
        Parse C{lines}.

        @param lines: lines to work on
        @type lines: iterable of L{bytes}
        i0*  r   s   $TTLr   s   $ORIGINs   $INCLUDEz"$INCLUDE directive not implementeds	   $GENERATEz#$GENERATE directive not implementedN)ru   r3   r   Zstr2timeNotImplementedErrorparseRecordLine)r*   r{   r:   ru   r   r!   r!   r"   ry   i  s     

zBindAuthority.parseLinesc                 C   sd   | ds |d |dd  }n|dd }t| d|f d}|rR||||| ntd|f dS )a  
        Add a record to our authority.  Expand domain with origin if necessary.

        @param owner: origin?
        @type owner: L{bytes}

        @param ttl: time to live for the record
        @type ttl: L{int}

        @param domain: the domain for which the record is to be added
        @type domain: L{bytes}

        @param type: record type
        @type type: L{str}

        @param cls: record class
        @type cls: L{str}

        @param rdata: record data
        @type rdata: L{list} of L{bytes}
        rs   Nr}   zclass_%szRecord class %r not supported)endswithrp   r   )r*   ownerr:   r0   domainrL   rdatar    r!   r!   r"   	addRecord  s    
zBindAuthority.addRecordc                 C   sj   t tdt|f d}|rT|| }||_| j| g | |dkrf||f| _nt	dt|f dS )a>  
        Simulate a class IN and recurse into the actual class.

        @param ttl: time to live for the record
        @type ttl: L{int}

        @param type: record type
        @type type: str

        @param domain: the domain
        @type domain: bytes

        @param rdata:
        @type rdate: bytes
        z	Record_%sNrG   zRecord type %r not supported)
rp   r   r
   r:   r3   rb   r5   rD   r@   r   )r*   r:   r0   r   r   r<   r   r!   r!   r"   class_IN  s    zBindAuthority.class_INc                 C   s  t r6tdd tj D }tdd tj D }nttj }ttj }||B }d}|}|d dkr|dd }|}n,|d  s|d |kr|d }|dd }|d  s|d |kr|}	|}n|d }	|dd }|d |kr,|d }|dd }|d  rtt|d }|dd }nH|d  rtt|d }|dd }|d |krt|d }|dd }|d }
|dd }| ||t	|
|	t	|| dS )	a  
        Parse a C{line} from a zone file respecting C{origin} and C{ttl}.

        Add resulting records to authority.

        @param origin: starting point for the zone
        @type origin: L{bytes}

        @param ttl: time to live for the record
        @type ttl: L{int}

        @param line: zone file line to parse; split by word
        @type line: L{list} of L{bytes}
        c                 s   s   | ]}| d V  qdS asciiNencode)rm   Zqcr!   r!   r"   r     s    z0BindAuthority.parseRecordLine.<locals>.<genexpr>c                 s   s   | ]}| d V  qdS r   r   )rm   Zqtr!   r!   r"   r     s    s   INr      @r   N)
r   setr   ZQUERY_CLASSESvaluesZQUERY_TYPESisdigitr   r   r
   )r*   ru   r:   r   ZqueryClassesZ
queryTypesZmarkersrL   r   r   r0   r   r!   r!   r"   r     sZ    
     zBindAuthority.parseRecordLineN)rY   rZ   r[   r\   r(   rw   rx   ry   r   r   r   r!   r!   r!   r"   rr   %  s   #rr   )r   )r\   Z
__future__r   r   r   r   Ztwisted.namesr   r   r   Ztwisted.internetr   Ztwisted.pythonr   Ztwisted.python.compatr	   r
   r   Ztwisted.python.filepathr   r#   r&   r$   r^   rr   r!   r!   r!   r"   <module>   s   
% K 