3
Z_ð]5K  ã               @   sZ  e d ƒZddlmZ eeeƒ eeƒd� ddlZddlmZm	Z	 ddl
mZmZmZmZ ddlmZmZ ddlmZmZ ddlZdd	lmZ e d
ƒZejZeZddddddgZejZejZ e!eddƒZ"ej#dk Z$edd„ ƒZ%G dd„ deƒZ&e&Zdd„ Ze'edƒ�rddd„Z(e'edƒ�rVej)Z"G dd„ de"ƒZ*e*Z)e'edƒ�rVej+Z,dd„ Z-e-Z+e-Z.dS )Ússlé    )Úslurp_properties)ZsrckeysN)ÚgreenioÚhubs)Úset_nonblockingÚGreenSocketÚCONNECT_ERRÚCONNECT_SUCCESS)Ú
trampolineÚIOClosed)Ú	get_errnoÚPY33)ÚcontextmanagerÚsocketÚ	SSLSocketÚ
SSLContextÚwrap_socketÚsslwrap_simpleÚcreate_default_contextÚ_create_default_https_contexté   é   c              o   s\   t jjdd ƒ}tjjjdd ƒ}ttjjd< tt jd< z
d V  W d |t jd< |tjjd< X d S )Nr   r   )Ú_original_wrap_socketÚ__globals__ÚgetÚ_original_sslsocketZ_createÚ_original_sslcontext)ÚargsÚkwargsZtmp_sslcontextZtmp_sslsocket© r   ú6/tmp/pip-build-yz_zf6az/eventlet/eventlet/green/ssl.pyÚ_original_ssl_context   s    


r!   c                   s  e Zd ZdZddddeeddf‡ fdd„	Zdddeeddf‡ fdd„	Zd	d
„ Zdd„ Z	dd„ Z
dd„ Z‡ fdd„Z‡ fdd„Zd3‡ fdd„	Zd4dd„Zd5dd„Zd6dd„Zd7dd „Zd8d!d"„Zd9‡ fd#d$„	Zd:‡ fd%d&„	Z‡ fd'd(„Z‡ fd)d*„Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Z‡  ZS );ÚGreenSSLSocketaÒ   This is a green version of the SSLSocket class from the ssl module added
    in 2.6.  For documentation on it, please see the Python standard
    documentation.

    Python nonblocking ssl objects don't give errors when the other end
    of the socket is closed (they do notice when the other end is shutdown,
    though).  Any write/read operations will simply hang if the socket is
    closed from the other end.  There is no obvious fix for this problem;
    it appears to be a limitation of Python's ssl object implementation.
    A workaround is to set a reasonable timeout on the socket using
    settimeout(), and to close/reopen the connection when a timeout
    occurs at an unexpected juncture in the code.
    NFTc	                s†   t rtt| ƒj| ƒS t|tƒs&t|ƒ}tƒ �( t|	|j||||||ddœ|
—Ž}W d Q R X ||_	||_
||_||_||_t|_|S d S )NF)ÚsockÚkeyfileÚcertfileÚserver_sideÚ	cert_reqsÚssl_versionÚca_certsÚdo_handshake_on_connect)Ú_is_under_py_3_7Úsuperr"   Ú__new__Ú
isinstancer   r!   r   Úfdr$   r%   r'   r(   r)   Ú	__class__)Úclsr#   r$   r%   r&   r'   r(   r)   r*   r   ÚkwÚret)r0   r   r    r-   9   s    
	*zGreenSSLSocket.__new__c	                sÚ   t |tƒst|ƒ}|j| _tjr*|jƒ | _tr\tt	| ƒj
