o
    ¯b+A  ã                   @   sœ   d Z ddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
 ddl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.
é    N)Údefer)ÚcommonÚdnsÚerror)Úfailure)ÚexecfileÚnativeString)ÚFilePathú/tmp/twisted-names.serialc              	   C   s  t  d¡}t d¡}z)tj | ¡s-t| dƒ}| |d ¡ W d  ƒ n1 s(w   Y  W t |¡ nt |¡ w t| ƒ}| ¡  	¡ \}}W d  ƒ n1 sQw   Y  ||kr`t
|ƒd pad}t| dƒ}| d||f ¡ W d  ƒ n1 s{w   Y  |d	|f  }|S )
aÛ  
    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.

    This manipulates process-global state by calling C{os.umask()}, so it isn't
    thread-safe.

    @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 0Né   r   z%s %dz%02d)ÚtimeÚstrftimeÚosÚumaskÚpathÚexistsÚopenÚwriteÚreadlineÚsplitÚint)ÚfilenameÚserialÚoÚfÚ
serialFileÚ
lastSerialÚzoneID© r    ú9/usr/lib/python3/dist-packages/twisted/names/authority.pyÚ	getSerial   s$   

ÿ€
ÿÿr"   c                   @   sp   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
„ Zddd„Zddd„Zdd„ ZdS )ÚFileAuthoritya­  
    An Authority that is loaded from a file.

    This is an abstract class that implements record search logic. To create
    a functional resolver, subclass it and override the L{loadFile} method.

    @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}.

    @ivar records: A mapping of domains (as lowercased L{bytes}) to records.
    @type records: L{dict} with L{bytes} keys
    Nc                 C   s    t j | ¡ |  |¡ i | _d S ©N)r   ÚResolverBaseÚ__init__ÚloadFileÚ_cache©Úselfr   r    r    r!   r&   V   s   

zFileAuthority.__init__c                 C   s
   || _ d S r$   )Ú__dict__)r*   Ústater    r    r!   Ú__setstate__[   s   
zFileAuthority.__setstate__c                 C   s   dS )ab  
        Load DNS records from a file.

        This method populates the I{soa} and I{records} attributes. It must be
        overridden in a subclass. It is called once from the initializer.

        @param filename: The I{filename} parameter that was passed to the
        initilizer.

        @returns: L{None} -- the return value is ignored
        Nr    r)   r    r    r!   r'   ^   s    zFileAuthority.loadFilec              
   c   sp    || D ]0}|j | jv r5|jjj}| j | ¡ d¡D ]}|j| jv r4t	j
||jt	j|jp.||ddV  qq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_TYPESÚpayloadÚnameÚrecordsÚgetÚlowerÚTYPEÚ_ADDRESS_TYPESr   ÚRRHeaderÚINÚttl)r*   ÚanswerÚ	authorityr;   Úrecordr3   Úrecr    r    r!   Ú_additionalRecordsk   s   €
ÿ€ûz FileAuthority._additionalRecordsc                 C   s´  g }g }g }g }t | jd j| jd jƒ}	| j | ¡ ¡}
|
r»|
D ]_}|jdur,|j}n|	}|jt	j
krP| ¡ | jd  ¡ krP| t	j||jt	j||dd¡ n|j|ksZ|t	jkrj| t	j||jt	j||dd¡ |jt	jkr€| t	j||jt	j||dd¡ q!|s…|}|  |||	¡}|r”| |¡ n| |¡ |s³|s³| t	j| jd t	jt	j|| jd dd¡ t |||f¡S t	 || jd ¡rÏt t t	 |¡¡¡S t t t |¡¡¡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Úexpirer4   r5   r6   r;   r7   r   ÚNSÚappendr9   r:   ÚALL_RECORDSÚCNAMEr@   ÚextendÚSOAr   ÚsucceedÚ_isSubdomainOfÚfailr   ÚFailureÚAuthoritativeDomainErrorr   ÚDomainError)r*   r3   Úclsr0   ÚtimeoutÚcnamesÚresultsr=   Ú
additionalÚdefault_ttlÚdomain_recordsr>   r;   ÚadditionalInformationr    r    r!   Ú_lookup‰   sT   
"ÿÿÿ€ÿ
ÿÿzFileAuthority._lookupé
   c           
      C   s  t  |¡}| jd  ¡ | ¡ krt| jd j| jd jƒ}| jd jd ur,| jd j}n|}t j| jd t j	t j
|| jd ddg}| j ¡ D ]*\}}|D ]#}|jd urX|j}	n|}	|jt j	krp| t j||jt j
|	|dd¡ qMqG| |d ¡ t |ddf¡S t t t  |¡¡¡S )Nr   r   Tr.   r    )r   ÚdomainStringrB   r6   rA   rC   rD   r;   r9   rJ   r:   r4   Úitemsr7   rF   r   rK   rM   r   rN   rP   )
r*   r3   rR   rV   Úsoa_ttlrT   ÚkÚrr?   r;   r    r    r!   Ú
lookupZoneâ   s0   
ÿÿ
ÿ€ú	zFileAuthority.lookupZonec                 C   sb   g g g }}}|D ]!}|d r+|  |d d ¡ |  |d d ¡ |  |d d ¡ q
|||fS )Nr   r   é   )rI   )r*   rT   Úansr/   ÚaddÚresr    r    r!   Ú_cbAllRecordsþ   s   €
zFileAuthority._cbAllRecordsr$   )rZ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rH   ÚMXrE   r1   ÚAÚAAAAr8   rB   r4   r&   r-   r'   r@   rY   r`   re   r    r    r    r!   r#   ;   s    

