B
    ÐH/\ßi  ã            	   @   s\  d Z ddlmZ ddlZejZddlZddlmZm	Z	 ddlm
Z ddlmZ ddlmZ ddlmZ d	d
ddgZeeeƒ edg ddZee Zdekr¤e d¡ ejZG dd	„ d	eƒZG dd„ dejƒZyeZW n ek
rè   Y nX eedƒr ddd„ZG dd
„ d
eƒZ e e_!edƒZ"edƒZ#edƒZ$ddde%e&ddddf	dd„Z'e&dfdd„Z(dS ) z SSL wrapper for socket objects on Python 3.

For the documentation, refer to :mod:`ssl` module manual.

This module implements cooperative SSL socket wrappers.
é    )Úabsolute_importN)ÚsocketÚtimeout_default)Úerror)Útimeout)Úcopy_globals)ÚrefÚ
SSLContextÚ	SSLSocketÚwrap_socketÚget_server_certificater   © )Znames_to_ignoreZdunder_names_to_keepÚ
namedtuplec                   s¦   e Zd ZdZddd„Zeedƒs$dZeejdƒrlejj	‡ fdd	„ƒZej
j	‡ fd
d„ƒZ
ejj	‡ fdd„ƒZeedƒržejj	‡ fdd„ƒZejj	‡ fdd„ƒZ‡  ZS )r	   NFTc          	   C   s   | j |||||| |dS )N)ÚsockÚserver_sideÚdo_handshake_on_connectÚsuppress_ragged_eofsÚserver_hostnameÚ_contextÚ_session)Ússlsocket_class)Úselfr   r   r   r   r   Úsessionr   r   ú+lib/python3.7/site-packages/gevent/_ssl3.pyr   4   s    zSSLContext.wrap_socketÚcheck_hostnameÚsetterc                s   t ttƒj | |¡ d S )N)ÚsuperÚorig_SSLContextÚoptionsÚ__set__)r   Úvalue)Ú	__class__r   r   r   O   s    zSSLContext.optionsc                s   t ttƒj | |¡ d S )N)r   r   Úverify_flagsr   )r   r    )r!   r   r   r"   S   s    zSSLContext.verify_flagsc                s   t ttƒj | |¡ d S )N)r   r   Úverify_moder   )r   r    )r!   r   r   r#   W   s    zSSLContext.verify_modeÚminimum_versionc                s   t ttƒj | |¡ d S )N)r   r   r$   r   )r   r    )r!   r   r   r$   ]   s    zSSLContext.minimum_versionc                s   t ttƒj | |¡ d S )N)r   r   Úmaximum_versionr   )r   r    )r!   r   r   r%   a   s    zSSLContext.maximum_version)FTTNN)Ú__name__Ú
__module__Ú__qualname__r   r   Úhasattrr   r   r   r   r"   r#   r$   r%   Ú__classcell__r   r   )r!   r   r	   /   s       


c               @   sL   e Zd ZdZedd„ ƒZejdd„ ƒZedd„ ƒZejdd„ ƒZdd	„ Zd
S )Ú_contextawaresock)Ú_sslsockc             C   s
   |   ¡ jS )N)r,   Úcontext)r   r   r   r   r-   s   s    z_contextawaresock.contextc             C   s   ||   ¡ _d S )N)r,   r-   )r   Úctxr   r   r   r-   w   s    c             C   s
   |   ¡ jS )z!The SSLSession for client socket.)r,   r   )r   r   r   r   r   {   s    z_contextawaresock.sessionc             C   s   ||   ¡ _d S )N)r,   r   )r   r   r   r   r   r   €   s    c             C   s0   yt |  ¡ |ƒS  tk
r"   Y nX t|ƒ‚d S )N)Úgetattrr,   ÚRuntimeErrorÚAttributeError)r   Únamer   r   r   Ú__getattr__„   s
    z_contextawaresock.__getattr__N)	r&   r'   r(   Ú	__slots__Úpropertyr-   r   r   r3   r   r   r   r   r+   f   s   r+   Z_createc             C   s0   t  t ¡}| |_|p||j_|d k	r,||j_|S )N)Ú	SSLObjectÚ__new__Ú_sslobjÚownerr   )Zsslobjr9   r   Úsr   r   r   Ú_SSLObject_factory—   s    
