o bG@sddlZddlZddlZddlZddlZddlZddlZddlmZm Z ddl m Z m Z ddl mZddlmZddlmZmZmZmZmZddlmZmZmZddlmZmZdd lmZm Z Gd d d eZ!da"da#da$da%da&da'd d Z(ddZ)ddZ*ddZ+ddZ,ddZ-ddZ.ddZ/ddZ0GdddZ1Gd d!d!ej2Z2Gd"d#d#ej3Z4Gd$d%d%ej5Z5Gd&d'd'ej6Z6d(d)Z7d*d+Z8e9d,kre(dSdS)-N)ListTuple)connectdefault) ConchOptions) ConchError)channelcommon connection forwardingsession)reactorstdiotask)logusage)ioType networkStringc @seZdZUdZdZgdgdgdgZgdgdgdgd gd gd gZejd gej d dej d dde ej ddej dddgdZ gZ e eeeeeffed<gZe eeeeeffed<ddZddZddZddZdS) ClientOptionsz(Usage: conch [options] host [command] zYconch is a SSHv2 client that allows logging into a remote machine and executing commands.)escapee~) localforwardLNzopt_localforward]zClientOptions.opt_localforwardcCr@)zH Forward remote port to local address (rport:host:port) rAN)rBrCr0rD)r;rrGconnHostconnPortr=r=r>opt_remoteforwardfrIzClientOptions.opt_remoteforwardcGs||d<d||d<dS)Nhost r))join)r;rMr)r=r=r> parseArgsoszClientOptions.parseArgsN)__name__ __module__ __qualname__synopsislongdesc optParametersoptFlagsr Completions CompleterCompleteUserAtHostcompDatar/rrrC__annotations__r0r?rHrLrPr=r=r=r>rs>         rc Cstjdd}d|vr#|d}|||d|}||d|d=|ddD],}z!||}|dddkrK||dddkrKg|||d<Wq)tyUYq)wtazt|Wn#tjy}zt d|t t dWYd}~nd}~wwtd rtd rtd dkrtj }n t td d }ntj}tj }t||t_ ntttj}zt|aWn tydaYnwz ttjd d }Wn tyd}Ynwz0tWtrt|tjt|rttj|tdrtds tdsttjtj n.trt|tjt|r)ttj|tdr3tds8tdsAttjtj wwtj !rVtdsVt d"tdt t#dS)Nr4z-lr3z-or-zERROR: rlogfileza+cWs tdtSNr)r callLater reConnect)ar=r=r>s zrun..r)r r"zConnection to {} closed.rM)$r9argvindex ValueErrorroptions parseOptionsr UsageErrorprintopt_helpr:stdoutopenstderrr startLogging discardLogs doConnectstdinfilenor tcgetattrold BaseExceptionsignalSIGUSR1r run tcsetattrTCSANOWSIGWINCHSIG_DFLisattyformat exitStatus)argsiargurrealoutfdoldUSR1r=r=r>rz}s  $        rzcCs,ddlm}datdtt|)Nrfailurer3g{Gz?) twisted.pythonrrr ra _stopReactorrerrFailurerr=r=r> handleErrors  rcCs$ztWdStyYdSwN)r stoprwr=r=r=r>rs  rcCsdtdvrtddd\td<td<tjsddgt_td}tds*ttd<tds3dtd<nttdtd<td}td}tj}td sRt|ttd <t tdtt }t ||t|| t dS) N@rMr4userz ~/.ssh/id_rsaz ~/.ssh/id_dsaportzhost-key-algorithms)rhrB identitysgetpassgetuserrCr verifyHostKeygetHostKeyAlgorithmsSSHUserAuthClient SSHConnectionr addErrback_ebExit)rMrvhkuaor=r=r>rrs"    rrcCsd|atdtdS)Nzconch: exiting with error 皙?)rr rar)rr=r=r>rs rc Cs.ttjdr tttjr&tjD]\}}t|t t|t }tj |qtj rItj D]\}}t d|d|t||q,tddttdrQtdrWtttdrtrdtd ttd D](}zt|Wqlty}zd dl}|j|jkrWYd}~qld}~wwdSdS) N sendIgnorez!asking for remote forwarding for rAbeforeshutdownr$agentrr)hasattrconn transport _KeepAliverhr/r listenTCPr SSHListenForwardingFactory SSHListenClientForwardingChannelrDr0rmsgrequestRemoteForwardingaddSystemEventTriggerbeforeShutdown openChannel SSHSessionosr_exitsetsidrangecloseOSErrorerrnoEBADF)rEhostportr'rGrrrr=r=r> onConnectsD      rcCsttjjdSr)rrrloseConnectionr=r=r=r>rb srbcCs8tj}|D]\}}td|d|t|qdS)Nz cancelling rA)rhr0rrrcancelRemoteForwarding)r0rGrr=r=r>rs   rcCstds tdtdSdS)N reconnectr)rhr rarr=r=r=r>stopConnectionsrc@s,eZdZddZddZddZddZd S) rcCs*||_d|_t|j|_|jddS)Ni,)r globalTimeoutr LoopingCall sendGloballcstart)r;rr=r=r>__init__sz_KeepAlive.__init__cCs2|jjdddd}||jtd|j|_dS)Ns"conch-keep-alive@twistedmatrix.comr4 wantReply)rsendGlobalRequestaddBoth _cbGlobalr ra _ebGlobalr)r;dr=r=r>r!s  z_KeepAlive.sendGlobalcCs|jr |jd|_dSdSr)rcancel)r;resr=r=r>r(s  z_KeepAlive._cbGlobalcCs |jrd|_|jjdSdSr)rrrrr;r=r=r>r-sz_KeepAlive._ebGlobalN)rQrRrSrrrrr=r=r=r>rs  rc@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)rcCs|ag|_i|_tdSr)rr/r0rrr=r=r>serviceStarted4s zSSHConnection.serviceStartedcCs(|j}g|_|D]}|qtdSr)r/rr)r;lfr'r=r=r>serviceStopped;s   zSSHConnection.serviceStoppedcCsXtd|f}|jd|dd}td|d|||j||||j||dS)N0.0.0.0s tcpip-forwardr4rzrequesting remote forwarding rA) r packGlobal_tcpip_forwardrrr addCallback_cbRemoteForwardingr_ebRemoteForwarding)r;rGrdatarr=r=r>rBs z%SSHConnection.requestRemoteForwardingcCs4td|d|||j|<tt|jdS)Nzaccepted remote forwarding rA)rrr0repr)r;resultrGrr=r=r>rIs z!SSHConnection._cbRemoteForwardingcCs&td|d|dt|dS)Nzremote forwarding rAz failedrr)r;rrGrr=r=r>rNsz!SSHConnection._ebRemoteForwardingcCs^td|f}|d|td|z|j|=Wn ty$Ynwtt|jdS)Nrscancel-tcpip-forwardzcancelling remote forwarding )r rrrrr0 Exceptionr)r;rGrr=r=r>rRs   z$SSHConnection.cancelRemoteForwardingcCs|td|t|\}}t|jt||d|jvr8|j|d}td|t||||dSttjd)NzFTCP r4zconnect forwarding ) remoteWindowremoteMaxPacketrzdon't know about that port) rrr unpackOpen_forwarded_tcpipr0SSHConnectForwardingChannelrr OPEN_CONNECT_FAILED)r; windowSize maxPacketrremoteHPorigHP connectHPr=r=r>channel_forwarded_tcpip\s  z%SSHConnection.channel_forwarded_tcpipcCsVtd|t|jt|jdkrtdtdS|jjd||dS)Nzconnection closing r4zstopping connectionr)rrchannelsr6r __class__ __bases__ channelClosed)r;rr=r=r>rls    zSSHConnection.channelClosedN) rQrRrSrrrrrrrrr=r=r=r>r3s rc@speZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZdS)rssessionc stdjdtdrjjdddd}|dd td r%dStd r-td s1td s4tt }tdrHtd sHd_ j |_ nj |_ fdd |_t|_d}tdrnjdttd dStd rtd rtjd}t|tjd}td|}t||d}jd|ttjjjdttd dStd stjd}t|tjd}td|}t||d}jd|ttjjjdddS)Nzsession z openrsauth-agent-req@openssh.comrr4rcSs t|Srrxr=r=r>rds z(SSHSession.channelOpen..r$r)r r"rcsSr)sendEOFrrr=r>rdsrr&s subsystemTERM123456784Hspty-reqsexecsshell)rridrhr sendRequestr _enterRawModer SSHSessionClient escapeMode handleInput dataReceivedwriteconnectionLostr StandardIOr NSrenvironfcntlioctlr TIOCGWINSZstructunpackpackRequest_pty_reqrxr}_windowResized) r;foorcrtermwinszwinSize ptyReqDatar=rr> channelOpen{sJ      zSSHSession.channelOpenc Cs&|dvrd|_||dS|jdkr|tdkrd|_dS|jdkrd|_|dkr4tdtdS|dkrDdd }td |dS|d krUtd |jj dS|d kr|j d|jj }||D]}|j td||jj |qkdS|d|dSd |_||dS)N)  r4rr3.zdisconnecting from escapecSs6ttjtjtttj t dSr) _leaveRawModer9rmflushrsrkillgetpidrxSIGTSTPrr=r=r=r>_s    z!SSHSession.handleInput.._rRzrekeying connection#s' The following connections are open: z #{} {} ~)rrrhrrrr rarr sendKexInitrrkeyssortrr)r;charrr channelIdr=r=r>rsF         zSSHSession.handleInputcCs|j|dSr)rrr;rr=r=r>rzSSHSession.dataReceivedcCsT|tjkr(tdt|dttjtkr tjj |dStj |dSdS)Nzgot z stderr data) r EXTENDED_DATA_STDERRrrr6rr9rostrbufferr)r;r!rr=r=r> extReceiveds zSSHSession.extReceivedcCstd|jdS)Nzgot eof)rrrloseWriteConnectionrr=r=r> eofReceiveds zSSHSession.eofReceivedcCs td||j|dS)Nzremote side closed )rrr sendCloserr=r=r> closeReceivedszSSHSession.closeReceivedcCs&td|tt|jjdS)Nzclosed )rrrrrrr=r=r>closedszSSHSession.closedcCs(ttd|datdtdS)Nz>Lrz exit status: )rCrrrrrr#r=r=r>request_exit_statusszSSHSession.request_exit_statuscCs|j|dSr)rrrr=r=r>rr$zSSHSession.sendEOFcC|jdSr)rpauseProducingrr=r=r> stopWritingzSSHSession.stopWritingcCr/r)rresumeProducingrr=r=r> startWritingr2zSSHSession.startWritingcGsZtdtjd}td|}|d|d|d|df}|j|dtjdg|RdS) Nrrrr4r3rs window-changez!4L) rrr rrrrrpack)r;rr rnewSizer=r=r>r s "zSSHSession._windowResizedN)rQrRrSnamerrrr(r*r,r-r.rr1r4r r=r=r=r>rws+- rc@ eZdZdS)rNrQrRrSr=r=r=r>rrc@r8)rNr9r=r=r=r>rr:rcCs*tsdStj}t|tjtdadSr`) _inRawModer9rsrtr r{r| _savedRawMode)rr=r=r>rs  rcCsVtrdStj}z t|}|dd}Wnty%tdYdSw|dtj B|d<|dtj tj Btj Btj BtjBtjBtjB@|d<ttdrZ|dtj@|d<|dtjtjBtjBtjBtjBtjBtjB@|d<ttdr|dtj@|d<|dtj@|d<d|dtj<d|dtj<|at|tj|dadS)Nznot a typewriter!rIUCLCrIEXTENr4) r;r9rsrtr rurwrrIGNPARISTRIPINLCRIGNCRICRNLIXONIXANYIXOFFrr=ISIGICANONECHOECHOEECHOKECHONLr>OPOSTVMINVTIMEr<r{r|)rrvnewr=r=r>rsd     r__main__):rrrrxrr9r typingrrtwisted.conch.clientrrtwisted.conch.client.optionsrtwisted.conch.errorrtwisted.conch.sshrr r r r twisted.internetr rrrrrtwisted.python.compatrrrrhrrrvr;r<rzrrrrrrrbrrrr SSHChannelrrrrrrQr=r=r=r>sT   W< $D  2