o
    ֞\.                     @   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yA   dZY nw 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 ]}||vr$||j|d q|D ]}||vr<t| |jr<||j|d q'|rDt|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rz| d} W n
 ty   Y dS w zt|  W dS  ty'   Y nw zt| dd W dS  ty>   Y dS w )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   sh   t |ts	td| }|dkst|sd|v r td||t| _	d| j	v r2t
| j	 dS 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   s0   z	| t |dW S  ty   td|w )Nr6   z Invalid IP address pattern {!r}.)r3   r4   r2   r   rA   )clsbsr   r   r   
from_bytes   s   zIPAddressPattern.from_bytesN)	r   r   r   r   r   r   r7   classmethodrN   r   r   r   r   rK      s
    rK   c                   @   (   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|vsd|v st|r#t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   rT   rU   rG   r   r   r   r   rQ      
    rQ   c                   @   rP   )
SRVPatternz8
    An SRV pattern as extracted from certificates.
    c                 C   s~   t |ts	td| t}|d dks"d|vs"d|v s"t|r)t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   rS   name_patternr9   rU   )rF   r7   namerV   r   r   r   rG      s"   

zSRVPattern.__init__N)	r   r   r   r   r   r   r[   rU   rG   r   r   r   r   rX      rW   rX   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|rtdtdd |D r.tr*t|}n	t	d|d}|
t| _| j| jdu rFt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   rV   rJ   r   )rF   rV   Zascii_idr   r   r   rG      s    

zDNS_ID.__init__c                 C   s   t || jrt|j| jS dS )zC
        https://tools.ietf.org/search/rfc6125#section-6.4
        F)r(   r"   _hostname_matchesr7   rV   rE   r   r   r   r'     s   zDNS_ID.verifyN)r   r   r   r   r   r   rV   rH   rI   rJ   r9   r"   r	   r    rG   r'   r   r   r   r   r]      s    
r]   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   ri   rK   r"   r
   r    r'   r   r   r   r   rh   !  s    rh   c                   @   8   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|vst|rt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   rS   re   rB   rC   protocolr]   dns_id)rF   ZuriZprotrV   r   r   r   rG   ?  s   
zURI_ID.__init__c                 C   s*   t || jr|j| jko| j|jS dS )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.2
        F)r(   r"   rT   rn   ro   r'   rU   rE   r   r   r   r'   O  s
   zURI_ID.verifyN)r   r   r   r   r   r   rn   ro   rQ   r"   r   r    rG   r'   r   r   r   r   rk   3      rk   c                   @   rj   )SRV_IDz
    An SRV service ID.
    c                 C   sv   t |ts	td| }d|vst|s|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   rS   re   rB   rC   r\   r]   ro   )rF   Zsrvr\   rV   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 )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.1
        F)r(   r"   r\   r[   ro   r'   rU   rE   r   r   r   r'   x  s
   zSRV_ID.verifyN)r   r   r   r   r   r   r\   ro   rX   r"   r   r    rG   r'   r   r   r   r   rq   \  rp   rq   c                 C   sZ   d| v r)|  dd\}}| dd\}}||krdS |dr!dS |dkp(||kS | |kS )z
    :type cert_pattern: `bytes`
    :type actual_hostname: `bytes`

    :return: `True` if *cert_pattern* matches *actual_hostname*, else `False`.
    :rtype: `bool`
    r>   rZ   r   Fs   xn--)rS   
startswith)r   Zactual_hostnameZ	cert_headZ	cert_tailZactual_headZactual_tailr   r   r   rg     s   
rg   c                 C   s   |  d}|dkrtd| | d}t|dk r"td| d|d v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.rZ      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   rb     s    z$_validate_pattern.<locals>.<genexpr>z0Certificate's DNS-ID {0!r} contains empty parts.N)countr   rA   rS   rv   rc   )r   Zcntpartsr   r   r   rD     s2   
	
rD   s   ABCDEFGHIJKLMNOPQRSTUVWXYZs   abcdefghijklmnopqrstuvwxyz)&r   Z
__future__r   r   r   r3   rH   r   Z_compatr   r   
exceptionsr   r	   r
   r   r   r   rd   rf   sobjectr   r&   r   r!   r8   r9   rK   rQ   rX   r]   rh   rk   rq   rg   rD   rC   r   r   r   r   <module>   sN     

	"

/('%