U
    ֞\.                     @   s  d Z ddlmZmZmZ ddlZddlZddlZddlm	Z	m
Z
 ddlmZmZmZmZmZmZ zddlZW n ek
r   dZY nX ejddG d	d
 d
eZdd Zdd Zdd Zdd ZejdddG dd deZejddG dd deZejdddG dd deZejdddG dd deZejdddG dd deZejddG dd  d eZ ejdddG d!d" d"eZ!ejdddG d#d$ d$eZ"d%d& Z#d'd( Z$e	d)d*Z%dS )+z
Common verification code.
    )absolute_importdivisionprint_functionN   )	maketrans	text_type)CertificateErrorDNSMismatchIPAddressMismatchSRVMismatchURIMismatchVerificationErrorT)slotsc                   @   s    e Zd ZdZe Ze ZdS )ServiceMatchz<
    A match of a service id and a certificate pattern.
    N)__name__
__module____qualname____doc__attrib
service_idcert_pattern r   r   :/usr/lib/python3/dist-packages/service_identity/_common.pyr      s   r   c                 C   s   g }t | |t | | }dd |D }|D ]}||kr*||j|d q*|D ]*}||krNt| |jrN||j|d qN|rt|d|S )z
    Verify whether *cert_patterns* are valid for *obligatory_ids* and
    *optional_ids*.

    *obligatory_ids* must be both present and match.  *optional_ids* must match
    if a pattern of the respective type is present.
    c                 S   s   g | ]
}|j qS r   )r   ).0matchr   r   r   
<listcomp>4   s     z+verify_service_identity.<locals>.<listcomp>)Zmismatched_id)errors)_find_matchesappenderror_on_mismatch_contains_instance_ofpattern_classr   )cert_patternsZobligatory_idsZoptional_idsr   matchesZmatched_idsir   r   r   verify_service_identity'   s$    
 
 
r&   c                 C   s8   g }|D ]*}| D ] }| |r|t||d qq|S )a  
    Search for matching certificate patterns and service_ids.

    :param cert_ids: List certificate IDs like DNSPattern.
    :type cert_ids: `list`

    :param service_ids: List of service IDs like DNS_ID.
    :type service_ids: `list`

    :rtype: `list` of `ServiceMatch`
    )r   r   )verifyr   r   )r#   Zservice_idsr$   ZsidZcidr   r   r   r   I   s    
r   c                 C   s   | D ]}t ||r dS qdS )zB
    :type seq: iterable
    :type cl: type

    :rtype: bool
    TF)