r;   c               @   s¦  e Zd ZdZeZddddeeddee	ddddddddfdd„Z
edd	„ ƒZejd
d	„ ƒZedd„ ƒZejdd„ ƒZedd„ ƒZdd„ ZdSdd„Zdd„ ZdTdd„Zdd„ ZdUdd„Zdd„ ZeedƒrÞd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zdefd*d+„ZdVd,d-„Z d.d/„ Z!dWd0d1„Z"dXd2d3„Z#dYd4d5„Z$dZd6d7„Z%d[d8d9„Z&d:d;„ Z'd<d=„ Z(d>d?„ Z)d@dA„ Z*dBdC„ Z+dDdE„ Z,dFdG„ Z-dHdI„ Z.dJdK„ Z/dLdM„ Z0dNdO„ Z1d\dQdR„Z2dS )]r
   zl
    gevent `ssl.SSLSocket <https://docs.python.org/3/library/ssl.html#ssl-sockets>`_
    for Python 3.
    NFTr   c          
   C   sˆ  |r|| _ n¤|r|stdƒ‚|r,|s,tdƒ‚|r8|s8|}t|ƒ| _ || j _|rZ| j  |¡ |rl| j  ||¡ |r|| j  |¡ |rŒ| j  |¡ || _|| _	|| _
|| _|| _|| _| tt¡tkrÈtdƒ‚|rè|rØtdƒ‚|d k	rètdƒ‚| j jrü|sütdƒ‚|| _|| _|| _|| _|| _d}|d k	r¤tj| |j|j|j| ¡ d |  |  ¡ ¡ y| !¡  W n4 t"k
r” } z|j#t#j$kr„‚ W d d }~X Y nX d	}| %¡  n,|d k	r¾tj| |d
 ntj| |	|
|d t&| ƒ| j'_(d| _)d | _*|| _+|r„y^| j  ,| j'||¡| _*|d k	r(t-| j*| | jd| _*|rP|   ¡ }|dkrHtdƒ‚|  .¡  W n0 t"k
r‚ } z|  /¡  |‚W d d }~X Y nX d S )Nz5certfile must be specified for server-side operationszcertfile must be specifiedz!only stream sockets are supportedz4server_hostname can only be specified in client modez,session can only be specified in client modez'check_hostname requires server_hostnameF)ÚfamilyÚtypeÚprotoÚfilenoT)r?   )r<   r=   r>   )r9   r   g        zHdo_handshake_on_connect should not be specified for non-blocking sockets)0r   Ú
ValueErrorr	   r#   Zload_verify_locationsZload_cert_chainZset_npn_protocolsZset_ciphersÚkeyfileÚcertfileÚ	cert_reqsÚssl_versionÚca_certsÚciphersZ
getsockoptZ
SOL_SOCKETZSO_TYPEÚSOCK_STREAMÚNotImplementedErrorr   r   r   r   r   r   r   Ú__init__r<   r=   r>   r?   Z
settimeoutZ
gettimeoutÚgetpeernameÚsocket_errorÚerrnoZENOTCONNÚdetachÚ_wrefÚ_sockr,   Z_closedr8   Ú
_connectedÚ_wrap_socketr;   Údo_handshakeÚclose)r   r   rA   rB   r   rC   rD   rE   r   r<   r=   r>   r?   r   Znpn_protocolsrF   r   r   r   Z	connectedÚer   Úxr   r   r   rI   ©   s–    





zSSLSocket.__init__c             C   s   | j S )N)r   )r   r   r   r   r-     s    zSSLSocket.contextc             C   s   || _ || j_d S )N)r   r8   r-   )r   r.   r   r   r   r-     s    c             C   s   | j dk	r| j jS dS )z!The SSLSession for client socket.N)r8   r   )r   r   r   r   r     s    
zSSLSocket.sessionc             C   s   || _ | jd k	r|| j_d S )N)r   r8   r   )r   r   r   r   r   r     s    
c             C   s   | j dk	r| j jS dS )z.Was the client session reused during handshakeN)r8   Úsession_reused)r   r   r   r   rV   "  s    
zSSLSocket.session_reusedc             C   s   t d| jj ƒ‚d S )NzCan't dup() %s instances)rH   r!   r&   )r   r   r   r   Údup(  s    zSSLSocket.dupc             C   s   d S )Nr   )r   Úmsgr   r   r   Ú_checkClosed,  s    zSSLSocket._checkClosedc             C   s   | j s|  ¡  d S )N)rP   rJ   )r   r   r   r   Ú_check_connected0  s    zSSLSocket._check_connectedé   c          
   C   s  |   ¡  xö| jstdƒ‚|dkr0|dkr,dS dS y&|dk	rH| j ||¡S | j |pTd¡S  tk
