ó à@Qc@€sòddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z dZ dZ dZ ee dƒr©e jZnde jfd„ƒYZdejfd „ƒYZd d d „ƒYZdS( iÿÿÿÿ(twith_statementNiiê i<t WarningPolicycB€seZd„ZRS(cC€s(d|jƒ|t|jƒƒfGHdS(Ns'WARNING: Unknown %s host key for %s: %s(tget_namethexlifytget_fingerprint(tselftclientthostnametkey((s..\sshtunnel.pytmissing_host_keys(t__name__t __module__R (((s..\sshtunnel.pyRstTunnelcB€sVeZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z RS( sThis class is a threaded implementation of an SSH tunnel. You should not access the attributes that starts with an underscore outside this thread of execution (e.g. self._server) for this could run into race conditions. Even when accessing its public attributes (those that don't start with an underscore) you should be careful of acquiring the self.lock reentrant lock (and releasing it once done): with tunnel.lock: if tunnel.connecting: ... whatever... cC€sªtt|ƒjƒt|_||_||_||_||_||_ t j ƒ|_ t j ƒ|_d|_d|_||_t|_t|_d|_g|_dS(N(tsuperR t__init__tTruetdaemont_servert _usernamet_targett _passwordt_keyfilet threadingtRLocktlocktEventt port_is_settNonet local_portt _listen_socktqtFalset _shutdownt connectingt_clientt _connections(RRtservertusernamettargettpasswordtkeyfile((s..\sshtunnel.pyR.s             cC€s|j |jSWdQXdS(N(RR!(R((s..\sshtunnel.pyt is_connectingIs c C€s€tjjdƒtjƒ|_xåtrtjddƒ}z¸yD|jjd|fƒ|jj dƒ|j ||_ WdQXPWnmtj k rð}tjjd||fƒ|j \}}|dkrÑw"n|jdtjƒƒ|‚nXWd|jjƒXq"W|j t|_WdQX|jrZ|jd d |jd |jd |jfƒn(|jd d |jd |jd fƒ|jƒs§|jjƒt|_n|jd dƒ|j t|_WdQX|`x?|jsye|jg}x1|jD]&\}}|j|ƒ|j|ƒqûWtj|ggtƒ\}} } Wn4tk r}} |jsy|jdd| ƒnPnX| rÃt|ƒd krÃ|jd d|jd |jd fƒPn|j|krï|jd dƒ|j ƒng} x¥|jD]š\}}||krR|j!dƒ} | sB| j||fƒqR|j"| ƒn||krÿ|j!dƒ} | s‰| j||fƒq™|j"| ƒqÿqÿWxtt| ƒD]f}|\}}y|jƒWnnXy|jƒWnnX|jd d|ƒ|jj#|ƒqªWqÙWxG|jD]<\}}y|jƒWnnXy|jƒWq"q"Xq"W|jjƒ|j$jƒdS(NsThread started iiÿÿs 127.0.0.1isSocket error: %s for port %d itERRORtINFOs1Connecting to SSH server at %s:%s using key %s...iis$Connecting to SSH server at %s:%s...sConnection openedsError while forwarding data: %rs*Closing tunnel to %s:%s for inactivity... sNew client connection sClient for %s disconnected (%tsyststdouttwritetsocketRRtrandomtrandinttbindtlistenRRterrortargstnotifytexc_infoRtsetR!RRt _connect_sshtcloseR RRR#tappendtselecttTUNNEL_TIMEOUTt Exceptiontlent accept_clienttrecvtsendtremoveR"(RRtexcterrtmsgtsockstsocktchantrtwtxtetclosedtdatatitem((s..\sshtunnel.pytrunMs¦     1(       % (     cC€s|jj||fƒdS(N(Rtput(Rtmsg_typet msg_object((s..\sshtunnel.pyR6¶scC€s?|j0|j|ko4|j|ko4|j|kSWdQXdS(N(RRRR(RR$R%R&((s..\sshtunnel.pytmatch¹s c C€sóyotjƒ|_|jjƒ|jjtƒƒ|jj|jd|jdd|jd|j d|j ƒWnytj k rÍ}t j dkr°|jdt jƒdƒqï|jdt jƒd ƒn"|jdt jƒƒtSXtSd S( säCreate the SSH client and set up the connection. Any exception coming from paramiko will be notified as an error that would cause the failure of the connection. Some of these are: paramiko.AuthenticationException --- raised when authentication failed for some reason paramiko.PasswordRequiredException --- raised when a password is needed to unlock a private key file; this is a subclass of paramiko.AuthenticationException paramiko.PasswordRequiredException --- raised when a password is needed to unlock a private key file; also a subclass of paramiko.AuthenticationException iiR%t key_filenameR'twin32R*s: Delete entries for the host from the SSH known hosts files= Delete entries for the host from the ~/.ssh/known_hosts fileN(tparamikot SSHClientR"tload_system_host_keystset_missing_host_key_policyRtconnectRRRRtBadHostKeyExceptionR,tplatformR6R7RR(RRD((s..\sshtunnel.pyR9½s  @cC€s*|jddƒ|jjƒt|_dS(NR+sClosing tunnel(R6RR:RR (R((s..\sshtunnel.pyR:Ùs cC€sYy|jjƒ\}}Wn(tk rC}|jdd|ƒdSX|jddƒ|jjƒ}y"|jd|j|jƒƒ}WnItk rÐ}|jdd|jd|jd|fƒ|j ƒdSX|dkr|jdd |jd|jdfƒ|j ƒdS|jdd |jƒ|jƒ|jfƒ|j j ||fƒdS( NR*s%Error accepting new tunnel client: %rR+sClient connection establisheds direct-tcpips%Remote connection to %s:%d failed: %riis:Remote connection to %s:%d was rejected by the SSH server.sTunnel now open %r -> %r -> %r( RtacceptR>R6R"t get_transportt open_channelRt getpeernameR:RR#R;(Rt local_socktpeeraddrRMt transporttsshchan((s..\sshtunnel.pyR@Þs&"+  ( ,( R R t__doc__RR)RQR6RUR9R:R@(((s..\sshtunnel.pyR s    i    t TunnelManagercB€sneZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z dd „Z d „Z d „Z RS( cC€s%i|_tj|_tj|_dS(N(ttunnel_by_portR,tstdintinpipeR-toutpipe(R((s..\sshtunnel.pyRùs  cC€sut|ƒtkrmd|kr`|jddƒ\}}yt|ƒ}Wn |}nX||fS||fSn|SdS(Nt:i(ttypetstrtsplittint(Rt raw_addresst default_porttaddresstport((s..\sshtunnel.pyt_address_port_tupleÿs    cC€s‰|j|dtƒ}|j|dtƒ}xX|jjƒD]G\}}|j|||ƒr:|jƒr:|j |jSWdQXq:q:WdS(NRs( RvtSSH_PORTt REMOTE_PORTRit iteritemsRUtisAliveRRR(RR$R%R&Ruttunnel((s..\sshtunnel.pyt lookup_tunnel s! c C€sby|j|||||ƒ}Wn6tk rW}ddl}|jƒtt|ƒfSXt|fS(Niÿÿÿÿ(topen_sshR>t tracebackt print_excRRoR( RR$R%R'R(R&RuRDR~((s..\sshtunnel.pyt open_tunnels  c C€s|j|dtƒ}|j|dtƒ}|p3d}|p?d}d}xB|jjƒD]1}|j|||ƒrX|jƒrX|}PqXqXW|r¹|jd|j GH|j SWdQXnbt t j ƒ|||||ƒ}|j ƒ|j jƒ|j|j }WdQX||j|<|SdS(NRstsReusing tunnel at port %d(RvRwRxRRit itervaluesRURzRRR tQueuetstartRtwait( RR$R%R'R(R&tfoundR{Ru((s..\sshtunnel.pyR} s(  !  !    cC€s |jj|ƒ}|s d|Sd}|jƒr xÔtry|jjƒ\}}Wntjk rjnmX|}t |ƒt kr²ddj t j |Œƒ}t|dƒ}nd||fGH|dkr×|}Pn|jƒ sñ|jƒ rõPntjdƒq5Wn|S(Ns#Could not find a tunnel for port %ds Ris%s: %sR*g333333Ó?(RitgetRRzRRt get_nowaitRƒtEmptyRnttupletjoinR~tformat_exceptionRoR)ttimetsleep(RRuR{R4RSRFt_msg((s..\sshtunnel.pytwait_connection;s,   cC€s |j|}|jjdtƒS(Ntblock(RiRR‡R(RRuR{((s..\sshtunnel.pyt get_messageXs cC€sdS(N((RRu((s..\sshtunnel.pyR:]sRcC€sJ|r%|jj|d|dƒn|jj|dƒ|jjƒdS(Nt s (RlR.tflush(Rtcodetarg((s..\sshtunnel.pyRBgscC€s(x!|jjƒD]}|jƒqWdS(N(RiR‚R:(RR{((s..\sshtunnel.pytshutdownnscC€s|jdƒxtr|jjƒ}|s/Pnyt|iiƒ\}}WndGH|jddƒqnX|dkrðyH|j|Œ}|dk r°|jdt|ƒƒn|jddƒWqtk rì}|jdt|ƒƒqXq|dkrTy)|j |Œ}|jdt|ƒƒWqtk rP}|jdt|ƒƒqXq|d krp|jdƒq|d krµ|j |ƒ}|s¡|jdƒq|jd |ƒq|d krö|j |ƒ}|ræ|j|ƒq|jd ƒqd|GH|jddƒqWdS(NtREADYsIgnoring invalid requestR*sInvalid requesttLOOKUPtOKs not foundtOPENSSHtCLOSEtWAITsERROR tMESSAGEtNONEsInvalid request %s( RBRRktreadlinetevalR|RRoR>R}RR’(RtrequesttcmdR5RuRDR4RF((s..\sshtunnel.pyt wait_requestsssN         ( R R RRvR|R€R}RR’R:RBR—R¤(((s..\sshtunnel.pyRhøs       ((t __future__RRR0RƒR~R/R<R,RRXRwRxR=thasattrRtMissingHostKeyPolicytThreadR Rh(((s..\sshtunnel.pyts$          ÙÖ