B
    v9a/i                 @   s   d dl Z d dlZyd dlZW n ek
r4   dZY nX ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 dd	 Zd
ZdZdZdZG dd deZG dd dejejZG dd dejZdS )    N   )base_events)	constants)	protocols)
transports)loggerc             C   s"   | rt dt }|sd|_|S )Nz(Server side SSL needs a valid SSLContextF)
ValueErrorsslZcreate_default_contextZcheck_hostname)server_sideserver_hostname
sslcontext r   /usr/lib/python3.7/sslproto.py_create_transport_context   s    r   Z	UNWRAPPEDZDO_HANDSHAKEZWRAPPEDZSHUTDOWNc               @   sz   e Zd ZdZdddZedd Zedd Zed	d
 Zedd Z	dddZ
dddZdd ZdddZdddZdS )_SSLPipei   Nc             C   sH   || _ || _|| _t| _t | _t | _d | _	d| _
d | _d | _d S )NF)_context_server_side_server_hostname
_UNWRAPPED_stater	   Z	MemoryBIO	_incoming	_outgoing_sslobj_need_ssldata_handshake_cb_shutdown_cb)selfcontextr
   r   r   r   r   __init__8   s    

z_SSLPipe.__init__c             C   s   | j S )N)r   )r   r   r   r   r   N   s    z_SSLPipe.contextc             C   s   | j S )N)r   )r   r   r   r   
ssl_objectS   s    z_SSLPipe.ssl_objectc             C   s   | j S )N)r   )r   r   r   r   need_ssldata[   s    z_SSLPipe.need_ssldatac             C   s
   | j tkS )N)r   _WRAPPED)r   r   r   r   wrappeda   s    z_SSLPipe.wrappedc             C   sR   | j tkrtd| jj| j| j| j| jd| _	t
| _ || _| jddd\}}|S )Nz"handshake in progress or completed)r
   r       T)only_handshake)r   r   RuntimeErrorr   Zwrap_bior   r   r   r   r   _DO_HANDSHAKEr   feed_ssldata)r   callbackssldataappdatar   r   r   do_handshakej   s    	
z_SSLPipe.do_handshakec             C   sB   | j tkrtd| j tkr$tdt| _ || _| d\}}|S )Nzno security layer presentzshutdown in progressr#   )r   r   r%   	_SHUTDOWNr   r'   )r   r(   r)   r*   r   r   r   shutdown   s    	

z_SSLPipe.shutdownc             C   s   | j   | d\}}d S )Nr#   )r   Z	write_eofr'   )r   r)   r*   r   r   r   feed_eof   s    
z_SSLPipe.feed_eofFc          
   C   s  | j tkr"|r|g}ng }g |fS d| _|r8| j| g }g }y| j tkrx| j  t| _ | j	rl| 	d  |rx||fS | j tkrxn| j
| j}|| |sP qW nJ| j tkr| j  d | _t| _ | jr|   n| j tkr|| j
  W nz tjtjfk
rn } zRt|dd }|tjtjtjfkrR| j tkrP| j	rP| 	|  |tjk| _W d d }~X Y nX | jjr|| j
  ||fS )NFerrno)r   r   r   r   writer&   r   r+   r!   r   readmax_sizeappendr,   Zunwrapr   r	   SSLErrorCertificateErrorgetattrSSL_ERROR_WANT_READSSL_ERROR_WANT_WRITESSL_ERROR_SYSCALLr   pending)r   datar$   r*   r)   chunkexc	exc_errnor   r   r   r'      sX    











z_SSLPipe.feed_ssldatar   c          
   C   s  | j tkr6|t|k r&||d  g}ng }|t|fS g }t|}xd| _y(|t|k rp|| j||d  7 }W nh tjk
r } zHt	|dd }|j
dkrtj }|_|tjtjtjfkr |tjk| _W d d }~X Y nX | jjr|| j  |t|ks| jrDP qDW ||fS )NFr/   ZPROTOCOL_IS_SHUTDOWN)r   r   len
memoryviewr   r   r0   r	   r4   r6   reasonr7   r/   r8   r9   r   r:   r3   r1   )r   r;   offsetr)   Zviewr=   r>   r   r   r   feed_appdata   s4    


z_SSLPipe.feed_appdata)N)N)N)F)r   )__name__
__module____qualname__r2   r   propertyr   r   r    r"   r+   r-   r.   r'   rC   r   r   r   r   r   $   s   
	



