3
]ð]E  ã               @   sˆ   d dl Z d dlZyd dlmZ W n ek
r<   dd„ ZY nX ejd  dk rReZndd„ ZG dd„ deƒZ	dd
d„Z
dd„ Zdd„ ZdS )é    N)Ú
ip_addressc             C   s   d S )N© )Úaddressr   r   ú=/tmp/pip-build-20mum3z4/pymongo/pymongo/ssl_match_hostname.pyÚ<lambda>   s    r   é   c             C   s   | S )Nr   )Úvaluer   r   r   r      s    c               @   s   e Zd ZdS )ÚCertificateErrorN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r	      s   r	   é   c       
      C   sö   g }| sdS | j dƒ}|d }|dd… }|jdƒ}||krLtdt| ƒ ƒ‚|s`| jƒ |jƒ kS |dkrt|jdƒ n>|jd	ƒsˆ|jd	ƒrš|jtj|ƒƒ n|jtj|ƒj	d
dƒƒ x|D ]}|jtj|ƒƒ q¸W tj
ddj|ƒ d tjƒ}	|	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ÚlowerÚappendÚ
startswithÚreÚescapeÚreplaceÚcompileÚjoinÚ
IGNORECASEÚmatch)
ÚdnÚhostnameÚmax_wildcardsÚpatsÚpartsÚleftmostÚ	remainderÚ	wildcardsÚfragÚpatr   r   r   Ú_dnsname_match   s*    


r'   c             C   s   t t| ƒjƒ ƒ}||kS )zˆExact matching of IP addresses.

    RFC 6125 explicitly doesn't define an algorithm for this
    (section 1.7.2 - "Out of Scope").
    )r   Ú_unicodeÚrstrip)ÚipnameÚhost_ipÚipr   r   r   Ú_ipaddress_matchK   s    r-   c             C   sV  | st dƒ‚ytt|ƒƒ}W n t tfk
r8   d}Y nX g }| jdf ƒ}xb|D ]Z\}}|dkr‚|dkrvt||ƒrvdS |j|ƒ qP|dkrP|dk	r t||ƒr dS |j|ƒ qPW |súxF| jdf ƒD ]6}x0|D ](\}}|dkrÊt||ƒrèdS |j|ƒ qÊW qÀW t|ƒdk�r&t	d	|d
j
tt|ƒƒf ƒ‚n,t|ƒdk�rJt	d||d f ƒ‚nt	dƒ‚dS )z÷Verify that *cert* (in decoded format as returned by
    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
    rules are followed.

    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_REQUIREDNÚsubjectAltNameÚDNSz
IP AddressÚsubjectÚ
commonNamer   z&hostname %r doesn't match either of %sz, zhostname %r doesn't match %rr   z=no appropriate commonName or subjectAltName fields were found)Ú
ValueErrorr   r(   ÚUnicodeErrorÚgetr'   r   r-   Úlenr	   r   Úmapr   )Úcertr   r+   ÚdnsnamesÚsanÚkeyr   Úsubr   r   r   Úmatch_hostnameV   s>    

r<   )r   )r   ÚsysÚ	ipaddressr   ÚImportErrorÚversion_infoÚunicoder(   r2   r	   r'   r-   r<   r   r   r   r   Ú<module>   s   
3