
                             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ZddlmZ ddlmZ ddlmZ dd	lmZ d
ZdZdZdZdZ G d dej2                        Z G d de      Zy)z6Implementation for tunneling through Security Gateway.    )absolute_import)division)unicode_literalsN)iap_tunnel_websocket_utils)sg_tunnel_utils)
exceptions)logi      zX-Resource-KeyzProxy-Authorizationc                       e Zd Zy)SGConnectionErrorN)__name__
__module____qualname__     /lib/googlecloudsdk/api_lib/compute/sg_tunnel.pyr   r   *   s    r   r   c                   D    e Zd ZdZ	 ddZd Zd Zd Zd Zd Z	d Z
d	 Zy
)SecurityGatewayTunnelz1Creates the tunnel connection to the destination.c                     || _         || _        || _        || _        || _        d | _        d | _        d| _        t        j                         \  | _
        | _        y )NF)_ignore_certs_get_access_token_callback_send_local_data_callback _close_local_connection_callback_target_sock_sending_thread	_stoppingsocket
socketpair_spair_rpair)selftargetaccess_token_callbacksend_local_data_callbackclose_local_connection_callbackignore_certss         r   __init__zSecurityGatewayTunnel.__init__1   sZ     &D&;D#%=D",KD)DLDJDDN  &002DKr   c                 $    | j                          y )N)Closer"   s    r   __del__zSecurityGatewayTunnel.__del__I   s    JJLr   c                    t        j                  | j                         t        j                  | j
                        }| j
                  rt        j                  |      }nt        j                  |      }t        j                  | j                  j                        \  }}t        j                  j                  |||      }dj                  | j                  j                  | j                  j                         }i }t#        | j$                        r&dj                  | j%                               |t&        <   | j                  j(                  r[t        j*                  | j                  j,                  | j                  j.                  | j                  j0                        |t2        <   nZt        j4                  | j                  j,                  | j                  j.                  | j                  j0                        |t2        <   t7        j8                  d|       |j;                  d||       t        j                  j=                  |j>                  d|      }|jA                         \  }	}
}|
t        j                  jB                  k7  r%t7        jD                  d	|
|       tG        d
|z         |j>                  | _$        | jH                  jK                  d       t7        jL                  d|       tO        jP                  | jR                        | _*        d| jT                  _+        | jT                  jY                          y)z<Starts a tunnel to the destination through Security Gateway.)cafile)contextz{}:{}z	Bearer {}zSending headers: %sCONNECT)headers)methodurlz.Connection request status [%s] with reason: %sz7Security Gateway failed to connect to destination url: FzConnected to [%s])r#   TN)-sg_utilsValidateParametersr   	iap_utilsCheckCACertsFiler   ssl_create_unverified_contextcreate_default_contextGetProxyHostPorturl_overridehttpclientHTTPSConnectionformathostportcallabler   PROXY_AUTH_HEADERuse_dest_groupGenerateDestGroupResourcePathprojectregionsecurity_gatewayRESOURCE_KEY_HEADER#GenerateSecurityGatewayResourcePathr	   debugrequestHTTPResponsesock_read_statusOKerrorr   r   setblockinginfo	threadingThread_RunReceiver   daemonstart)r"   ca_certsssl_ctx
proxy_host
proxy_portconndst_addrr1   resp_codereasons               r   InitiateConnectionz(SecurityGatewayTunnel.InitiateConnectionL   so    -))$*<*<=H..h?g**(;g%66!!#J
 ;;&&z:w&OD~~dll//1B1BCHG//0#.#5#5

)
)
+$-g ||""%-%K%K
,,


,,


,,
'
'&)g!" 
6
6ll""ll!!ll++- !"
 II#W-LLHgL6;;##DIIiX#ND))+Qft{{~~	ii@$O