Kr   c               @   s   e Zd ZejjZdd Zd"ddZdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd Zdd Zd#ddZdd Zedd Zdd Zdd Zd d! ZdS )$_SSLProtocolTransportc             C   s   || _ || _d| _d S )NF)_loop_ssl_protocol_closed)r   loopZssl_protocolr   r   r   r   !  s    z_SSLProtocolTransport.__init__Nc             C   s   | j ||S )N)rJ   _get_extra_info)r   namedefaultr   r   r   get_extra_info'  s    z$_SSLProtocolTransport.get_extra_infoc             C   s   | j | d S )N)rJ   _set_app_protocol)r   protocolr   r   r   set_protocol+  s    z"_SSLProtocolTransport.set_protocolc             C   s   | j jS )N)rJ   _app_protocol)r   r   r   r   get_protocol.  s    z"_SSLProtocolTransport.get_protocolc             C   s   | j S )N)rK   )r   r   r   r   
is_closing1  s    z _SSLProtocolTransport.is_closingc             C   s   d| _ | j  d S )NT)rK   rJ   _start_shutdown)r   r   r   r   close4  s    z_SSLProtocolTransport.closec             C   s(   | j s$tjd| t| d |   d S )Nzunclosed transport )source)rK   warningswarnResourceWarningrX   )r   r   r   r   __del__?  s    z_SSLProtocolTransport.__del__c             C   s    | j j}|d krtd| S )Nz*SSL transport has not been initialized yet)rJ   
_transportr%   
is_reading)r   trr   r   r   r_   E  s    z _SSLProtocolTransport.is_readingc             C   s   | j j  d S )N)rJ   r^   pause_reading)r   r   r   r   ra   K  s    z#_SSLProtocolTransport.pause_readingc             C   s   | j j  d S )N)rJ   r^   resume_reading)r   r   r   r   rb   S  s    z$_SSLProtocolTransport.resume_readingc             C   s   | j j|| d S )N)rJ   r^   set_write_buffer_limits)r   ZhighZlowr   r   r   rc   [  s    z-_SSLProtocolTransport.set_write_buffer_limitsc             C   s   | j j S )N)rJ   r^   get_write_buffer_size)r   r   r   r   rd   p  s    z+_SSLProtocolTransport.get_write_buffer_sizec             C   s
   | j jjS )N)rJ   r^   _protocol_paused)r   r   r   r   re   t  s    z&_SSLProtocolTransport._protocol_pausedc             C   s<   t |tttfs$tdt|j |s,d S | j| d S )Nz+data: expecting a bytes-like instance, got )	
isinstancebytes	bytearrayr@   	TypeErrortyperD   rJ   _write_appdata)r   r;   r   r   r   r0   y  s
    z_SSLProtocolTransport.writec             C   s   dS )NFr   )r   r   r   r   can_write_eof  s    z#_SSLProtocolTransport.can_write_eofc             C   s   | j   d| _d S )NT)rJ   _abortrK   )r   r   r   r   abort  s    
z_SSLProtocolTransport.abort)N)NN)rD   rE   rF   r   Z_SendfileModeZFALLBACKZ_sendfile_compatibler   rP   rS   rU   rV   rX   r]   r_   ra   rb   rc   rd   rG   re   r0   rl   rn   r   r   r   r   rH     s"   

rH   c               @   s   e Zd Zd+ddZdd Zd,dd	Zd
d Zdd Zdd Zdd Z	dd Z
dd Zd-ddZdd Zdd Zdd Zdd Zd d! Zd"d# Zd.d%d&Zd'd( Zd)d* ZdS )/SSLProtocolFNTc	       	      C   s   t d krtd|d kr tj}n|dkr6td| |sDt||}|| _|rZ|sZ|| _nd | _|| _t	|d| _
t | _d| _|| _|| _| | t| j| | _d | _d| _d| _d| _d | _|| _|| _d S )Nzstdlib ssl module not availabler   z7ssl_handshake_timeout should be a positive number, got )r   F)r	   r%   r   ZSSL_HANDSHAKE_TIMEOUTr   r   r   r   _sslcontextdict_extracollectionsdeque_write_backlog_write_buffer_size_waiterrI   rQ   rH   _app_transport_sslpipe_session_established_in_handshake_in_shutdownr^   _call_connection_made_ssl_handshake_timeout)	r   rL   app_protocolr   Zwaiterr
   r   Zcall_connection_madeZssl_handshake_timeoutr   r   r   r     s:    

zSSLProtocol.__init__c             C   s   || _ t|tj| _d S )N)rT   rf   r   ZBufferedProtocol_app_protocol_is_buffer)r   r   r   r   r   rQ     s    zSSLProtocol._set_app_protocolc             C   sD   | j d krd S | j  s:|d k	r.| j | n| j d  d | _ d S )N)rw   Z	cancelledZset_exceptionZ
set_result)r   r=   r   r   r   _wakeup_waiter  s    

zSSLProtocol._wakeup_waiterc             C   s&   || _ t| j| j| j| _|   d S )N)r^   r   rp   r   r   ry   _start_handshake)r   	transportr   r   r   connection_made  s
    
zSSLProtocol.connection_madec             C   sn   | j r d| _ | j| jj| n| jd k	r2d| j_d | _d | _t| dd rT| j	
  | | d | _d | _d S )NFT_handshake_timeout_handle)rz   rI   	call_soonrT   connection_lostrx   rK   r^   r6   r   cancelr   ry   )r   r=   r   r   r   r     s    


