U
    g                     @  s   d Z ddlmZ ddlZddlZddlZddlmZmZ ejrJddl	m
Z
 dZG dd	 d	eZdd
ddddddZddddddZddddddddZdS )zHThe match_hostname() function from Python 3.5, essential when using SSL.    )annotationsN)IPv4AddressIPv6Address   )_TYPE_PEER_CERT_RET_DICTz3.5.0.1c                   @  s   e Zd ZdS )CertificateErrorN)__name__
__module____qualname__ r   r   C/tmp/pip-unpacked-wheel-f4zjg0cl/urllib3/util/ssl_match_hostname.pyr      s   r   z
typing.Anystrintztyping.Match[str] | None | bool)dnhostnamemax_wildcardsreturnc           
      C  s   g }| sdS |  d}|d }|dd }|d}||krLtdt|  |sdt|  | kS |dkrx|d n>|d	s|d	r|t	| n|t	|
d
d |D ]}|t	| qtdd| d tj}	|	|S )zhMatching according to RFC 6125, section 6.4.3

    http://tools.ietf.org/html/rfc6125#section-6.4.3
    F.r   r   N*z,too many wildcards in certificate DNS name: z[^.]+zxn--z\*z[^.]*z\Az\.z\Z)splitcountr   reprboollowerappend
startswithreescapereplacecompilejoin
IGNORECASEmatch)
r   r   r   patspartsleftmost	remainder	wildcardsfragpatr   r   r   _dnsname_match   s,    


r*   zIPv4Address | IPv6Addressr   )ipnamehost_ipr   c                 C  s   t |  }t|j|jkS )a  Exact matching of IP addresses.

    RFC 9110 section 4.3.5: "A reference identity of IP-ID contains the decoded
    bytes of the IP address. An IP version 4 address is 4 octets, and an IP
    version 6 address is 16 octets. [...] A reference identity of type IP-ID
    matches if the address is identical to an iPAddress value of the
    subjectAltName extension of the certificate."
    )	ipaddress
ip_addressrstripr   packed)r+   r,   ipr   r   r   _ipaddress_matchP   s    r2   Fz_TYPE_PEER_CERT_RET_DICT | NoneNone)certr   hostname_checks_common_namer   c           	      C  s  | st dz0d|kr0t|d|d }n
t|}W n t k
rT   d}Y nX g }| dd}|D ]^\}}|dkr|dkrt||r dS || qj|dkrj|dk	rt||r dS || qj|r&|dkr&|s&| ddD ]8}|D ].\}}|d	krt||r  dS || qqt|d
krRt	d|d
tt|f n0t|d
krzt	d|d|d nt	ddS )a)  Verify that *cert* (in decoded format as returned by
    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
    rules are followed, but IP addresses are not accepted for *hostname*.

    CertificateError is raised on failure. On success, the function
    returns nothing.
    ztempty or no certificate, match_hostname needs a SSL socket or SSL context with either CERT_OPTIONAL or CERT_REQUIRED%NsubjectAltNamer   DNSz
IP Addresssubject
commonNamer   z&hostname %r doesn't match either of %sz, z	hostname z doesn't match r   z/no appropriate subjectAltName fields were found)
ValueErrorr-   r.   rfindgetr*   r   r2   lenr   r    mapr   )	r4   r   r5   r,   dnsnamessankeyvaluesubr   r   r   match_hostname_   sJ    
rE   )r   )F)__doc__
__future__r   r-   r   typingr   r   TYPE_CHECKINGssl_r   __version__r;   r   r*   r2   rE   r   r   r   r   <module>   s    8 