isinstance)seqZcler   r   r   r!   ]   s    
r!   c                 C   s   t | tr0z| d} W n tk
r.   Y dS X zt|  W dS  tk
rR   Y nX zt| dd W n tk
r   Y dS X dS )z
    Check whether *pattern* could be/match an IP address.

    :param pattern: A pattern for a host name.
    :type pattern: `bytes` or `unicode`

    :return: `True` if *pattern* could be an IP address, else `False`.
    :rtype: bool
    asciiFT*1)	r(   bytesdecodeUnicodeErrorint
ValueError	ipaddress
ip_addressreplacepatternr   r   r   _is_ip_addressj   s    

r8   F)Zinitr   c                   @   s*   e Zd ZdZe ZedZ	dd Z
dS )
DNSPatternz7
    A DNS pattern as extracted from certificates.
       ^[a-z0-9\-_.]+$c                 C   sd   t |tstd| }|dks2t|s2d|kr@td||t| _	d| j	kr`t
| j	 dS )(
        :type pattern: `bytes`
        z'The DNS pattern must be a bytes string.        zInvalid DNS pattern {0!r}.   *N)r(   r.   	TypeErrorstripr8   r   format	translate_TRANS_TO_LOWERr7   _validate_patternselfr7   r   r   r   __init__   s    

zDNSPattern.__init__N)r   r   r   r   r   r   r7   recompile_RE_LEGAL_CHARSrG   r   r   r   r   r9      s   
r9   c                   @   s$   e Zd ZdZe Zedd ZdS )IPAddressPatternz?
    An IP address pattern as extracted from certificates.
    c                 C   s:   z| t |dW S  tk
r4   td|Y nX d S )Nr6   z Invalid IP address pattern {!r}.)r3   r4   r2   r   rA   )clsZbsr   r   r   
from_bytes   s    zIPAddressPattern.from_bytesN)	r   r   r   r   r   r   r7   classmethodrM   r   r   r   r   rK      s   rK   c                   @   s(   e Zd ZdZe Ze Zdd ZdS )
URIPatternz8
    An URI pattern as extracted from certificates.
    c                 C   sd   t |tstd| t}d|ks8d|ks8t|rFtd||	d\| _
}t|| _dS )r;   z'The URI pattern must be a bytes string.   :r>   zInvalid URI pattern {0!r}.N)r(   r.   r?   r@   rB   rC   r8   r   rA   splitprotocol_patternr9   dns_pattern)rF   r7   hostnamer   r   r   rG      s    
zURIPattern.__init__N)	r   r   r   r   r   r   rR   rS   rG   r   r   r   r   rO      s   rO   c                   @   s(   e Zd ZdZe Ze Zdd ZdS )
SRVPatternz8
    An SRV pattern as extracted from certificates.
    c                 C   s~   t |tstd| t}|d dksDd|ksDd|ksDt|rRtd||	dd\}}|dd | _
t|| _dS )	r;   z'The SRV pattern must be a bytes string.r   _      .r>   zInvalid SRV pattern {0!r}.r   N)r(   r.   r?   r@   rB   rC   r8   r   rA   rQ   name_patternr9   rS   )rF   r7   namerT   r   r   r   rG      s"    

zSRVPattern.__init__N)	r   r   r   r   r   r   rX   rS   rG   r   r   r   r   rU      s   rU   c                   @   s:   e Zd ZdZe ZedZ	e
ZeZdd Zdd ZdS )DNS_IDz)
    A DNS service ID, aka hostname.
    r:   c                 C   s   t |tstd| }|dks*t|r2tdtdd |D r^trTt|}qht	dn
|d}|
t| _| j| jdkrtddS )	z+
        :type hostname: `unicode`
        z DNS-ID must be a unicode string. zInvalid DNS-ID.c                 s   s   | ]}t |d kV  qdS )   N)ord)r   cr   r   r   	<genexpr>	  s     z"DNS_ID.__init__.<locals>.<genexpr>z+idna library is required for non-ASCII IDs.r+   N)r(   r   r?   r@   r8   r2   anyidnaencodeImportErrorrB   rC   rT   rJ   r   )rF   rT   Zascii_idr   r   r   rG      s    

zDNS_ID.__init__c                 C   s"   t || jrt|j| jS dS dS )zC
        https://tools.ietf.org/search/rfc6125#section-6.4
        FN)r(   r"   _hostname_matchesr7   rT   rE   r   r   r   r'     s    zDNS_ID.verifyN)r   r   r   r   r   r   rT   rH   rI   rJ   r9   r"   r	   r    rG   r'   r   r   r   r   rZ      s   
rZ   c                   @   s.   e Zd ZdZejejdZe	Z
eZdd ZdS )IPAddress_IDz#
    An IP address service ID.
    )Z	converterc                 C   s   | j |jkS )zC
        https://tools.ietf.org/search/rfc2818#section-3.1
        )ipr7   rE   r   r   r   r'   ,  s    zIPAddress_ID.verifyN)r   r   r   r   r   r   r3   r4   rf   rK   r"   r
   r    r'   r   r   r   r   re   !  s
   re   c                   @   s8   e Zd ZdZe Ze ZeZ	e
Zdd Zdd ZdS )URI_IDz
    An URI service ID.
    c                 C   sf   t |tstd| }d|ks*t|r2td|d\}}|dt	| _
t|d| _dS )z&
        :type uri: `unicode`
        z URI-ID must be a unicode string.:zInvalid URI-ID.r+   /N)r(   r   r?   r@   r8   r2   rQ   rb   rB   rC   protocolrZ   dns_id)rF   ZuriZprotrT   r   r   r   rG   ?  s    
zURI_ID.__init__c                 C   s.   t || jr&|j| jko$| j|jS dS dS )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.2
        FN)r(   r"   rR   rj   rk   r'   rS   rE   r   r   r   r'   O  s
    zURI_ID.verifyN)r   r   r   r   r   r   rj   rk   rO   r"   r   r    rG   r'   r   r   r   r   rg   3  s   rg   c                   @   s8   e Zd ZdZe Ze ZeZ	e
Zdd Zdd ZdS )SRV_IDz
    An SRV service ID.
    c                 C   sv   t |tstd| }d|ks6t|s6|d dkr>td|dd\}}|dd dt	| _
t|| _dS )	z&
        :type srv: `unicode`
        z SRV-ID must be a unicode string..r   _zInvalid SRV-ID.r   Nr+   )r(   r   r?   r@   r8   r2   rQ   rb   rB   rC   rY   rZ   rk   )rF   ZsrvrY   rT   r   r   r   rG   h  s    
zSRV_ID.__init__c                 C   s.   t || jr&| j|jko$| j|jS dS dS )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.1
        FN)r(   r"   rY   rX   rk   r'   rS   rE   r   r   r   r'   x  s
    zSRV_ID.verifyN)r   r   r   r   r   r   rY   rk   rU   r"   r   r    rG   r'   r   r   r   r   rl   \  s   rl   c                 C   s^   d| krR|  dd\}}| dd\}}||kr4dS |drBdS |dkpP||kS | |kS dS )z
    :type cert_pattern: `bytes`
    :type actual_hostname: `bytes`

    :return: `True` if *cert_pattern* matches *actual_hostname*, else `False`.
    :rtype: `bool`
    r>   rW   r   Fs   xn--N)rQ   
startswith)r   Zactual_hostnameZ	cert_headZ	cert_tailZactual_headZactual_tailr   r   r   rd     s    
rd   c                 C   s   |  d}|dkr td| | d}t|dk rDtd| d|d kr^td| td	d
 |D r~td| dS )z
    Check whether the usage of wildcards within *cert_pattern* conforms with
    our expectations.

    :type hostname: `bytes`

    :return: None
    r>   r   z7Certificate's DNS-ID {0!r} contains too many wildcards.rW      zJCertificate's DNS-ID {0!r} has too few host components for wildcard usage.r   zECertificate's DNS-ID {0!r} has a wildcard outside the left-most part.c                 s   s   | ]}t | V  qd S )N)len)r   pr   r   r   r_     s     z$_validate_pattern.<locals>.<genexpr>z0Certificate's DNS-ID {0!r} contains empty parts.N)countr   rA   rQ   rq   r`   )r   Zcntpartsr   r   r   rD     s4    	

rD   s   ABCDEFGHIJKLMNOPQRSTUVWXYZs   abcdefghijklmnopqrstuvwxyz)&r   Z
__future__r   r   r   r3   rH   r   Z_compatr   r   
exceptionsr   r	   r
   r   r   r   ra   rc   sobjectr   r&   r   r!   r8   r9   rK   rO   rU   rZ   re   rg   rl   rd   rD   rC   r   r   r   r   <module>   sL    


	"
/
('% 