|j|||||||oPtjf|	ž|
Ž yxtjD ]}t| |ƒ qfW W n tk
rŽ   Y nX tjrÖ|jƒ | _tj| dƒ tj| ƒdks¾t‚|| _|rÖ| jrÖ| jƒ  d S )Ng        )r.   r   Úact_non_blockingÚsixÚPY2Ú
gettimeoutÚ_timeoutr+   r,   r"   Ú__init__r/   Úorig_socketZ_delegate_methodsÚdelattrÚAttributeErrorÚPY3r   Ú
settimeoutÚAssertionErrorr*   Ú
_connectedÚdo_handshake)Úselfr#   r$   r%   r&   r'   r(   r)   r*   r   r2   Úfn)r0   r   r    r9   X   s*    




zGreenSSLSocket.__init__c             C   s
   || _ d S )N)r8   )rB   Útimeoutr   r   r    r>   ‚   s    zGreenSSLSocket.settimeoutc             C   s   | j S )N)r8   )rB   r   r   r    r7   …   s    zGreenSSLSocket.gettimeoutc             C   s"   |rd| _ d | _nd| _ d| _d S )NFTg        )r4   r8   )rB   Úflagr   r   r    Úsetblockingˆ   s
    zGreenSSLSocket.setblockingc             O   s–   | j r|||ŽS x€y
|||ŽS  tk
rŒ } zTt|ƒtkrTt| d| jƒ tdƒd� n(t|ƒtkrzt| d| jƒ tdƒd� n‚ W Y d d }~X qX qW d S )NTz	timed out)ÚreadrD   Útimeout_exc)ÚwriterD   rH   )r4   ÚSSLErrorr   ÚSSL_ERROR_WANT_READr
   r7   rH   ÚSSL_ERROR_WANT_WRITE)rB   ÚfuncÚar2   Úexcr   r   r    Ú_call_trampolining�   s"    

z!GreenSSLSocket._call_trampoliningc                s   | j tt| ƒj|ƒS )zhWrite DATA to the underlying SSL channel.  Returns
        number of bytes of DATA actually transmitted.)rP   r,   r"   rI   )rB   Údata)r0   r   r    rI   ¥   s    zGreenSSLSocket.writec                s4   y| j tt| ƒjf|ž|ŽS  tk
r.   dS X dS )zORead up to LEN bytes and return them.
        Return zero-length string on EOF.ó    N)rP   r,   r"   rG   r   )rB   r   r   )r0   r   r    rG   «   s
    zGreenSSLSocket.readr   c                s@   | j r| jtt| ƒj||ƒS t| dtdƒd� tj| ||ƒS d S )NTz	timed out)rI   rH   )Ú_sslobjrP   r,   r"   Úsendr
   rH   r   )rB   rQ   Úflags)r0   r   r    rT   ´   s
    zGreenSSLSocket.sendc             C   s<   | j rtd| j ƒ‚n"t| dtdƒd� tj| |||ƒS d S )Nz%sendto not allowed on instances of %sTz	timed out)rI   rH   )rS   Ú
ValueErrorr0   r
   rH   r   Úsendto)rB   rQ   ÚaddrrU   r   r   r    rW   ¼   s
    zGreenSSLSocket.sendtoc       	      C   sú   | j rx|dkrtd| j ƒ‚t|ƒ}d}|}xF||k rr| j|ƒ}||7 }|dkrdt| dtdƒd� q.||d … }q.W |S x|ytj| ||ƒS  t	j
k
rð } zJ| jr¤‚ t|ƒ}|tjkrÐt| d| jƒ tdƒd� n|tjkrÞdS ‚ W Y d d }~X qzX qzW d S )Nr   z6non-zero flags not allowed in calls to sendall() on %sTz	timed out)rI   rH   )rI   rD   rH   Ú )rS   rV   r0   ÚlenrT   r
   rH   r   Úsendallr:   Úerrorr4   r   r   ÚSOCKET_BLOCKINGr7   ÚSOCKET_CLOSED)	rB   rQ   rU   ÚamountÚcountZdata_to_sendÚvÚeÚernor   r   r    r[   Å   s8    




zGreenSSLSocket.sendallé   c             C   s   | j ||dd�S )NF)Úinto)Ú
_base_recv)rB   ÚbuflenrU   r   r   r    Úrecvæ   s    zGreenSSLSocket.recvc             C   s4   |r|d krt |ƒ}n|d kr"d}| j||d|d�S )Ni   T)re   Úbuffer_)rZ   rf   )rB   ÚbufferÚnbytesrU   r   r   r    Ú	recv_intoé   s
    
