Ϫf dZddlZddlmZddlmZddlmZddl m Z m Z ddl Z ddl mZmZmZddlmZdd lmZdd lmZdd lmZdd lmZmZmZmZdd lmZm Z m!Z!m"Z"ddl#m$Z$m%Z%ddl&m'Z'm(Z(ddl)m*Z*m+Z+m,Z,ddl-m.Z.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;e9dreddlm?Z?m@Z@ddlAmBZBmCZCddlDmEZEmFZFmGZGmHZHmIZImJZJmKZKddlLmMZMddlNmOZOddlPmQZQdd lRmSZSdd!lTmUZUdd"lVmWZWdd#lXmYZYdd$lZm[Z[dd%l\m]Z]m^Z^m_Z_m`Z`nd&ZaebZUebZ[ebZSebZWebZQebZOebZCebZ@ebZ=dd'lcmdZdmeZeGd(d)edZfGd*d+eQZgGd,d-eQZhGd.d/eQZiGd0d1ZjGd2d3e'ZkGd4d5ZlGd6d7e[ZmGd8d9eUZnee$Gd:d;Zoee%Gd<d=ZpGd>d?ZqGd@dAe;eqZrGdBdCe;eqZsGdDdEe;ZtGdFdGZuGdHdIe;Zvy)Jz' Tests for L{twisted.conch.endpoints}. N)ENOSYS)pack) implementer) verifyClass verifyObject) ConchErrorHostKeyChangedUserRejectedKey) IConchUser)'InMemoryUsernamePasswordDatabaseDontUse)Portal) IPv4Address)CancelledErrorDeferredfailsucceed)ConnectingCancelledErrorConnectionDoneConnectionRefusedErrorProcessTerminated)IAddressIStreamClientEndpoint)FactoryProtocol)EventLoggingObserverMemoryReactorClockStringTransport)LogLevelglobalLogPublisher) networkString)Failure)FilePath)msg) requireModule)TestCase cryptography) ConchUser)InMemorySSHKeyDBSSHPublicKeyChecker) ConsoleUIKnownHostsFile)AuthenticationFailedSSHCommandAddressSSHCommandClientEndpoint_ExistingConnectionHelper_ISSHConnectionCreator_NewConnectionHelper _ReadFile)common)SSHAgentServer) SSHChannel) SSHConnection) SSHFactory)Key)SSHClientTransport)SSHUserAuthServer)privateDSA_opensshprivateRSA_openssh privateRSA_openssh_encrypted_aespublicRSA_opensshzcan't run w/o cryptography) FakeTransportconnectceZdZdZdZdZy)AbortableFakeTransportzC A L{FakeTransport} with added C{abortConnection} support. Fcd|_y)z} Abort the connection in a fake manner. This should really be implemented in the underlying module. TNabortedselfs C/usr/lib/python3/dist-packages/twisted/conch/test/test_endpoints.pyabortConnectionz&AbortableFakeTransport.abortConnection]s  N)__name__ __module__ __qualname____doc__rErIrJrHrBrBVsGrJrBceZdZdZdZy)BrokenExecSessionzO L{BrokenExecSession} is a session on which exec requests always fail. cy)z Fail all exec requests. @param data: Information about what is being executed. @type data: L{bytes} @return: C{0} to indicate failure @rtype: L{int} rrOrGdatas rH request_execzBrokenExecSession.request_execkrJNrKrLrMrNrUrOrJrHrQrQf  rJrQceZdZdZdZy)WorkingExecSessionzS L{WorkingExecSession} is a session on which exec requests always succeed. cy)z Succeed all exec requests. @param data: Information about what is being executed. @type data: L{bytes} @return: C{1} to indicate success @rtype: L{int} rOrSs rHrUzWorkingExecSession.request_exec}rVrJNrWrOrJrHrZrZxrXrJrZceZdZdZdZy)UnsatisfiedExecSessionz L{UnsatisfiedExecSession} is a session on which exec requests are always delayed indefinitely, never succeeding or failing. ctS)z Delay all exec requests indefinitely. @param data: Information about what is being executed. @type data: L{bytes} @return: A L{Deferred} which will never fire. @rtype: L{Deferred} )rrSs rHrUz#UnsatisfiedExecSession.request_execs zrJNrWrOrJrHr^r^s  rJr^ceZdZdZdZy) TrivialRealmci|_yN) channelLookuprFs rH__init__zTrivialRealm.__init__s rJcLt}|j|_t|dfS)NcyrcrOrOrJrHz,TrivialRealm.requestAvatar..srJ)r'rdr )rGavatarIdmind interfacesavatars rH requestAvatarzTrivialRealm.requestAvatars$#11FL11rJN)rKrLrMrermrOrJrHraras  2rJraceZdZdZdZy)AddressSpyFactoryNc<||_tj||Src)addressr buildProtocol)rGrqs rHrrzAddressSpyFactory.buildProtocols $$T733rJ)rKrLrMrqrrrOrJrHroros G4rJroceZdZdZdZdZy)FixedResponseUIc||_yrc)result)rGrvs rHrezFixedResponseUI.__init__s  rJc,t|jSrc)rrvrGtexts rHpromptzFixedResponseUI.promptst{{##rJcyrcrOrxs rHwarnzFixedResponseUI.warns rJN)rKrLrMrerzr|rOrJrHrtrts$ rJrtc,eZdZedZedZy)FakeClockSSHUserAuthServercB|jjjS)zy Use the C{attemptsBeforeDisconnect} value defined by the factory to make it easier to override. ) transportfactoryattemptsBeforeDisconnectrFs rHrz3FakeClockSSHUserAuthServer.attemptsBeforeDisconnects ~~%%>>>rJcB|jjjS)z Use the reactor defined by the factory, rather than the default global reactor, to simplify testing (by allowing an alternate implementation to be supplied by tests). )rrreactorrFs rHclockz FakeClockSSHUserAuthServer.clocks~~%%---rJN)rKrLrMpropertyrrrOrJrHr~r~s( ??..rJr~c:eZdZedZedZeedZdZ y)CommandFactoryc:dtjtiSNssh-rsa)rT)r8 fromStringr>rFs rH publicKeyszCommandFactory.publicKeyssCNN0ABCCrJc:dtjtiSr)r8rr<rFs rH privateKeyszCommandFactory.privateKeyssCNN0BCDDrJ)s ssh-userauthsssh-connectionrN) rKrLrMrrrr~r6servicesrrOrJrHrrsC DDEE4(H !rJrc eZdZy) MemoryAddressN)rKrLrMrOrJrHrrsrJrceZdZdZdZdZy)SingleUseMemoryEndpointa] L{SingleUseMemoryEndpoint} is a client endpoint which allows one connection to be set up and then exposes an API for moving around bytes related to that connection. @ivar pump: L{None} until a connection is attempted, then a L{IOPump} instance associated with the protocol which is connected. @type pump: L{IOPump} c d|_||_y)z @param server: An L{IProtocol} provider to which the client will be connected. @type server: L{IProtocol} provider N)pump_server)rGservers rHrez SingleUseMemoryEndpoint.__init__s   rJc &|j td |jt}t |j t |j d|t |d|_t|S#t$r tcYSwxYw)Nz(SingleUseMemoryEndpoint was already usedTisServerF) r Exceptionrrrr@rrBr BaseExceptionr)rGrprotocols rHr@zSingleUseMemoryEndpoint.connects 99 FG G %,,]_=H  &t||dC&x%@ DI 8$ $ 6M sA::BBN)rKrLrMrNrer@rOrJrHrrs%rJrceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZddZdZdZy)"SSHCommandClientEndpointTestsMixina Tests for L{SSHCommandClientEndpoint}, an L{IStreamClientEndpoint} implementations which connects a protocol with the stdin and stdout of a command running in an SSH session. These tests apply to L{SSHCommandClientEndpoint} whether it is constructed using L{SSHCommandClientEndpoint.existingConnection} or L{SSHCommandClientEndpoint.newConnection}. Subclasses must override L{create}, L{assertClientTransportState}, and L{finishConnection}. cd|_d|_d|_d|_t |_t |_t|j|_ t|_ |jj|j|j|jj|jt|_|j |j_|j|j_ |jj!|j#|jj$t'ddd|_t'ddd |_y) Nsssh.example.comi&suserspasswordTCPz10.0.0.1i90z192.168.100.200i1)hostnameportuserpasswordrrrarealmr portalr passwdDBaddUserregisterCheckerrrdoStart addCleanupdoStopr clientAddress serverAddressrFs rHsetUpz(SSHCommandClientEndpointTestsMixin.setUps*   # )+ !^ TZZ( ?A  dii7 ##DMM2%' #|| "kk    ++,( EB(0A5IrJcFt|jjd)z Create and return a new L{SSHCommandClientEndpoint} to be tested. Override this to implement creation in an interesting way the endpoint. z did not implement createNotImplementedError __class__rKrFs rHcreatez)SSHCommandClientEndpointTestsMixin.create1s' "~~&&))B C  rJcFt|jjd)a Make an assertion about the connectedness of the given protocol's transport. Override this to implement either a check for the connection still being open or having been closed as appropriate. @param client: The client whose state is being checked. @param immediateClose: Boolean indicating whether the connection was closed immediately or not. z- did not implement assertClientTransportStaterrGclientimmediateCloses rHassertClientTransportStatez=SSHCommandClientEndpointTestsMixin.assertClientTransportState:s#"~~&& )  rJcFt|jjd)z Do any remaining work necessary to complete an in-memory connection attempted initiated using C{self.reactor}. z# did not implement finishConnectionrrFs rHfinishConnectionz3SSHCommandClientEndpointTestsMixin.finishConnectionJs' "~~&&))L M  rJc|jd}|jd}t|d|j|j}t|d|j|j}t ||||}|||fS)aw Set up an in-memory connection between protocols created by C{serverFactory} and C{clientFactory}. @return: A three-tuple. The first element is the protocol created by C{serverFactory}. The second element is the protocol created by C{clientFactory}. The third element is the L{IOPump} connecting them. NF)r hostAddress peerAddressT)rrrBrrr@)rG serverFactory clientFactoryclientProtocolserverProtocolclientTransportserverTransportrs rHconnectedServerAndClientz;SSHCommandClientEndpointTestsMixin.connectedServerAndClientSs'44T:&44T:0 ****   1 ****  ~X~t33rJc8|j}t}t|_|j |}|j \}}}|j t}|jd|djj|djjf|jdt||j|}|jt|jd|jj|j|dy)z If a channel cannot be opened on the authenticated SSH connection, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping the reason given by the server. unknown channelrr\unknown channelFN)rrrrr@rflushLoggedErrorsrassertInvaluerT assertEquallenfailureResultOftrapr) rGendpointr connectedrrrerrorsfs rHtest_channelOpenFailurez:SSHCommandClientEndpointTestsMixin.test_channelOpenFailureps ;;=)#$$W- #446'' 3 '&)//*>*>q @U@U)VW CK(   + z +QWW]]; ''6rJct|jjd<|j}t }t |_|j|}|j\}}}|j|}|jt|jd|jj|j|dy)z If execution of the command fails, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping the reason given by the server. sessionzchannel request failedFN)rQrrdrrrrr@rrrrrrrrGrrrrrrrs rHtest_execFailurez3SSHCommandClientEndpointTestsMixin.test_execFailures 0A   ,;;=)#$$W- #446   + z 1177==A ''6rJcbt|jjd<|j}t }t |_|j|}|j\}}}|j|j|}|jt|j|dy)z If execution of the command is cancelled via the L{Deferred} returned by L{SSHCommandClientEndpoint.connect}, the connection is closed immediately. rTN)r^rrdrrrrr@rcancelrrrrrs rHtest_execCancelledz5SSHCommandClientEndpointTestsMixin.test_execCancelleds 0F   ,;;=)#$$W- #446   + ~ ''5rJc:t|jjd<|j}t }t |_|j||j\}}}|j|jt|j|jj|jj|j|j |jj"|jd|jj$y)aD Once the necessary SSH actions have completed successfully, L{SSHCommandClientEndpoint.connect} uses the factory passed to it to construct a protocol instance by calling its C{buildProtocol} method with an address object representing the SSH connection and command executed. r /bin/ls -lN)rZrrdrrorrr@rassertIsInstancerqr-rrgetHostrrusernamecommand)rGrrrrrs rHtest_buildProtocolz5SSHCommandClientEndpointTestsMixin.test_buildProtocols0B   ,;;=#%#!#446 goo/@A ))113W__5K5KL GOO$<$<= (?(?@rJc*t|jjd<|j}t }t |_|j|}|j\}}}|j|}|j|jy)a L{SSHCommandClientEndpoint} establishes an SSH connection, creates a channel in it, runs a command in that channel, and uses the protocol's C{makeConnection} to associate it with a protocol representing that command's stdin and stdout. rN) rZrrdrrrrr@rsuccessResultOfassertIsNotNonerrGrrrrrrrs rHtest_makeConnectionz6SSHCommandClientEndpointTestsMixin.test_makeConnections|0B   ,;;=)#$$W- #446'' 2 X//0rJct|jjd<|j}t }t |_|j|}|j\}}}|j|}g}|j|_ |jj} |jj| j!d|j#|j%ddj'|y)z After establishing the connection, when the command on the SSH server produces output, it is delivered to the protocol's C{dataReceived} method. r hello, worldrJN)rZrrdrrrrr@rrappend dataReceivedridservicechannelswriterrjoin) rGrrrrrrrr channelIds rHtest_dataReceivedz4SSHCommandClientEndpointTestsMixin.test_dataReceiveds 0B   ,;;=)#$$W- #446'' 2 , 3 3&&))  *00A  #((<*@ArJct|jjd<|j}t }t |_|j|}|j\}}}|j|}g}|j|_ |jj} |jj| j!|j#|dj%t&|j)|dy)zq When the command closes the channel, the protocol's C{connectionLost} method is called. rrFN)rZrrdrrrrr@rrrconnectionLostrrrrloseConnectionrrrr) rGrrrrrrrrrs rHtest_connectionLostz6SSHCommandClientEndpointTestsMixin.test_connectionLosts 0B   ,;;=)#$$W- #446'' 2"0"7"7&&))  *99; q~. ''6rJct|jjd<|j}t }t |_|j|}|j\}}}|j|} g} | j| _ | jj} |jj| } |jj!| ||| j#|j%|j'|d| dS)zJ Test handling of non-zero exit statuses or exit signals. rFr)rZrrdrrrrr@rrrrrrrr sendRequestrrr) rGrequest requestArgrrrrrrrrrchannels rH_exitStatusTestz2SSHCommandClientEndpointTestsMixin._exitStatusTests0B   ,;;=)#$$W- #446'' 2"0"7"7 &&)) ..)))4""7GZ@   ''6a  rJcjd}|jdtd|}|jty) When the command exits with a non-zero status, the protocol's C{connectionLost} method is called with a L{Failure} wrapping an exception which encapsulates that status. r exit-status>LN)rrrr)rGexitCodeexcs rHtest_zeroExitCodez4SSHCommandClientEndpointTestsMixin.test_zeroExitCode2s. "">4h3GH  rJcd}d}|jdtd|}|jt|j ||j j |j ||j jy)r{Nrr)rrrrrrrsignal)rGrrrs rHtest_nonZeroExitStatusz9SSHCommandClientEndpointTestsMixin.test_nonZeroExitStatus<sh "">4h3GH "# 399#5#56 !1!12rJct}tj||jtj|d}d}dj t jddt jdt jdg}|jd|}|jt|j||jj|j||jjd }tj |tj"tj$tj&t(j*|dd d dd y) a When the command exits with a non-zero signal, the protocol's C{connectionLost} method is called with a L{Failure} wrapping an exception which encapsulates that status. Additional packet contents are logged at the C{info} level. NrJsTERMsmessagesen-USs exit-signalz'twisted.conch.endpoints._CommandChannelTmessage) log_level log_namespaceshortSignalName coreDumped errorMessage languageTag)rr addObserverrremoveObserverrr3NSrrrrrrrhamcrest assert_thathas_item has_entriesequal_torinfo)rG logObserverrrpacketr logNamespaces rHtest_nonZeroExitSignalz9SSHCommandClientEndpointTestsMixin.test_nonZeroExitSignalIs +, &&{3 *99;G '" *% (#   "">6: "# 399#5#56 !1!12@     $$%-%6%6x}}%E)5+2&*(1'/    rJc|jj}g|rfd}n j}t|jj |||S)a Hook into and record events which happen to C{protocol}. @param server: The SSH server protocol over which C{protocol} is running. @type server: L{IProtocol} provider @param protocol: @param event: @param noArgs: c&jdSrc)r)recordersrHrhz;SSHCommandClientEndpointTestsMixin.record..s-rJ)rrrsetattrrr)rGrreventnoArgsrrr#s @rHrecordz)SSHCommandClientEndpointTestsMixin.recordwsL &&))  -AA'' 2E1=rJct|jjd<|j}t }t |_|j|}|j\}}}|j|}|j||d}|jjd|j|jddj|y)z The transport connected to the protocol has a C{write} method which sends bytes to the input of the command executing on the SSH server. rrrrJN)rZrrdrrrrr@rrr'rrrrr rGrrrrrrrrs rH test_writez-SSHCommandClientEndpointTestsMixin.test_writes 0B   ,;;=)#$$W- #446'' 2{{68^D   1  #((<*@ArJct|jjd<|j}t }t |_|j|}|j\}}}|j|}|j||d}|jjdg|j|jddj|y)z The transport connected to the protocol has a C{writeSequence} method which sends bytes to the input of the command executing on the SSH server. rrrrJN)rZrrdrrrrr@rrr'r writeSequencerrrr)s rHtest_writeSequencez5SSHCommandClientEndpointTestsMixin.test_writeSequences 0B   ,;;=)#$$W- #446'' 2{{68^D ((/):;  #((<*@ArJN)F)rKrLrMrNrrrrrrrrrrrrrrr r r'r*r-rOrJrHrrsl J(   4:747*6*A.1&B678!:! 3, \6B*BrJrceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZy)NewConnectionTestsz` Tests for L{SSHCommandClientEndpoint} when using the C{newConnection} constructor. ctj|t|j|_t |j|_|j j|j|jjd|j jt|jj|jjd|j jy) Configure an SSH server with password authentication enabled for a well-known (to the tests) account. rN)rrr"mktemp hostKeyPathr+ knownHosts addHostKeyrrrr rhostsaverFs rHrzNewConnectionTests.setUps +006#DKKM2()9)9: ""4==$,,2I2I*2UV "" $,,11 2DLL4K4KJ4W  rJc tj|jd|j|j|j |j |jtdS)zu Create and return a new L{SSHCommandClientEndpoint} using the C{newConnection} constructor. rFrr4ui) r. newConnectionrrrrrr4rtrFs rHrzNewConnectionTests.createsL (55 LL  II MM II]]u%  rJcn|j|j|jjddS)z} Establish the first attempted TCP connection using the SSH server which C{self.factory} can create. r)rrr tcpClientsrFs rHrz#NewConnectionTests.finishConnections4 ,, LL$,,11!4Q7  rJc|j||dd}|jj|j|j dg||j|jj y)a Lose the connection to a server and pump the L{IOPump} sufficiently for the client to handle the lost connection. Asserts that the client disconnects its transport. @param server: The SSH server protocol over which C{protocol} is running. @type server: L{IProtocol} provider @param client: The SSH client protocol over which C{protocol} is running. @type client: L{IProtocol} provider @param protocol: The protocol created by calling connect on the ssh endpoint under test. @type protocol: L{IProtocol} provider @param pump: The L{IOPump} connecting client to server. @type pump: L{IOPump} closedT)r&N)r'rrrrreportDisconnect)rGrrrrr@s rHloseConnectionToServerz)NewConnectionTests.loseConnectionToServersf*VXxE))+  $(  ))+rJc|r&|j|jjy|j|jjy)z Assert that the transport for the given protocol has been disconnected. L{SSHCommandClientEndpoint.newConnection} creates a new dedicated SSH connection and cleans it up after the command exits. N) assertTruerrE disconnectingrs rHrz-NewConnectionTests.assertClientTransportStates7  OOF,,44 5 OOF,,:: ;rJctj|jdd|j|j}|j t t|y)zY L{SSHCommandClientEndpoint} instances provide L{IStreamClientEndpoint}. dummy command dummy userN)r.r;rrrrDrrrGrs rHtest_interfacez!NewConnectionTests.test_interfacesB,99 LL*M4==$))   %:HEFrJctj|jdd|j}|j d|j j y)z L{SSHCommandClientEndpoint} uses the default port number for SSH when the C{port} argument is not specified. rGrHNr.r;rrr_creatorrrIs rHtest_defaultPortz#NewConnectionTests.test_defaultPort$sD ,99 LL*M4==  X..334rJctj|jdd|jd}|j d|j j y)zU L{SSHCommandClientEndpoint} uses the C{port} argument if specified. rGrHi)rNrMrIs rHtest_specifiedPortz%NewConnectionTests.test_specifiedPort.sF,99 LL*M4==t  x00556rJc 2tj|jd|j|j|j |j |jtd}t}t|_ |j||jjd\}}}}}|j|jt||j|j ||jdt!|jjy)z L{SSHCommandClientEndpoint} uses the L{IReactorTCP} passed to it to attempt a connection to the host/port address also passed to it. rFr9rr\N)r.r;rrrrrr4rtrrrr@r>rr r)rGrrr6rtimeout bindAddresss rHtest_destinationz#NewConnectionTests.test_destination7s ,99 LL  II MM II]]u%  )#!48LL4K4KA4N1dGWk  d(;< D) C 7 789rJc tj|jdd|j|j|j t d}t}t|_ |j|}|jjdd}|jdtt|j|j!ty)z If a connection cannot be established, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} representing the reason for the connection setup failure. rrHFr4r:rr=N)r.r;rrrr4rtrrrr@r>clientConnectionFailedr!rrrrGrrds rHtest_connectionFailedz(NewConnectionTests.test_connectionFailedOs ,99 LL   MM IIu% )#   W %,,))!,Q/&&tW5K5M-NO Q$$%;rrr rs rHtest_userRejectedHostKeyz+NewConnectionTests.test_userRejectedHostKeygs,99 LL   MM II%dkkm4u% )#$$W- #<< LL$,,11!4Q7    + rJc tjtj}t t |j }|jt|jj|tjtdj}|j|j|td}tj|j dd|j|j"d||}t%}t&|_|j+|}|j-|j.|j j0dd \}} } |j3|} | j5t6y ) ac If the SSH public key presented by the SSH server does not match the previously remembered key, as reported by the L{KnownHostsFile} instance use to construct the endpoint, for that server, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping L{HostKeyChanged}. stestxp) passphraseTrrHdummy passwordr9rr=N)r8rr<publicr+r"r2r5r rr6r=rrtr.r;rrrrrr@rrr>rrr ) rGfirstKeyr4 differentKeyr:rrrrrrrs rHtest_mismatchedHostKeyz)NewConnectionTests.test_mismatchedHostKeys8>>"45<<>#HT[[]$;< mD,>,>,C,CDhO~~ , &(  dmm\: T "+99 LL   MM II&!  )#$$W- #<< LL$,,11!4Q7    + ~rJc tj|jdd|j|j|j t d}t}t|_ |j|}t}|jjdd}|jd}|j||jt!t#|j%|j't"y)aU If the connection closes at any point before the SSH transport layer has finished key exchange (ie, gotten to the point where we may attempt to authenticate), the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping the reason for the lost connection. rrHFrWrr=N)r.r;rrrr4rtrrrr@rr>rrmakeConnectionrr!rrrrGrrrZrrs rH!test_connectionClosedBeforeSecurez4NewConnectionTests.test_connectionClosedBeforeSecures,99 LL   MM IIu% )#   W %#% ,,))!,Q/&&t,i(gn&678 Q$$^4rJc btj|jdd|j|j|j t d}t}t|_ |j|}tdd}|jjdd}|jd}|j||j|j!|j#t$|j'|j(|j+t-t/y) a[ If the connection is cancelled before the SSH transport layer has finished key exchange (ie, gotten to the point where we may attempt to authenticate), the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping L{CancelledError} and the connection is aborted. rrHFrWNrrr=)r.r;rrrr4rtrrrr@rBr>rrrfrrrrrDrErr!rrgs rH$test_connectionCancelledBeforeSecurez7NewConnectionTests.test_connectionCancelledBeforeSecures,99 LL   MM IIu% )#   W %*4%@ ,,))!,Q/&&t,i(   Q$$^4  ))* gn&678rJc tj|jdd|j|j|j t d}t}t|_ |j|}|j|j|jt|j|jj dj"y)zz If the connection is cancelled before it finishes connecting, the connection attempt is stopped. rrHFrWrN)r.r;rrrr4rtrrrr@rrrrrD connectorsstoppedConnectingrYs rH'test_connectionCancelledBeforeConnectedz:NewConnectionTests.test_connectionCancelledBeforeConnecteds ,99 LL   MM IIu% )#   W %   Q$$%=>  //2DDErJc Ntj|jdd|j|jd|j t d}t}t|_ |j|}|j|j|jjdd\}}}|jj|jj |j#|j%|}|j't(|j+|dy) z If the SSH server rejects the password presented during authentication, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping L{AuthenticationFailed}. rrHr`Fr9rr=N)r.r;rrrr4rtrrrr@rrr>advancer passwordDelayflushrrr,rrs rH"test_passwordAuthenticationFailurez5NewConnectionTests.test_passwordAuthenticationFailures ,99 LL   MM II&u%  )#$$W- #<< LL$,,11!4Q7  V^^99:   + #$ ''6rJc|jDcic]*\}}|tj|jg,}}}t t |}|j |ycc}}w)a Create an L{ISSHPrivateKey} checker which recognizes C{users} and add it to C{portal}. @param portal: A L{Portal} to which to add the checker. @type portal: L{Portal} @param users: The users and their keys the checker will recognize. Keys are byte strings giving user names. Values are byte strings giving OpenSSH-formatted private keys. @type users: L{dict} N)itemsr8rrar)r(r)rGruserskvmappingcheckers rHsetupKeyCheckerz"NewConnectionTests.setupKeyChecker-sa@E{{}Mtq!1s~~a(//122MM%&6w&?@w'Ns/A,c tjt}|j|j|j t itj|jd|j |j|j|g|jtd}t}t|_|j#|}|j%|j&|jj(dd\}}}|j+|}|j-t.|j1|j2j4y)z If the SSH server rejects the key pair presented during authentication, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping L{AuthenticationFailed}. rFkeysr4r:rr=N)r8rr<r{rrr;r.r;rrrr4rtrrrr@rrr>rrr,rDrrE) rGbadKeyrrrrrrrs rH#test_publicKeyAuthenticationFailurez6NewConnectionTests.test_publicKeyAuthenticationFailure>s  23 T[[4996H*IJ+99 LL  II MM IIu%  )#$$W- #<< LL$,,11!4Q7    + #$ ((667rJc :tjt}|j|j|j t itj|jd|j |j|j|g|j|jtd }t}t |_|j%|}|j&xj(dz c_|j+|j&|jj,dd\}}}|j/|j1t2}|j5d|dj6j8|dj6j6f|j;dt=||j?|} | jAt2|j;d| j6j6|jC|jDjFy ) z{ If the SSH server does not accept any of the specified SSH keys, the specified password is tried. rF)r~rr4r:r\rr=rrN)$r8rr<r{rrr;r.r;rrrrr4rtrrrr@rrrr>rrrrrrTrrrrrDrrE) rGrrrrrrrrrs rHtest_authenticationFallbackz.NewConnectionTests.test_authenticationFallbackcs  23 T[[4996H*IJ+99 LL  II MM II]]u%  )#$$W-  --2-#<< LL$,,11!4Q7  '' 3 '&)//*>*>q @U@U)VW CK(   + z +QWW]]; ((667rJc tjt}|j|j|j tit |jjd<tj|jd|j |j|j|g|jtd}t!}t"|_|j'|}|j)|j*|jj,dd\}}}|j/|}|j1|j2y)z If L{SSHCommandClientEndpoint} is initialized with any private keys, it will try to use them to authenticate with the SSH server. rrFr}rr=N)r8rr;r{rrrZrrdr.r;rrrr4rtrrrr@rrr>rrr) rGkeyrrrrrrrs rHtest_publicKeyAuthenticationz/NewConnectionTests.test_publicKeyAuthentications nn/0 T[[4996H*IJ/A   ,+99 LL  II MM IIu%  )#$$W- #<< LL$,,11!4Q7 '' 2 X//0rJc (tj|jd|j|j|j |j td}t}t|_ |j|}|j|j|jjdd\}}}|j|j!|}|j#t$|j'|j(j*y)z If the password is not specified, L{SSHCommandClientEndpoint} doesn't try it as an authentication mechanism. rFrWrr=N)r.r;rrrrr4rtrrrr@rrr>rrrr,rDrrErs rHtest_skipPasswordAuthenticationz2NewConnectionTests.test_skipPasswordAuthentications ,99 LL  II MM IIu% )#$$W- #<< LL$,,11!4Q7     + #$ ((667rJc btjt}t}t |_|j |dfi|j _|j|j|jtit|}tj|jd|j|j|j |j"t%d|}t&|j(j*d<t }t,|_|j1|}|j3|j |jj4dd\}}} t7dD],} |j8j9| j9.|j;|} |j=| j>|jA||| | |jC|j>jD|jC|j8jFjDy ) a  If L{SSHCommandClientEndpoint} is initialized with an L{SSHAgentClient}, the agent is used to authenticate with the SSH server. Once the connection with the SSH server has concluded, the connection to the agent is disconnected. rJrF)r4r: agentEndpointrrr=N)$r8rr<r4rrblobr~r{rrrr.r;rrrr4rtrZrrdrrr@rr>rangerrrrrBrDrEclientIO) rGr agentServerrrrrrrrirs rHtest_agentAuthenticationz+NewConnectionTests.test_agentAuthenticationsnn/0$& %i $'HHJc #;   T[[4996H*IJ/ < +99 LL  II MM IIu%'  0B   ,)#$$W- #<< LL$,,11!4Q7  r A    # # % IIK '' 2 X//0 ##FFHdC ((667  **33AABrJcft|jjd<|j}t }t |_|j|}|j\}}}|j|}|j|||||j|jjy)z The transport connected to the protocol has a C{loseConnection} method which causes the channel in which the command is running to close and the overall connection to be closed. rN)rZrrdrrrrr@rrrBrDrrErs rHtest_loseConnectionz&NewConnectionTests.test_loseConnections 0B   ,;;=)#$$W- #446'' 2 ##FFHdC ((667rJN)rKrLrMrNrrrrBrrJrOrQrUr[r]rdrhrjrnrsr{rrrrrrrOrJrHr/r/s   !,F <G57:0=0 8*X5< 9DF,&7P("#8J.8`1>8B1Cf8rJr/c(eZdZdZdZdZdZdZy)ExistingConnectionTestsze Tests for L{SSHCommandClientEndpoint} when using the C{existingConnection} constructor. c tj|tt|j }|j |j |jjd|j t|jj|jjdtj|jd|j|j |j |j"|t%d|_y)r1rrFr9N)rrr+r"r2r5rrrr rr6r.r;rrrrrtr)rGr4s rHrzExistingConnectionTests.setUp#s +006#HT[[]$;< dmmT\\-D-DZ-PQ $,,11 2DLL4K4KJ4W 1>> LL  II MM II]]!u%   rJc,t}t|_|jj |}|j j j} t|j j d<|j|j|jjdd\}}}|j j j|j j j|||_||_||_|j%|}|j&j(}t+j,|dS#|j j j|j j j|wxYw)zz Create and return a new L{SSHCommandClientEndpoint} using the C{existingConnection} constructor. rrr=r)rrrrr@rrdcopyrZrrrr>clearupdater_client_pumprrconnr.existingConnection) rGrrrdrrrr connections rHrzExistingConnectionTests.create;s9 )#MM))'2  00557  ;3EDJJ $ $Z 0#'#@#@ dll55a8;$ FFD JJ $ $ * * , JJ $ $ + +M :   '' 2'',, ':::}UU JJ $ $ * * , JJ $ $ + +M :sAEA Fc|jj|jj|jj|jj|j|j|jfS)z Give back the connection established in L{create} over which the new command channel being tested will exchange data. )rrrrrFs rHrz(ExistingConnectionTests.finishConnectionYsU    ||T\\4::55rJc|j|jj|j|jjy)a Assert that the transport for the given protocol is still connected. L{SSHCommandClientEndpoint.existingConnection} re-uses an SSH connected created by some other code, so other code is responsible for cleaning it up. N) assertFalserrErErs rHrz2ExistingConnectionTests.assertClientTransportStategs8 ))778 ))112rJN)rKrLrMrNrrrrrOrJrHrrs  0V< 63rJrc(eZdZdZdZdZdZdZy)ExistingConnectionHelperTestsz1 Tests for L{_ExistingConnectionHelper}. cJ|jttty)zT L{_ExistingConnectionHelper} implements L{_ISSHConnectionCreator}. N)rDrr0r/rFs rHrJz,ExistingConnectionHelperTests.test_interfacews  $:.sFrJN)rpatchr1rr4)rGrrvs @rHtest_defaultKnownHostsz/NewConnectionHelperTests.test_defaultKnownHostssS  '8JK% $dD$dD$  ff//0rJctjd}t|j}t |}|j d||j td|jtjjd}|jj|d}|jtd|td|tj}|j|j!d|y)z Existing entries in the I{known_hosts} file are reflected by the L{KnownHostsFile} created by L{_NewConnectionHelper} when none is supplied to it. rs 127.0.0.1zCreated known_hosts file at z~/rzPatched _KNOWN_HOSTS with N)rrr"r2r+r5r7r#pathos expanduserreplacerr1rrD hasHostKey)rGrrr4homedefaultloadeds rHtest_readExistingz*NewConnectionHelperTests.test_readExistings ))*5 &#D) lC0 *499- 89ww!!$'))##D$/ 'A ( 45%113 )),<=rJc ltdddddddddd }|j|jty)zz If L{None} is passed for the C{ui} parameter to L{_NewConnectionHelper}, a L{ConsoleUI} is used. N)r1rr:r*rs rHtest_defaultConsoleUIz.NewConnectionHelperTests.test_defaultConsoleUIs9 & $dD$dD$  fii3rJc td}tdddddddddd| }|j|jj d}|j |y)z If L{None} is passed for the C{ui} parameter to L{_NewConnectionHelper} and /dev/tty is available, the L{ConsoleUI} used is associated with /dev/tty. syesNsdoes this work?)rr1rr:rzrDrGttyrrvs rHtest_ttyConsoleUIz*NewConnectionHelperTests.test_ttyConsoleUIs] v% $dD$dD$ %%fii&6&67I&JK rJc t|j}tdddddddddd| }|j|jj d}|j |y)z If L{None} is passed for the C{ui} parameter to L{_NewConnectionHelper} and /dev/tty is not available, the L{ConsoleUI} used is associated with some file which always produces a C{b"no"} response. Nsdid this break?)r"r2r1rr:rzrrs rH test_nottyUIz%NewConnectionHelperTests.test_nottyUIse t{{}%% $dD$dD$ %%fii&6&67I&JK  rJc vtdddddddddd }|jtd|jy)zy If not passed the name of a tty in the filesystem, L{_NewConnectionHelper} uses C{b"/dev/tty"}. Ns/dev/tty)r1rr"rrs rHtest_defaultTTYFilenamez0NewConnectionHelperTests.test_defaultTTYFilenames> & $dD$dD$  +. ;rJc tdddddddddd }t}t|_|j |d|j |jj y)z L{_NewConnectionHelper.cleanupConnection} closes the transport cleanly if called with C{immediate} set to C{False}. NF)r1r6rrrrDrE)rGrrs rHrz=NewConnectionHelperTests.test_cleanupConnectionNotImmediatelys_ & $dD$dD$ #_ .0   U3  ,,::;rJc  Gdd}tdddddddddd }t}t|_||j_|j |d|j |jjj y)z L{_NewConnectionHelper.cleanupConnection} closes the transport with C{abortConnection} if called with C{immediate} set to C{True}. ceZdZdZdZy)MNewConnectionHelperTests.test_cleanupConnectionImmediately..AbortableFcd|_y)z7 Abort the connection. TNrDrFs rHrIz]NewConnectionHelperTests.test_cleanupConnectionImmediately..Abortable.abortConnection3s  $ rJN)rKrLrMrErIrOrJrH Abortabler0s G $rJrNT)r1r6r9rrrDrE)rGrrrs rHrz:NewConnectionHelperTests.test_cleanupConnectionImmediately*s  $ $& $dD$dD$ #_ 13 )2 &  T2  ,,66>>?rJN)rKrLrMrNrJrrrrrrrrrrOrJrHrrs<S R 1>.4   !< <@rJr)wrNos.pathrerrnorstructrzope.interfacerzope.interface.verifyrrrtwisted.conch.errorrr r twisted.conch.interfacesr twisted.cred.checkersr twisted.cred.portalr twisted.internet.addressrtwisted.internet.deferrrrrtwisted.internet.errorrrrrtwisted.internet.interfacesrrtwisted.internet.protocolrrtwisted.internet.testingrrrtwisted.loggerrrtwisted.python.compatr twisted.python.failurer!twisted.python.filepathr"twisted.python.logr#twisted.python.reflectr$twisted.trial.unittestr%twisted.conch.avatarr'twisted.conch.checkersr(r)twisted.conch.client.knownhostsr*r+twisted.conch.endpointsr,r-r.r/r0r1r2twisted.conch.sshr3twisted.conch.ssh.agentr4twisted.conch.ssh.channelr5twisted.conch.ssh.connectionr6twisted.conch.ssh.factoryr7twisted.conch.ssh.keysr8twisted.conch.ssh.transportr9twisted.conch.ssh.userauthr:twisted.conch.test.keydatar;r<r=r>skiprtwisted.test.iosimr?r@rBrQrZr^rarortr~rrrrr/rrrrrOrJrHrs&;KK/I&0JJ H7 8/*,"0+ .LI)64:4*>< (DJM CJNN I5 ]   $$Z&2244  .!2.(!Z!* X    "##%#%$#%LkBkB\ ] 8#E] 8@R3h(JR3j)1H)1X::6G@xG@rJ