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>)mismatched_id)errors)_find_matchesappenderror_on_mismatch_contains_instance_ofpattern_classr   )cert_patternsobligatory_idsoptional_idsr   matches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$   service_idsr'   sid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)seq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$   

r@   F)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/   r6   	TypeErrorstripr@   r   format	translate_TRANS_TO_LOWERr?   _validate_patternselfr?   r   r   r   __init__   s   

zDNSPattern.__init__N)r   r   r   r   r   r   r?   recompile_RE_LEGAL_CHARSrP   r   r   r   r   rB      s
    
rB   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 )Nr>   z Invalid IP address pattern {!r}.)r;   r<   r:   r   rJ   )clsbsr   r   r   
from_bytes   s   zIPAddressPattern.from_bytesN)	r   r   r   r   r   r   r?   classmethodrW   r   r   r   r   rT      s
    rT   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 )rD   z'The URI pattern must be a bytes string.   :rG   zInvalid URI pattern {0!r}.N)r/   r6   rH   rI   rK   rL   r@   r   rJ   splitprotocol_patternrB   dns_pattern)rO   r?   hostnamer   r   r   rP      s   
zURIPattern.__init__N)	r   r   r   r   r   r   r]   r^   rP   r   r   r   r   rZ      
    rZ   c                   @   rY   )
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 )	rD   z'The SRV pattern must be a bytes string.r   _      .rG   zInvalid SRV pattern {0!r}.r   N)r/   r6   rH   rI   rK   rL   r@   r   rJ   r\   name_patternrB   r^   )rO   r?   namer_   r   r   r   rP      s"   

zSRVPattern.__init__N)	r   r   r   r   r   r   rd   r^   rP   r   r   r   r   ra      r`   ra   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.
    rC   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.r3   N)r/   r   rH   rI   r@   r:   anyidnaencodeImportErrorrK   rL   r_   rS   r   )rO   r_   ascii_idr   r   r   rP      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_matchesr?   r_   rN   r   r   r   r+     s   zDNS_ID.verifyN)r   r   r   r   r   r   r_   rQ   rR   rS   rB   r#   r	   r!   rP   r+   r   r   r   r   rf      s    
rf   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.
    )	converterc                 C   s   | j |jkS )zC
        https://tools.ietf.org/search/rfc2818#section-3.1
        )ipr?   rN   r   r   r   r+   ,  s   zIPAddress_ID.verifyN)r   r   r   r   r   r   r;   r<   rt   rT   r#   r
   r!   r+   r   r   r   r   rr   !  s    rr   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.r3   /N)r/   r   rH   rI   r@   r:   r\   rn   rK   rL   protocolrf   dns_id)rO   uriprotr_   r   r   r   rP   ?  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#   r]   ry   rz   r+   r^   rN   r   r   r   r+   O  s
   zURI_ID.verifyN)r   r   r   r   r   r   ry   rz   rZ   r#   r   r!   rP   r+   r   r   r   r   rv   3      rv   c                   @   ru   )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   Nr3   )r/   r   rH   rI   r@   r:   r\   rn   rK   rL   re   rf   rz   )rO   srvre   r_   r   r   r   rP   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#   re   rd   rz   r+   r^   rN   r   r   r   r+   x  s
   zSRV_ID.verifyN)r   r   r   r   r   r   re   rz   ra   r#   r   r!   rP   r+   r   r   r   r   r~   \  r}   r~   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`
    rG   rc   r   Fs   xn--)r\   
startswith)r   actual_hostname	cert_head	cert_tailactual_headactual_tailr   r   r   rq     s   
rq   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
    rG   r   z7Certificate's DNS-ID {0!r} contains too many wildcards.rc      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   rk     s    z$_validate_pattern.<locals>.<genexpr>z0Certificate's DNS-ID {0!r} contains empty parts.N)countr   rJ   r\   r   rl   )r   cntpartsr   r   r   rM     s2   
	
rM   s   ABCDEFGHIJKLMNOPQRSTUVWXYZs   abcdefghijklmnopqrstuvwxyz)&r   
__future__r   r   r   r;   rQ   r   _compatr   r   
exceptionsr   r	   r
   r   r   r   rm   ro   sobjectr   r*   r   r"   r@   rB   rT   rZ   ra   rf   rr   rv   r~   rq   rM   rL   r   r   r   r   <module>   sN     

	"

/('%