r†   | jdkrr‚ | j| jtd Y q
 t	k
r´   | jdkr ‚ | j| j
td Y q
 tk
rú } z*|jd tkrè| jrè|dkrädS dS ‚ W dd}~X Y q
X q
W dS )zORead up to LEN bytes and return them.
        Return zero-length string on EOF.z'Read on closed or unwrapped SSL socket.r   Nó    i   g        )Útimeout_exc)rY   r8   r@   ÚreadÚSSLWantReadErrorr   Ú_waitÚ_read_eventÚ_SSLErrorReadTimeoutÚSSLWantWriteErrorÚ_write_eventÚSSLErrorÚargsZSSL_ERROR_EOFr   )r   ÚlenÚbufferÚexr   r   r   r^   8  s0    

zSSLSocket.readc          
   C   sª   |   ¡  xœ| jstdƒ‚y| j |¡S  tk
r  } z^|jd tkrb| jdkrP‚ | j| j	t
d n.|jd tkrŽ| jdkr|‚ | j| jt
d n‚ W dd}~X Y q
X q
W dS )zhWrite DATA to the underlying SSL channel.  Returns
        number of bytes of DATA actually transmitted.z(Write on closed or unwrapped SSL socket.r   g        )r]   N)rY   r8   r@   Úwritere   rf   ZSSL_ERROR_WANT_READr   r`   ra   Ú_SSLErrorWriteTimeoutZSSL_ERROR_WANT_WRITErd   )r   Údatari   r   r   r   rj   Y  s     

zSSLSocket.writec             C   sB   |   ¡  |  ¡  y| jj}W n tk
r8   | jj}Y nX ||ƒS )záReturns a formatted version of the data in the
        certificate provided by the other end of the SSL channel.
        Return None if no certificate was provided, {} if a
        certificate was provided, but not validated.)rY   rZ   r8   Zpeer_certificater1   Úgetpeercert)r   Zbinary_formÚcr   r   r   rm   p  s    zSSLSocket.getpeercertc             C   s"   |   ¡  | jrtjsd S | j ¡ S )N)rY   r8   Ú_sslZHAS_NPNÚselected_npn_protocol)r   r   r   r   rp   €  s    zSSLSocket.selected_npn_protocolÚHAS_ALPNc             C   s"   |   ¡  | jrtjsd S | j ¡ S )N)rY   r8   ro   rq   Úselected_alpn_protocol)r   r   r   r   rr   ˆ  s    z SSLSocket.selected_alpn_protocolc             C   s
   | j  ¡ S )zReturn a list of ciphers shared by the client during the handshake or
            None if this is not a valid server connection.
            )r8   Úshared_ciphers)r   r   r   r   rs   Ž  s    zSSLSocket.shared_ciphersc             C   s   | j s
dS | j  ¡ S )z^Return a string identifying the protocol version used by the
            current SSL channel. N)r8   Úversion)r   r   r   r   rt   ”  s    zSSLSocket.versionc             C   s   |   ¡  | jsd S | j ¡ S )N)rY   r8   Úcipher)r   r   r   r   ru     s    zSSLSocket.cipherc             C   s   |   ¡  | jsd S | j ¡ S )N)rY   r8   Úcompression)r   r   r   r   rv   £  s    zSSLSocket.compressionc             C   s¶   |   ¡  |tkr| j}| jr¢|dkr2td| j ƒ‚x~y| j |¡S  tk
rn   | jdkr^dS |  | j	¡ Y q4 t
k
rš   | jdkrŠdS |  | j¡ Y q4X q4W nt | |||¡S d S )Nr   z3non-zero flags not allowed in calls to send() on %sg        )rY   r   r   r8   r@   r!   rj   r_   r`   ra   rc   rd   r   Úsend)r   rl   Úflagsr   r   r   r   rw   ©  s(    


zSSLSocket.sendc             C   sH   |   ¡  | jrtd| j ƒ‚n&|d kr4t | ||¡S t | |||¡S d S )Nz%sendto not allowed on instances of %s)rY   r8   r@   r!   r   Úsendto)r   rl   Zflags_or_addrÚaddrr   r   r   ry   À  s    zSSLSocket.sendtoc             O   s   t d| j ƒ‚d S )Nz&sendmsg not allowed on instances of %s)rH   r!   )r   rf   Úkwargsr   r   r   ÚsendmsgÊ  s    zSSLSocket.sendmsgc             C   s`   |   ¡  | jr$|dkr$td| j ƒ‚yt | ||¡S  tk
rZ   | jdkrTtdƒ‚‚ Y nX d S )Nr   z6non-zero flags not allowed in calls to sendall() on %sg        z&The operation did not complete (write))	rY   r8   r@   r!   r   ÚsendallÚ_socket_timeoutr   rc   )r   rl   rx   r   r   r   r}   Ð  s    

zSSLSocket.sendallc             C   sH   |   ¡  | jr:|dkr$td| j ƒ‚|dkr0dS |  |¡S t | ||¡S )Nr   z3non-zero flags not allowed in calls to recv() on %sr\   )rY   r8   r@   r!   r^   r   Úrecv)r   Úbuflenrx   r   r   r   r   à  s    

zSSLSocket.recvc             C   sb   |   ¡  |r|d krt|ƒ}n|d kr*d}| jrR|dkrFtd| j ƒ‚|  ||¡S t | |||¡S )Ni   r   z8non-zero flags not allowed in calls to recv_into() on %s)rY   rg   r8   r@   r!   r^   r   Ú	recv_into)r   rh   Únbytesrx   r   r   r   r   î  s    
zSSLSocket.recv_intoc             C   s0   |   ¡  | jrtd| j ƒ‚nt | ||¡S d S )Nz'recvfrom not allowed on instances of %s)rY   r8   r@   r!   r   Úrecvfrom)r   r€   rx   r   r   r   rƒ   ú  s
    zSSLSocket.recvfromc             C   s2   |   ¡  | jrtd| j ƒ‚nt | |||¡S d S )Nz,recvfrom_into not allowed on instances of %s)rY   r8   r@   r!   r   Úrecvfrom_into)r   rh   r‚   rx   r   r   r   r„     s
    zSSLSocket.recvfrom_intoc             O   s   t d| j ƒ‚d S )Nz&recvmsg not allowed on instances of %s)rH   r!   )r   rf   r{   r   r   r   Úrecvmsg
  s    zSSLSocket.recvmsgc             O   s   t d| j ƒ‚d S )Nz+recvmsg_into not allowed on instances of %s)rH   r!   )r   rf   r{   r   r   r   Úrecvmsg_into  s    zSSLSocket.recvmsg_intoc             C   s   |   ¡  | jr| j ¡ S dS )Nr   )rY   r8   Úpending)r   r   r   r   r‡     s    
zSSLSocket.pendingc             C   s   |   ¡  d | _t | |¡ d S )N)rY   r8   r   Úshutdown)r   Zhowr   r   r   rˆ     s    zSSLSocket.shutdownc             C   sœ   | j stdt| ƒ ƒ‚xly| j  ¡ }P W q tk
rT   | jdkrD‚ |  | j¡ Y q tk
r~   | jdkrn‚ |  | j	¡ Y qX qW d | _ || j
ks˜t‚| S )NzNo SSL wrapper around g        )r8   r@   Ústrrˆ   r_   r   r`   ra   rc   rd   rO   ÚAssertionError)r   r:   r   r   r   Úunwrap  s"    