Y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|vrtd| ƒ‚i | _|d D ]}t|d tjƒr+|| _| j |d  	¡ g ¡ 
|d ¡ qd S )NÚzonezNo zone defined in r   r   )ÚsetupConfigNamespacer   Ú
ValueErrorr4   Ú
isinstancer   Ú
Record_SOArB   Ú
setdefaultr6   rF   )r*   r   ÚgÚlÚrrr    r    r!   r'     s   "ýzPySourceAuthority.loadFilec                    s   ‡ fdd„}|S )Nc                    s   t  | ¡ˆ |i |¤ŽfS r$   )r   r[   )r3   ÚargÚkw©r0   r    r!   ÚwrapRecordFunc  s   z4PySourceAuthority.wrapRecord.<locals>.wrapRecordFuncr    )r*   r0   rz   r    ry   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>r|   )r   r+   ÚkeysÚgetattrr{   Úlen)r*   r_   r\   r>   r0   r   r    r    r!   ro     s   


z&PySourceAuthority.setupConfigNamespaceN)rf   rg   rh   ri   r'   r{   ro   r    r    r    r!   rm     s
    rm   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ÚoriginÚ
getContentÚ
splitlinesÚstripCommentsÚcollapseContinuationsÚ
parseLines)r*   r   ÚfpÚlinesr    r    r!   r'   1  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   s4    | ]}|  d ¡dkr|p|d|  d ¡… V  qdS )ó   ;éÿÿÿÿN)Úfind)r~   Úar    r    r!   Ú	<genexpr>K  s
   € "ÿ
ÿz.BindAuthority.stripComments.<locals>.<genexpr>c                 S   s   g | ]}|  ¡ ‘qS r    )Ústrip)r~   Úbr    r    r!   r€   M  s    z/BindAuthority.stripComments.<locals>.<listcomp>r    )r*   rŽ   r    r    r!   rŠ   B  s   	þzBindAuthority.stripCommentsc              
   C   s°   g }d}|D ]G}|dkr(|  d¡dkr| |¡ q| |d|  d¡… ¡ d}q|  d¡dkrC|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   )r~   Úliner    r    r!   r“   h  s   € z6BindAuthority.collapseContinuations.<locals>.<genexpr>)r‘   rF   Úfilter)r*   rŽ   ru   r,   r™   r    r    r!   r‹   P  s   	"z#BindAuthority.collapseContinuationsc                 C   sŒ   d}| j }i | _|D ]6}|d dkrt |d ¡}q
|d dkr%|d }q
|d dkr/tdƒ‚|d dkr9td	ƒ‚|  |||¡ 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)r‡   r4   r   Ústr2timeÚNotImplementedErrorÚparseRecordLine)r*   rŽ   r;   r‡   r™   r    r    r!   rŒ   j  s   

zBindAuthority.parseLinesc                 C   sd   |  d¡s|d |dd…  }n|dd… }t| d|› dƒ}|r*|||||ƒ dS td|›dƒ‚)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}
        r…   Nr   Úclass_zRecord class ú not supported)Úendswithr‚   rœ   )r*   Úownerr;   r0   ÚdomainrQ   Úrdatar   r    r    r!   Ú	addRecord…  s   
zBindAuthority.addRecordc                 C   sn   t tdt|ƒ› dƒ}|r-||Ž }||_| j | ¡ g ¡ |¡ |dkr+||f| _dS dS t	dt|ƒ›dƒ‚)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 rdata: bytes
        r|   NrJ   zRecord type rŸ   )
r‚   r   r   r;   r4   rs   r6   rF   rB   rœ   )r*   r;   r0   r¢   r£   r>   r_   r    r    r!   Úclass_IN¥  s   ÿÿzBindAuthority.class_INc                 C   sv  dd„ t j ¡ D ƒ}dd„ t j ¡ D ƒ}||B }d}|}|d dkr+|dd… }|}n|d  ¡ sA|d |vrA|d }|dd… }|d  ¡ sM|d |v rR|}	|}n
|d }	|dd… }|d |v r|d }|dd… }|d  ¡ r~t|d ƒ}|dd… }n"|d  ¡ r¡t|d ƒ}|dd… }|d |v r¡|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   ó   h | ]}|  d ¡’qS ©Úascii©Úencode)r~   Úqcr    r    r!   Ú	<setcomp>Ñ  ó    z0BindAuthority.parseRecordLine.<locals>.<setcomp>c                 S   r¦   r§   r©   )r~   Úqtr    r    r!   r¬   Ò  r­   s   INr   ó   @r   N)r   ÚQUERY_CLASSESÚvaluesÚQUERY_TYPESÚisdigitr   r¤   r   )r*   r‡   r;   r™   ÚqueryClassesÚ
queryTypesÚmarkersrQ   r¡   r¢   r0   r£   r    r    r!   r   Â  s@   € zBindAuthority.parseRecordLineN)rf   rg   rh   ri   r'   rŠ   r‹   rŒ   r¤   r¥   r   r    r    r    r!   r„   )  s     r„   )r
   )ri   r   r   Útwisted.internetr   Útwisted.namesr   r   r   Útwisted.pythonr   Útwisted.python.compatr   r   Útwisted.python.filepathr	   r"   r%   r#   rm   r„   r    r    r    r!   Ú<module>   s   
' N!