Ch
NP P DJJJ5!HH (+$++43C3CDD"&D r   c                     | j                   S )z?Signals to parent thread that this connection should be closed.)r   r+   s    r   
ShouldStopz SecurityGatewayTunnel.ShouldStop|   s     >>r   c                    | j                   sA| j                  r5| j                  j                  d       | j                  j	                          | j                          | j                  y	 | j                  j                  t        j                         | j                  j                          y# t        j                  t        f$ r }t        j                  d|       Y d}~yd}~ww xY w)z8Attempts to close both the local and tunnel connections.   0Nz3Failed to close connection to remote endpoint: [%s])r   r   r    sendjoinr   r   shutdownr   	SHUT_RDWRcloserR   EnvironmentErrorr	   rL   )r"   es     r   r*   zSecurityGatewayTunnel.Close   s    >>d22 kkt
!))+zzJ jj&**+
jjLL*+ J	iiEqIIJs   ,AB0 0C)	C$$C)c                    t        |      }t        j                         t        j                  k(  r5t        j
                  j                         j                  d||dd fz         d}||k  r&	 || j                  j                  |      z  }||k  r%yy# t        j                  t        j                  t        f$ r* t        j                  d| j                  gdt               Y Yw xY w)z:Attempts to send all bytes in data to the remote endpoint.z'DEBUG: SEND data_len [%d] data[:20] %r
N   r   r   )lenr	   GetVerbosityloggingDEBUGerrGetConsoleWriterStreamwriter   ri   r8   SSLWantWriteErrorSSLWantReadErrorBlockingIOErrorselectSEND_TIMEOUT_SECONDS)r"   datadata_len	sent_datas       r   SendzSecurityGatewayTunnel.Send   s    4yH
W]]*	gg$$&,,
4$s)7L
LNI
h
BTZZ__T**	 h
 ##S%9%9?K Bb4::,,@ABs   .B AC&%C&c                 n   	 | j                   s| j                  sn| j                  gg}| j                  j                         s2t        j                  | j                  | j                  gddt
              }|d   D ]  }|| j                  u r	d| _          n|| j                  u s*| j                         \  }}t        j                         t        j                  k(  r>t        j                  j                         j                  dt        |      |dd fz         |dk(  rYt        j                  d| j                   j"                  | j                   j$                         | j'                  d       d| _          n|dkD  s| j'                  |        | j                   sd| _         y# d| _         w xY w)	z7Receives server data and sends to the local connection.r   r   Tz'DEBUG: RECV data_len [%d] data[:20] %r
Nrq   z)Remote endpoint [%s:%d] closed connectionr   )r   r   pendingr|   r!   RECV_TIMEOUT_SECONDS_Readr	   rs   rt   ru   rv   rw   rx   rr   rL   r   rA   rB   r   )r"   readysr~   r   s        r   rW   z!SecurityGatewayTunnel._RunReceive   s\   zz
**zz!!#--T[[ 92r 46%qA$++!DN$**_!ZZ\ND(!W]]2gg,,.44<$icr@, ,- 1}iiC))4<<+<+<>,,S1#dn!|,,T2%  6 dntdns   B#F+ &CF+  F+ +	F4c                     d}	 | j                   j                  t              }|t        |      fS # t        j                  t        j
                  t        f$ r |dfcY S w xY w)zCReads MAX_BYTES_SOCKET_READ bytes of data from the remote endpoint.r   )r   recvMAX_BYTES_SOCKET_READr8   ry   rz   r{   rr   )r"   r~   s     r   r   zSecurityGatewayTunnel._Read   s\    DZZ__23d T? !!3#7#7I 2Xos   0 ,AAN)F)r   r   r   __doc__r(   r,   rd   rf   r*   r   rW   r   r   r   r   r   r   .   s6    9 30.!`
J(B@r   r   )r   
__future__r   r   r   http.clientr=   rt   r|   r   r8   rU   googlecloudsdk.api_lib.computer   r6   r   r4   googlecloudsdk.corer   r	   r   r   r}   rJ   rD   Errorr   objectr   r   r   r   <module>r      sq    = &  '     
  R F * #    & ) 
(( [F [r   