
    *                     D   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	Z	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lmZ ddlZddlZdZ G d dej0                        Z G d dej0                        Z G d dej0                        Z G d de      Zy)z4WebSocket helper class for tunneling with Cloud IAP.    )absolute_import)division)unicode_literalsN) iap_tunnel_lightweight_websocket)iap_tunnel_websocket_utils)context_aware)
exceptions)log)encodingzbot:iap-tunnelerc                       e Zd Zy)WebSocketConnectionClosedN__name__
__module____qualname__     Alib/googlecloudsdk/api_lib/compute/iap_tunnel_websocket_helper.pyr   r   (       r   r   c                       e Zd Zy)WebSocketInvalidOpcodeErrorNr   r   r   r   r   r   ,   r   r   r   c                       e Zd Zy)WebSocketSendErrorNr   r   r   r   r   r   0   r   r   r   c                   `    e Zd ZdZ	 ddZd ZddZd Zd Zd Z	d Z
d	 Zd
 ZddZd Zd Zy)IapTunnelWebSocketHelperzEHelper class for common operations on websocket and related metadata.c	                 ^   || _         || _        || _        || _        d | _        t        j                  |      }	t        j                  |	d| _	        |r,t        j                  | j                  d<   d| j                  d<   t        j                         }
|
r|
j                  t        j                  j                  u rt!        j"                  d       nJ|
j$                  }t!        j"                  d|       || j                  d<   |
j&                  | j                  d<   t!        j(                         t*        j,                  k7  r2t+        j.                  d	      j1                  t*        j2                         d| _        d
| _        || _        | j8                  rNt;        j<                  ||| j>                  | j@                  | jB                  t
        jD                  g      | _#        y tI        jJ                  ||| j>                  | j@                  | jB                  t
        jD                  g      | _#        y )N)	cert_reqsca_certsr   Fcheck_hostnamez%Using enterprise certificate for mTLSzUsing client certificate %scertfilepassword	websocket )headeron_closeon_dataon_errorsubprotocols)&_on_data	_on_close_proxy_info_conn_id_receiving_threadutilsCheckCACertsFilesslCERT_REQUIRED_sslopt	CERT_NONEr   Configconfig_type
ConfigTypeENTERPRISE_CERTIFICATEr
   debugencrypted_client_cert_pathencrypted_client_cert_passwordGetVerbosityloggingDEBUG	getLoggersetLevelCRITICAL
_is_closed
_error_msg_should_use_new_websocketiap_websocketIapLightWeightWebsocket_OnClose_OnData_OnErrorSUBPROTOCOL_NAME
_websocketr"   WebSocketApp)selfurlheadersignore_certs
proxy_infor&   r%   should_use_new_websocketconn_idr   
caa_config	cert_paths               r   __init__z!IapTunnelWebSocketHelper.__init__7   s   DMDN!DDM!D%%l3H!$!2!2 (*DL"%--dll;',dll#$%%'J

 
 

"
"
9
9:		9:99			/;#,Z #-#L#LZ  W]]*$--g.>.>?DODO%=D"%%%==
==,,==../1do "..
==,,==../1dor   c                 $    | j                          y N)CloserL   s    r   __del__z IapTunnelWebSocketHelper.__del__j   s    JJLr   c                     | j                   s6	 | j                  j                          | j                  s|| _        d| _         yy#  Y  xY w)zClose the WebSocket.TN)rA   rJ   closerB   )rL   msgs     r   rX   zIapTunnelWebSocketHelper.Closem   sD    ?? __do s   A Ac                 p    | j                   xs) | j                  xr | j                  j                          S )z%Check to see if WebSocket has closed.)rA   r-   is_aliverY   s    r   IsClosedz!IapTunnelWebSocketHelper.IsClosedx   s5    OO O##MD,B,B,K,K,M(MPr   c                     | j                   S rW   )rB   rY   s    r   ErrorMsgz!IapTunnelWebSocketHelper.ErrorMsg}   s    ??r   c           
         	 t        j                         t        j                  k(  r.t        j                  d| j
                  t        |      |dd        | j                  j                  |t        j                  j                         y# t        $ r | j                           t        j                  $ r | j                          t               t         $ r}t        j                  d| j
                  d       t#        j$                         d   }| j                          t'        j(                  t+        t-        j.                  t1        |      |      |	             Y d}~yd}~ww xY w)
z"Send data on WebSocket connection.z)[%d] SEND data_len [%d] send_data[:20] %rN   )opcodez1[%d] Error during WebSocket send of Data message.Texc_info   )tb)r
   r;   r<   r=   r8   r,   lenrJ   sendr"   ABNFOPCODE_BINARYEnvironmentErrorrX   "WebSocketConnectionClosedExceptionr   	Exceptionsysrg   r	   reraiser   	tracebackformat_exception_onlytype)rL   	send_dataeri   s       r   SendzIapTunnelWebSocketHelper.Send   s   % 
			w}}	,		=--Y3B	B
oo9Y^^-I-IJ 
jjl77 (
jjl%'' 	%	iiC. <<>!b
jjl
Y<<T!WaH "$% %	%s   BB AE)BE$$E)c                    | j                   r| j                  }n| j                  j                  }|r2t        j                  d| j
                         	 |j                          yy# t        t        j                  f$ rN}t        j                  d| j
                  t        j                  |             | j                          Y d}~yd}~w t        j                  d| j
                  d       | j                          Y yxY w)z)Send WebSocket Close message if possible.z
[%d] CLOSEz1[%d] Unable to send WebSocket Close message [%s].Nz2[%d] Error during WebSocket send of Close message.Trf   )rC   rJ   sockr
   r8   r,   
send_closern   r"   ro   infosix	text_typerX   )rL   rz   rw   s      r   	SendClosez"IapTunnelWebSocketHelper.SendClose   s     %%__d__!!d	iidmm,
  ::< Da 0	2

E	/

s   A% %D >AC7D c                     | j                   sQt        j                  | j                        | _        d| j                  _        | j                  j                          y y )N)targetT)rA   	threadingThread_ReceiveFromWebSocketr-   daemonstartrY   s    r   StartReceivingThreadz-IapTunnelWebSocketHelper.StartReceivingThread   sJ    ??(//++ -d&*d#
""$	 r   c                 P   ||| j                          y|d|}t        j                  d| j                  |       | j                  |       |dk(  ry	 | j	                          y# t
        t        j                  f$ r$ t        j                  d| j                  d        w xY w)	z&Callback for WebSocket Close messages.Nz: z+[%d] Received WebSocket Close message [%s].)r]   i  z)[%d] Error while processing Close messageTrf   )rX   r
   r|   r,   r*   rn   r	   Error)rL   
close_codeclose_reason	close_msgs       r   rF   z!IapTunnelWebSocketHelper._OnClose   s     l2 jjl&5IHH:]]I'JJ9JT 
nnj../ 	hh:}}t-s   A( (=B%c           	      j   t        j                         t        j                  k(  r/t        j                  d| j
                  |t        |      |dd        	 |t        j                  j                  t        j                  j                  fvrt        d|z        | j                  |       y# t        $ rJ}t        j                  d| j
                  t        j                   |             | j#                           d}~w t        j                  d| j
                  d       | j#                           xY w)	z%Callback for WebSocket Data messages.z9[%d] RECV opcode [%r] data_len [%d] binary_data[:20] [%r]Nrd   z!Unexpected WebSocket opcode [%r].z([%d] Error [%s] while sending to client.z)[%d] Error while processing Data message.Trf   )r
   r;   r<   r=   r8   r,   rj   r"   rl   OPCODE_CONTrm   r   r)   rn   r|   r}   r~   rX   )rL   binary_datare   unused_finishedrw   s        r   rG   z IapTunnelWebSocketHelper._OnData   s     W]]*	iiKvs;'7Sb9IK
 
	22!446 
6)*M*0+1 2 	2
mmK  	hh94==}}Q!
jjl	hh:DMM
jjls   AB, ,	D25AC::8D2c           
      4   | j                   st        j                  d| j                  d       t        j                  ddj                  t        j                  t        |      |            z   | j                         t        j                  |      | _        y y )Nz'[%d] Error during WebSocket processing.Trf   z([%d] Error during WebSocket processing:
r#   )rA   r
   r8   r,   r|   joinrs   rt   ru   r}   r~   rB   )rL   exception_objs     r   rH   z!IapTunnelWebSocketHelper._OnError   s}     ??	ii9.	hh:wwy66tM7J7DF GG }} m4do r   c                    	 | j                   rd}| j                   j                  s| j                   j                  rRt        j                  | j                   j                        t        j                  | j                   j                        f}| j
                  j                  t        | j                  | j                   j                  | j                   j                  |       n+| j
                  j                  t        | j                         	 | j                          y#  	 t        j                  d| j                  d       n#  Y nxY wY AxY w#  	 t        j                  d| j                  d       Y y#  Y Y yxY wxY w)z'Receive data from WebSocket connection.N)originsslopthttp_proxy_hosthttp_proxy_porthttp_proxy_auth)r   r   z*[%d] Error while receiving from WebSocket.Trf   z-[%d] Error while closing in receiving thread.)r+   
proxy_user
proxy_passr   DecoderJ   run_foreverTUNNEL_CLOUDPROXY_ORIGINr2   
proxy_host
proxy_portr
   r|   r,   rX   )rL   r   s     r   r   z.IapTunnelWebSocketHelper._ReceiveFromWebSocket   s:   			&&$*:*:*E*E
 &__T-=-=-H-HI%__T-=-=-H-HIK/##+DLL ,,77 ,,77+	 	$ 	- 	##+C+/<< 	$ 	9
jjl	=	/
 	@	/sH   DD" E "E%"EEE
EF"E;;F =F FN)r   )r#   )r   r   r   __doc__rU   rZ   rX   r`   rb   rx   r   r   rF   rG   rH   r   r   r   r   r   r   4   sH    M 2311f	P
%4.%<8
5%r   r   )r   
__future__r   r   r   r<   r0   rq   r   rs   googlecloudsdk.api_lib.computer   rD   r   r.   googlecloudsdk.corer   r	   r
   googlecloudsdk.core.utilr   r}   r"   r   r   r   r   r   objectr   r   r   r   <module>r      s     ; &  '  
 
   \ N - * # - 
 - 
 0 0 *"2"2 )) ov or   