zSSLProtocol.connection_lostc             C   s   | j   d S )N)rT   pause_writing)r   r   r   r   r     s    zSSLProtocol.pause_writingc             C   s   | j   d S )N)rT   resume_writing)r   r   r   r   r     s    zSSLProtocol.resume_writingc             C   s   | j d krd S y| j |\}}W n. tk
rP } z| |d d S d }~X Y nX x|D ]}| j| qXW xr|D ]j}|ry&| jrt| j	| n| j	
| W q tk
r } z| |d d S d }~X Y qX qr|   P qrW d S )NzSSL error in data receivedz/application protocol failed to receive SSL data)ry   r'   	Exception_fatal_errorr^   r0   r   r   Z_feed_data_to_buffered_protorT   data_receivedrW   )r   r;   r)   r*   er<   Zexr   r   r   r     s,    


zSSLProtocol.data_receivedc             C   sT   zB| j  rtd|  | t | js@| j }|r@t	d W d | j
  X d S )Nz%r received EOFz?returning true from eof_received() has no effect when using ssl)rI   	get_debugr   debugr   ConnectionResetErrorr{   rT   eof_receivedZwarningr^   rX   )r   Z	keep_openr   r   r   r   *  s    


zSSLProtocol.eof_receivedc             C   s4   || j kr| j | S | jd k	r,| j||S |S d S )N)rr   r^   rP   )r   rN   rO   r   r   r   rM   @  s
    


zSSLProtocol._get_extra_infoc             C   s.   | j r
d S | jr|   nd| _ | d d S )NTr#   )r|   r{   rm   rk   )r   r   r   r   rW   H  s    
zSSLProtocol._start_shutdownc             C   s.   | j |df |  jt|7  _|   d S )Nr   )ru   r3   rv   r?   _process_write_backlog)r   r;   r   r   r   rk   Q  s    zSSLProtocol._write_appdatac             C   s\   | j  r$td|  | j  | _nd | _d| _| jd | j 	| j
| j| _|   d S )Nz%r starts SSL handshakeT)r#   r   )rI   r   r   r   time_handshake_start_timer{   ru   r3   Z
call_laterr~   _check_handshake_timeoutr   r   )r   r   r   r   r   V  s    


zSSLProtocol._start_handshakec             C   s*   | j dkr&d| j d}| t| d S )NTz$SSL handshake is taking longer than z! seconds: aborting the connection)r{   r~   r   ConnectionAbortedError)r   msgr   r   r   r   e  s    
z$SSLProtocol._check_handshake_timeoutc          
   C   s   d| _ | j  | jj}y|d k	r&|| }W nD tk
rt } z&t|tj	rTd}nd}| 
|| d S d }~X Y nX | j r| j | j }td| |d  | jj|| | |d | jr| j| j |   d| _| j| j d S )NFz1SSL handshake failed on verifying the certificatezSSL handshake failedz%r: SSL handshake took %.1f msg     @@)peercertciphercompressionr   T)r{   r   r   ry   r   Zgetpeercertr   rf   r	   r5   r   rI   r   r   r   r   r   rr   updater   r   r}   rT   r   rx   r   rz   r   r   )r   Zhandshake_excZsslobjr   r=   r   Zdtr   r   r   _on_handshake_completen  s2    

z"SSLProtocol._on_handshake_completec          
   C   s0  | j d ks| jd krd S yxtt| jD ]}| jd \}}|rT| j||\}}n*|rl| j| j}d}n| j| j	}d}x|D ]}| j 
| qW |t|k r||f| jd< | j jr| j   P | jd= |  jt|8  _q*W W nD tk
r* } z$| jr| | n| |d W d d }~X Y nX d S )Nr   r   zFatal error on SSL transport)r^   ry   ranger?   ru   rC   r+   r   r-   	_finalizer0   Z_pausedrb   rv   r   r{   r   )r   ir;   rB   r)   r<   r=   r   r   r   r     s4    

z"SSLProtocol._process_write_backlogFatal error on transportc             C   sV   t |tr(| j r@tjd| |dd n| j||| j| d | jrR| j| d S )Nz%r: %sT)exc_info)messageZ	exceptionr   rR   )	rf   OSErrorrI   r   r   r   Zcall_exception_handlerr^   Z_force_close)r   r=   r   r   r   r   r     s    


zSSLProtocol._fatal_errorc             C   s   d | _ | jd k	r| j  d S )N)ry   r^   rX   )r   r   r   r   r     s    
zSSLProtocol._finalizec             C   s(   z| j d k	r| j   W d |   X d S )N)r^   rn   r   )r   r   r   r   rm     s    
zSSLProtocol._abort)FNTN)N)N)r   )rD   rE   rF   r   rQ   r   r   r   r   r   r   r   rM   rW   rk   r   r   r   r   r   r   rm   r   r   r   r   ro     s*     
+

"
		')
ro   )rs   rZ   r	   ImportError r   r   r   r   logr   r   r   r&   r!   r,   objectr   Z_FlowControlMixinZ	TransportrH   ZProtocolro   r   r   r   r   <module>   s(   
 yx