zSSLSocket.unwrapc             C   s   d | _ t | ¡ d S )N)r8   r   Ú_real_close)r   r   r   r   rŒ   A  s    zSSLSocket._real_closec             C   sº   |   ¡  xty| j ¡  P W q
 tk
rJ   | jdkr6‚ | j| jtd Y q
 tk
rx   | jdkrd‚ | j| j	td Y q
X q
W t
jdd… dk r¶| jjr¶| js¦tdƒ‚t|  ¡ | jƒ dS )zPerform a TLS/SSL handshake.g        )r]   Né   )é   é   z-check_hostname needs server_hostname argument)rZ   r8   rR   r_   r   r`   ra   Ú_SSLErrorHandshakeTimeoutrc   rd   ÚsysÚversion_infor   r   r   r@   Zmatch_hostnamerm   )r   r   r   r   rR   F  s"    


zSSLSocket.do_handshakec             C   s°   | j rtdƒ‚| jrtdƒ‚| j | jd| j¡| _| jd k	rPt	| j| | jd| _y>|rdt
 | |¡}nd }t
 | |¡ |sŒ| jr†|  ¡  d| _|S  tk
rª   d | _‚ Y nX d S )Nz!can't connect in server-side modez/attempt to connect already-connected SSLSocket!F)r9   r   T)r   r@   rP   r   rQ   rO   r   r8   r   r;   r   Ú
connect_exÚconnectr   rR   rK   )r   rz   r“   Zrcr   r   r   Ú_real_connect^  s(    
zSSLSocket._real_connectc             C   s   |   |d¡ dS )zQConnects to remote ADDR, and then wraps the connection in
        an SSL channel.FN)r•   )r   rz   r   r   r   r”   w  s    zSSLSocket.connectc             C   s   |   |d¡S )zQConnects to remote ADDR, and then wraps the connection in
        an SSL channel.T)r•   )r   rz   r   r   r   r“   |  s    zSSLSocket.connect_exc             C   s6   t  | ¡\}}| ¡  | jj|| j| jdd}||fS )z¿Accepts a new connection from a remote client, and returns
        a tuple containing that new connection wrapped with a server-side
        SSL channel, and the address of the remote client.T)r   r   r   )r   ÚacceptZ_drop_eventsr   r   r   r   )r   Znewsockrz   r   r   r   r–     s    zSSLSocket.acceptú
tls-uniquec             C   sV   t | jdƒr| j |¡S |tkr(tdƒ‚|dkr>td |¡ƒ‚| jdkrLdS | j ¡ S )zäGet channel binding data for current connection.  Raise ValueError
        if the requested `cb_type` is not supported.  Return bytes of the data
        or None if the data is not available (e.g. before the handshake).
        Úget_channel_bindingz Unsupported channel binding typez
tls-uniquez({0} channel binding type not implementedN)r)   r8   r˜   ZCHANNEL_BINDING_TYPESr@   rH   ÚformatZtls_unique_cb)r   Zcb_typer   r   r   r˜   Ž  s    
zSSLSocket.get_channel_binding)N)r[   N)F)N)r   )r[   r   )Nr   )r[   r   )Nr   )r—   )3r&   r'   r(   Ú__doc__r+   Ú_gevent_sock_classÚ	CERT_NONEÚPROTOCOL_SSLv23ZAF_INETrG   rI   r5   r-   r   r   rV   rW   rY   rZ   r^   rj   rm   rp   r)   ro   rr   rs   rt   ru   rv   r   rw   ry   r|   r}   r   r   rƒ   r„   r…   r†   r‡   rˆ   r‹   rŒ   rR   r•   r”   r“   r–   r˜   r   r   r   r   r
   Ÿ   sb   \

!

	






$zThe read operation timed outzThe write operation timed outz!The handshake operation timed outFTc
       
      C   s   t | |||||||||	d
S )N)
r   rA   rB   r   rC   rD   rE   r   r   rF   )r
   )
r   rA   rB   r   rC   rD   rE   r   r   rF   r   r   r   r   ©  s    c             C   sL   | \}}|dk	rt }nt}t| ƒ}t||||d}| d¡}| ¡  t|ƒS )z÷Retrieve the certificate from the server at the specified address,
    and return it as a PEM-encoded string.
    If 'ca_certs' is specified, validate the server cert against it.
    If 'ssl_version' is specified, use it in the connection attempt.N)rD   rC   rE   T)ZCERT_REQUIREDrœ   Zcreate_connectionr   rm   rS   ZDER_cert_to_PEM_cert)rz   rD   rE   Ú_rC   r:   Zdercertr   r   r   r   ¸  s    

)NN))rš   Z
__future__r   ZsslZ__ssl__ro   rL   Zgevent.socketr   r   r   rK   r   r~   Zgevent._utilr   Úweakrefr   rN   Z__implements__ÚglobalsZ__imports__Ú__all__Úremover	   r   r›   r+   r6   r;   Ú	NameErrorr)   r
   r   rb   rk   r   rœ   r   r   r   r   r   r   r   Ú<module>   sX   
7'
    