zGreenSSLSocket.recv_intoc       
      C   s  |rt j}nt j}| jrR|dkr2td|j | jƒ‚|rD| j||ƒ}n
| j|ƒ}|S x¬y"| ||g}|rp|jd|ƒ ||Ž S  t	j
k
� rú } zd| jr”‚ t|ƒ}	|	tjkrÚyt| d| jƒ tdƒd� W qè tk
rÖ   dS X n|	tjkrèdS ‚ W Y d d }~X qTX qTW d S )Nr   z1non-zero flags not allowed in calls to %s() on %sé   Tz	timed out)rG   rD   rH   rR   )r   rl   rh   rS   rV   Ú__name__r0   rG   Úinsertr:   r\   r4   r   r   r]   r
   r7   rH   r   r^   )
rB   rk   rU   re   ri   Zplain_socket_functionrG   r   rb   rc   r   r   r    rf   ó   s@    



zGreenSSLSocket._base_recvc                s2   | j st| d| jƒ tdƒd� tt| ƒj|||ƒS )NTz	timed out)rG   rD   rH   )r4   r
   r7   rH   r,   r"   Úrecvfrom)rB   rX   rg   rU   )r0   r   r    rp     s    zGreenSSLSocket.recvfromc                s2   | j st| d| jƒ tdƒd� tt| ƒj|||ƒS )NTz	timed out)rG   rD   rH   )r4   r
   r7   rH   r,   r"   Úrecvfrom_into)rB   rj   rk   rU   )r0   r   r    rq      s    zGreenSSLSocket.recvfrom_intoc                s   t | jtt| ƒjƒƒS )N)r   rP   r,   r"   Úunwrap)rB   )r0   r   r    rr   &  s    zGreenSSLSocket.unwrapc                s   | j tt| ƒjƒS )zPerform a TLS/SSL handshake.)rP   r,   r"   rA   )rB   )r0   r   r    rA   *  s    zGreenSSLSocket.do_handshakec             C   s,  t j}| jr|| |ƒS tjƒ j}| jƒ d kr�x`y
|| |ƒS  tjk
rˆ } z2t	|ƒt
krft| dd� nt	|ƒtkrvd S ‚ W Y d d }~X q.X q.W n˜|ƒ | jƒ  }xˆy|| |ƒ W nb tjk
�r } zBt	|ƒt
krìt| d||ƒ  tdƒd� nt	|ƒtk� rþd S ‚ W Y d d }~X nX |ƒ |kr tdƒ‚q W d S )NT)rI   z	timed out)rI   rD   rH   )r   Úconnectr4   r   Zget_hubÚclockr7   r:   r\   r   r   r
   r	   rH   )rB   rX   Zreal_connectrt   rO   Úendr   r   r    Ú_socket_connect/  s8    



zGreenSSLSocket._socket_connectc             C   sì   | j rtdƒ‚| j|ƒ d}y
tj}W nL tk
rr   tjrR| jj	| j
|| d�}ntr\| jn| j}|j	| |ƒ}Y n*X || j
|| j| j| j| j| jf| jžŽ }yt W n tk
r¾   || _ Y nX trÔt|| d�| _ n|| _ | jrè| jƒ  dS )zQConnects to remote ADDR, and then wraps the connection in
        an SSL channel.z/attempt to connect already-connected SSLSocket!F)Ússl_sock)ÚownerN)rS   rV   rv   Ú_sslÚsslwrapr<   r5   r6   Ú_contextÚ_wrap_socketÚ_sockr   Úcontextr$   r%   r'   r(   r)   ÚciphersÚ	SSLObjectÚ	NameErrorr+   r*   rA   )rB   rX   r&   rz   Ússlobjr~   r   r   r    rs   S  s.    

zGreenSSLSocket.connectc             C   s¸   | j rtj| ƒ\}}npxnytj| ƒ\}}t|ƒ P W q tjk
r€ } z.t|ƒtjkrX‚ t	| d| j
ƒ tdƒd� W Y dd}~X qX qW t| ƒ|| j| jd| j| j| jd| j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.Tz	timed out)rG   rD   rH   NF)r$   r%   r&   r'   r(   r)   r*   Úsuppress_ragged_eofs)r4   r   Úacceptr   r:   r\   r   r   r]   r
   r7   rH   Útyper$   r%   r'   r(   r)   rƒ   )rB   ÚnewsockrX   rb   Znew_sslr   r   r    r„   x  s.    "
zGreenSSLSocket.acceptc             C   s   t dƒ‚d S )NzCan't dup an ssl object)ÚNotImplementedError)rB   r   r   r    Údup—  s    zGreenSSLSocket.dup)r   )r   )r   )rd   r   )Nr   )N)rd   r   )Nr   )rn   Ú
__module__Ú__qualname__Ú__doc__Ú	CERT_NONEÚPROTOCOL_SSLv23r-   r9   r>   r7   rF   rP   rI   rG   rT   rW   r[   rh   rl   rf   rp   rq   rr   rA   rv   rs   r„   rˆ   Ú__classcell__r   r   )r0   r    r"   +   s:   '	
	
!



'$%r"   c             O   s   t | f|ž|ŽS )N)r"   )r#   rN   r2   r   r   r    r   ž  s    c          	   C   s   t | ||dttdd�}|S )z–A replacement for the old socket.ssl function.  Designed
        for compatibility with Python 2.5 and earlier.  Will disappear in
        Python 3.0.FN)r$   r%   r&   r'   r(   r)   )r"   rŒ   r�   )r#   r$   r%   rw   r   r   r    r   £  s    c                   sd   e Zd Zf Zdd„ Zeejdƒr\ejj‡ fdd„ƒZej	j‡ fdd„ƒZ	ej
j‡ fdd	„ƒZ
‡  ZS )
ÚGreenSSLContextc             O   s   t |f|žd| i|—ŽS )Nr{   )r"   )rB   r#   rN   r2   r   r   r    r   µ  s    zGreenSSLContext.wrap_socketÚsetterc                s   t ttƒjj| |ƒ d S )N)r,   r   ÚoptionsÚ__set__)rB   Úvalue)r0   r   r    r‘   À  s    zGreenSSLContext.optionsc                s   t ttƒjj| |ƒ d S )N)r,   r   Úverify_flagsr’   )rB   r“   )r0   r   r    r”   Ä  s    zGreenSSLContext.verify_flagsc                s   t ttƒjj| |ƒ d S )N)r,   r   Úverify_moder’   )rB   r“   )r0   r   r    r•   È  s    zGreenSSLContext.verify_mode)rn   r‰   rŠ   Ú	__slots__r   Úhasattrr   r‘   r�   r”   r•   rŽ   r   r   )r0   r    r�   ²  s   r�   c              O   s   t | |Ž}t|_|S )N)Ú _original_create_default_contextr�   r0   )rN   r2   r~   r   r   r    Úgreen_create_default_contextÑ  s    
r™   )r   r   )NN)/Ú
__import__Z__sslZeventlet.patcherr   ÚglobalsÚdirÚsysZeventletr   r   Zeventlet.greenior   r   r   r	   Zeventlet.hubsr
   r   Zeventlet.supportr   r   r5   Ú
contextlibr   r:   r   rJ   rH   Z__patched__r   r   r   r   Úgetattrr   Úversion_infor+   r!   r"   r—   r   r   r�   r   r˜   r™   r   r   r   r   r    Ú<module>   sF   
  r
	