Ϫf,dddlZddlZddlZddlZddlmZddlmZddlm Z ddl m Z ddl m Z mZmZmZddlmZddlmZdd lmZmZmZdd lmZdd lmZdd lmZdd lm Z m!Z!m"Z"ddl#m$Z$ddl%m&Z&ddl'm(Z(ddl)m*Z*m+Z+ ddlm,Z,m-Z-e(dZ/e/rddl0m1Z1ddl2m3Z3m4Z4m5Z5nddl6m3Z3GddZ1 ddl7m4Z8e8Z9dZ=e=Z>GddZ?Gdde+Z@Gdd ejZBGd!d"ejZDGd#d$ejZFGd%d&ejZGGd'd(ejZHd>d)ZIGd*d+ZJGd,d-eJZKe e3Gd.d/e1ZLGd0d1ZMGd2d3eJZNGd4d5ZOGd6d7eJeOe+ZPGd8d9eKeOe+ZQGd:d;eNeOe+ZRGd<d=eKe+ZSy#e.$rYFwxYw#e.$rZ:dZ9e;e:Z<[:YdZ:[:,dZ:[:wwxYw)?N)count)skipIf) implementer) ConchError)privateDSA_opensshprivateRSA_opensshpublicDSA_opensshpublicRSA_opensshConchTestRealm)portal)deferprotocolreactor)ProcessExitedAlready) LoopingCall)getProcessValue)filepathlogruntime)FilePath)which) requireModule)SkipTestTestCase)ConchTestServerFactoryconchTestPublicKeyChecker cryptography) ConchUser)ISession SSHSession wrapProtocol)r c eZdZy)rN)__name__ __module__ __qualname__?/usr/lib/python3/dist-packages/twisted/conch/test/test_conch.pyrr1s r(r)r!cd}d} tjtj}|jdd}|r|j |S#t$rYwxYw)z4Returns True if the system can bind an IPv6 address.NF)::1rT)socketAF_INET6bindOSErrorclose)sockhas_ipv6s r) _has_ipv6r3?s[ DH }}V__- *  O    s6A AAceZdZdZdZdZy) FakeStdioz A fake for testing L{twisted.conch.scripts.conch.SSHSession.eofReceived} and L{twisted.conch.scripts.cftp.SSHSession.eofReceived}. @ivar writeConnLost: A flag which records whether L{loserWriteConnection} has been called. Fcd|_y)z9 Record the call to loseWriteConnection. TN) writeConnLostselfs r)loseWriteConnectionzFakeStdio.loseWriteConnection^s "r(N)r$r%r&__doc__r7r:r'r(r)r5r5SsM"r(r5ceZdZdZeeZdZy)StdioInteractingSessionTestsz> Tests for L{twisted.conch.scripts.conch.SSHSession}. Nct}t}||_|j|j |j y)z} L{twisted.conch.scripts.conch.SSHSession.eofReceived} loses the write half of its stdio connection. N)r5StdioInteractingSessionstdio eofReceived assertTruer7)r9r@channels r)test_eofReceivedz-StdioInteractingSessionTests.test_eofReceivedms8  )+  ++,r()r$r%r&r;r?_reasonskiprDr'r(r)r=r=es& -r(r=ceZdZdZdZdZy)Echoc.tjdy)NzECHO CONNECTION MADErmsgr8s r)connectionMadezEcho.connectionMadez &'r(c.tjdy)NzECHO CONNECTION DONErJr9reasons r)connectionLostzEcho.connectionLost}rMr(cx|jj|d|vr|jjyy)N ) transportwriteloseConnectionr9datas r) dataReceivedzEcho.dataReceiveds0 T" D= NN ) ) + r(N)r$r%r&rLrQrYr'r(r)rHrHys((,r(rHceZdZeZy) EchoFactoryN)r$r%r&rHrr'r(r)r[r[sHr(r[c4eZdZdZdZdZdZdZdZdZ dZ y)ConchTestOpenSSHProcessa Test protocol for launching an OpenSSH client process. @ivar deferred: Set by whatever uses this object. Accessed using L{_getDeferred}, which destroys the value so the Deferred is not fired twice. Fires when the process is terminated. Nr(c.|jdc}|_|SNdeferredr9ds r) _getDeferredz$ConchTestOpenSSHProcess._getDeferred==$4=r(c.|xj|z c_yr_)bufrWs r) outReceivedz#ConchTestOpenSSHProcess.outReceiveds Dr(c.|xj|z c_yr_)problemsrWs r) errReceivedz#ConchTestOpenSSHProcess.errReceiveds  r(c x|jjdk7rf|jjt dj |jj|j jdy|jjdd}|jj|y)z~ Called when the process has ended. @param reason: a Failure giving the reason for the process' end. rzexit code was not 0: {} ({})charmaps rSN) valueexitCoderderrbackrformatrjdecodergreplacecallback)r9rPrgs r) processEndedz$ConchTestOpenSSHProcess.processEndeds << A %     ' '299 -- ,,Y7 ((""7E2C     ( ( -r() r$r%r&r;rargrjrdrhrkrur'r(r)r]r]s,H CH.r(r]cDeZdZdZdZdZdZdZdZdZ dZ d Z d Z y) ConchTestForwardingProcessa Manages a third-party process which launches a server. Uses L{ConchTestForwardingPort} to connect to the third-party server. Once L{ConchTestForwardingPort} has disconnected, kill the process and fire a Deferred with the data received by the L{ConchTestForwardingPort}. @ivar deferred: Set by whatever uses this object. Accessed using L{_getDeferred}, which destroys the value so the Deferred is not fired twice. Fires when the process is terminated. Nc.||_d|_||_y)aF @type port: L{int} @param port: The port on which the third-party server is listening. (it is assumed that the server is running on localhost). @type data: L{str} @param data: This is sent to the third-party server. Must end with ' ' in order to trigger a disconnect. N)portbufferrX)r9ryrXs r)__init__z#ConchTestForwardingProcess.__init__s   r(c.|jdc}|_|Sr_r`rbs r)rdz'ConchTestForwardingProcess._getDeferredrer(c$|jyr_)_connectr8s r)rLz)ConchTestForwardingProcess.connectionMades  r(ctjtt||j}|j d|j }|j|j|S)a Connect to the server, which is often a third-party process. Tries to reconnect if it fails because we have no way of determining exactly when the port becomes available for listening -- we can only know when the process starts. 127.0.0.1) r ClientCreatorrConchTestForwardingPortrX connectTCPry addErrback _ebConnect)r9ccrcs r)r~z#ConchTestForwardingProcess._connectsH # #G-DdDII V MM+tyy 1 T__%r(cDtjd|jy)Ng?)r callLaterr~)r9fs r)rz%ConchTestForwardingProcess._ebConnects#t}}-r(c||_|jjd|jjt j d|j y)z The network connection has died; save the buffer of output from the network and attempt to quit the process gracefully, and then (after the reactor has spun) send it a KILL signal. rN)rzrTrUrVrr _reallyDie)r9rzs r)forwardingPortDisconnectedz5ConchTestForwardingProcess.forwardingPortDisconnectedsA   W% %%'!T__-r(cZ |jjdy#t$rYywxYw)NKILL)rT signalProcessrr8s r)rz%ConchTestForwardingProcess._reallyDies+  NN ( ( 0#   s  **cV|jj|jy)z Fire the Deferred at self.deferred with the data collected from the L{ConchTestForwardingPort} connection, if any. N)rdrtrzrOs r)ruz'ConchTestForwardingProcess.processEndeds $$T[[1r() r$r%r&r;rar{rdrLr~rrrrur'r(r)rwrws6 H  . . 2r(rwc(eZdZdZdZdZdZdZy)rz Connects to server launched by a third-party process (managed by L{ConchTestForwardingProcess}) sends data, then reports whatever it received back to the L{ConchTestForwardingProcess} once the connection is ended. c ||_||_y)z @type protocol: L{ConchTestForwardingProcess} @param protocol: The L{ProcessProtocol} which made this connection. @type data: str @param data: The data to be sent to the third-party server. N)rrX)r9rrXs r)r{z ConchTestForwardingPort.__init__ s!  r(c\d|_|jj|jy)Nr()rzrTrUrXr8s r)rLz&ConchTestForwardingPort.connectionMades  TYY'r(c.|xj|z c_yr_)rzrWs r)rYz$ConchTestForwardingPort.dataReceiveds t r(cN|jj|jyr_)rrrzrOs r)rQz&ConchTestForwardingPort.connectionLosts 00=r(N)r$r%r&r;r{rLrYrQr'r(r)rrs (>r(rctjd|zg}g}|t|zD]4}t|tr|j d}|j |6|S)Na$-c ### Twisted Preamble import sys, os path = os.path.abspath(sys.argv[0]) while os.path.dirname(path) != path: if os.path.basename(path).startswith('Twisted'): sys.path.insert(0, path) break path = os.path.dirname(path) from twisted.conch.scripts.%s import run run()utf-8)sys executablelist isinstancestrencodeappend)argsmodstartmadeArgsargs r) _makeArgsrsi     E"HtDz! c3 **W%C Or(cBeZdZesdZedZdZdZdZ dZ dZ y) ConchServerSetupMixinzcan't run without cryptographyctdS)Nstestuserr r'r(r) realmFactoryz"ConchServerSetupMixin.realmFactory=s k**r(cdD]7}tjj|s#tj|9t dd5}|j t dddt dd5}|j tdddt dd5}|j tdddt dd5}|j tdddtjddtjddtdj}|jjs|jjr t!dt d d5}|j d tzdddy#1swY2xYw#1swYxYw#1swYxYw#1swYxYw#1swYyxYw) N)rsa_test rsa_test.pubdsa_test dsa_test.pubkh_testrwbrrrizgprivate key readable by others despite chmod; possible windows permission issue? see https://tm.tl/9767rs 127.0.0.1 )ospathexistsremoveopenrUrr r rchmodrgetPermissionsgroupreadotherr)r9r permissionss r) _createFilesz"ConchServerSetupMixin._createFilesAs~T Aww~~a  !  *d # (q GG& ' ( .$ ' '1 GG% & ' .$ ' '1 GG% & ' *d # (q GG& ' ( U# U#z*99;    ! ![%6%6%;%;*  )T " 7a GGM$55 6 7 7# ( ( ' ' ' ' ( ( 7 7s< F3FF)F5-GFF&)F25F>G ctj}|jd|jd}|j|S)N)r)r,r. getsocknamer0)r9srys r) _getFreePortz"ConchServerSetupMixin._getFreePortYs6 MMO w}}q!   r(c|j}tj|}|jt t }||_|S)z Make a L{ConchTestServerFactory}, which allows us to start a L{ConchTestServer} -- i.e. an actually listening conch. )rr PortalregisterCheckerrr)r9realmpfactorys r)_makeConchFactoryz'ConchServerSetupMixin._makeConchFactory`sF !!# MM%  356(*r(c|j|j|_d|j_t j d|jd|_t j dt|_|jjj|_ trOt j dtd|_ |jjj|_yy)Nrrr) interfacer+)rr conchFactoryexpectedLoseConnectionr listenTCP conchServerr[ echoServergetHostryechoPortHAS_IPV6 echoServerV6 echoPortV6r8s r)setUpzConchServerSetupMixin.setUpls  224340",, t  K "++A{}=//166  ' 1 1![]e TD "//779>>DO r(c d|jj_|jjjj t j|jjt j|jjg}tr8|jt j|jjt j|S#t $rYwxYw)Nr)rprotodonerTrVAttributeErrorr maybeDeferredr stopListeningrrrr gatherResults)r9 deferredss r)tearDownzConchServerSetupMixin.tearDownys ?+,D   # # (    # # - - < < >    0 0 > > ?    = = >     U001B1B1P1PQ R""9--   sC00 C<;C<N) r$r%r&rrF staticmethodrrrrrrr'r(r)rr9s5 /++70  ? .r(rc"eZdZdZdZdZdZy)ForwardingMixina Template class for tests of the Conch server's ability to forward arbitrary protocols over SSH. These tests are integration tests, not unit tests. They launch a Conch server, a custom TCP server (just an L{EchoProtocol}) and then call L{execute}. L{execute} is implemented by subclasses of L{ForwardingMixin}. It should cause an SSH client to connect to the Conch server, asking it to forward data to the custom TCP server. cn|jdt}|j|jdS)z Test that we can use whatever client to send the command "echo goodbye" to the Conch server. Make sure we receive "goodbye" back from the server. echo goodbyegoodbye executer] addCallback assertEqualrbs r) test_execzForwardingMixin.test_execs/ LL)@)B C}}T--|<.writesxW ABw !!&&22%%~7J((*%,{{7+%r(g{Gz?N)rProtocolmakeConnectionr"rrr)r9rTrrUrs ` @r) openShellzRekeyAvatar.openShellsU!!# Y'  e!45 &(5%'* 4r(cy)z2 Ignore the close of the session. Nr'r8s r)closedzRekeyAvatar.closedr(cyr_r'r8s r)rAzRekeyAvatar.eofReceived r(cyr_r')r9rcommands r) execCommandzRekeyAvatar.execCommandr r(cyr_r')r9term windowSizemodess r)getPtyzRekeyAvatar.getPtyr r(cyr_r')r9 newWindowSizes r) windowChangedzRekeyAvatar.windowChangedr r(N) r$r%r&r;r{rr rArrrr'r(r)rrs+4B     r(rceZdZdZdZy) RekeyRealmzS This realm gives out new L{RekeyAvatar} instances for any avatar request. c$|dtdfS)Nrcyr_r'r'r(r)z*RekeyRealm.requestAvatar.. r r()r)r9avatarIDmind interfacess r) requestAvatarzRekeyRealm.requestAvatar s!}km\99r(N)r$r%r&r;r!r'r(r)rrs :r(rceZdZdZeZdZy)RekeyTestsMixinzp TestCase mixin which defines tests exercising L{SSHTransportBase}'s handling of rekeying messages. cnt}jd|d}fd}|j||S)z After a client-initiated rekey is completed, application data continues to be passed over the SSH connection. rz-o RekeyLimit=2KcdjtdDcgc]}d|fz c}dz}|jd}j||ycc}w)N rz line #%02dr)joinrangerr)resultrexpectedResultr9s r)finishedz2RekeyTestsMixin.test_clientRekey..finishedsS!YYU2Y'O t(;'OPSWWN+227;N   V^ 4(Ps A)r]rr)r9rrcr+s` r)test_clientRekeyz RekeyTestsMixin.test_clientRekeys8 *+ LLW&8 9 5 hr(N)r$r%r&r;rrr,r'r(r)r#r# s Lr(r#c(eZdZedsdZddZy)OpenSSHClientMixinsshz$no ssh command-line client availableclttddd}fd}|j|S)a Connects to the SSH server started in L{ConchServerSetupMixin.setUp} by running the 'ssh' command line tool. @type remoteCommand: str @param remoteCommand: The command (with arguments) to run on the remote end. @type process: L{ConchTestOpenSSHProcess} @type sshArgs: str @param sshArgs: Arguments to pass to the 'ssh' process. @return: L{defer.Deferred} r/r)z-ozPubkeyAcceptedKeyTypes=ssh-dssz-Vc|dk(rd}nd}tj_d|z zdzz} jj j }||zj }g}|D]4}t|tr|jd}|j|6tjtdd|jS)Nrz!-oPubkeyAcceptedKeyTypes=ssh-dss rzssh -2 -l testuser -p %i -F /dev/null -oUserKnownHostsFile=kh_test -oPasswordAuthentication=no -oHostKeyAlgorithms=ssh-rsa -a -i dsa_test 127.0.0.1 rr/)rDeferredrarrrysplitrrrrr spawnProcessr) statusoptscmdlinerycmds encodedCmdscmdr remoteCommandr9rs r)hasPAKTz+OpenSSHClientMixin.execute..hasPAKTBs{:$~~/G  #          ##++-22DdN))+DK (c3'**W-C""3' (  %,q/; G## #r()rrr)r9r<rrrcr=s```` r)rzOpenSSHClientMixin.execute*s4(  %LOK " $H}}W%%r(N)r)r$r%r&rrFrr'r(r)r.r.&s <5<&r(r.c@eZdZdZdZdZdZdZdZdZ dZ d Z y ) OpenSSHKeyExchangeTestsz\ Tests L{SSHTransportBase}'s key exchange algorithm compatibility with OpenSSH. cg} tjtddddgtj}t |t s|j d}|j}||vrt|d|jdtd |z}|j|jd S#t$rYWwxYw) aI Call execute() method of L{OpenSSHClientMixin} with an ssh option that forces the exclusive use of the key exchange algorithm specified by keyExchangeAlgo @type keyExchangeAlgo: L{str} @param keyExchangeAlgo: The key exchange algorithm to use @return: L{defer.Deferred} r/rz-Qkex)stderrrz not supported by ssh clientz echo helloz-oKexAlgorithms=shello ) subprocess check_outputrSTDOUTrrrrr4 BaseExceptionrrr]rr)r9keyExchangeAlgo kexAlgorithmsoutputrcs r)assertExecuteWithKexAlgorithmz5OpenSSHKeyExchangeTests.assertExecuteWithKexAlgorithmos  ,,ua$.z7H7HFfc*w/"LLNM - /o..JKL L LL  # %  0  }}T--z::   sA%B55 CCc$|jdS)zb The ecdh-sha2-nistp256 key exchange algorithm is compatible with OpenSSH zecdh-sha2-nistp256rJr8s r)test_ECDHSHA256z'OpenSSHKeyExchangeTests.test_ECDHSHA256 112FGGr(c$|jdS)zb The ecdh-sha2-nistp384 key exchange algorithm is compatible with OpenSSH zecdh-sha2-nistp384rLr8s r)test_ECDHSHA384z'OpenSSHKeyExchangeTests.test_ECDHSHA384rNr(c$|jdS)zb The ecdh-sha2-nistp521 key exchange algorithm is compatible with OpenSSH zecdh-sha2-nistp521rLr8s r)test_ECDHSHA521z'OpenSSHKeyExchangeTests.test_ECDHSHA521rNr(c$|jdS)zl The diffie-hellman-group14-sha1 key exchange algorithm is compatible with OpenSSH. zdiffie-hellman-group14-sha1rLr8s r)test_DH_GROUP14z'OpenSSHKeyExchangeTests.test_DH_GROUP14s 112OPPr(c$|jdS)zs The diffie-hellman-group-exchange-sha1 key exchange algorithm is compatible with OpenSSH. z"diffie-hellman-group-exchange-sha1rLr8s r)test_DH_GROUP_EXCHANGE_SHA1z3OpenSSHKeyExchangeTests.test_DH_GROUP_EXCHANGE_SHA1s 112VWWr(c$|jdS)zu The diffie-hellman-group-exchange-sha256 key exchange algorithm is compatible with OpenSSH. z$diffie-hellman-group-exchange-sha256rLr8s r)test_DH_GROUP_EXCHANGE_SHA256z5OpenSSHKeyExchangeTests.test_DH_GROUP_EXCHANGE_SHA256s 11 2  r(cF|jt|jdy)zy The list of key exchange algorithms supported by OpenSSH client is obtained with C{ssh -Q kex}. zunsupported-algorithmN) assertRaisesrrJr8s r)test_unsupported_algorithmz2OpenSSHKeyExchangeTests.test_unsupported_algorithms  d88:Q r(N) r$r%r&r;rJrMrPrRrTrVrXr[r'r(r)r?r?is5 ;@HHHQX  r(r?c0eZdZdZee ddZy)OpenSSHClientForwardingTestszR Connection forwarding tests run against the OpenSSL command line client. zRequires IPv6 supportc|j}t|d}|jd|d||jfz}|j |j d|S)zG Forwarding of arbitrary IPv6 TCP connections via SSH. rrz-N -L%i:[::1]:%ir)rrwrrrrrs r)test_localToRemoteForwardingV6z;OpenSSHClientForwardingTests.test_localToRemoteForwardingV6sb %%' ,Y B LL !3y$//6R!R   d&& 2r(N)r$r%r&r;rrr_r'r(r)r]r]s% L12 3 r(r]ceZdZdZy)OpenSSHClientRekeyTestszE Rekeying tests run against the OpenSSL command line client. N)r$r%r&r;r'r(r)rarasr(racFeZdZdZej dk(rdZddZdZdZ y) CmdLineClientTestszP Connection forwarding tests run against the Conch command line client. win32z!can't run cmdline client on win32Nc|g}tj|_|jj j }dj ||zdz|z}t||jz}tjj}tjjtj|d<g} i} |D]4}t!|t"r|j%d}| j'|6|D]N} || } t!| t"r| j%d} t!| t"r| j%d} | | | <Pt)j*|tj,| | |jS)z{ As for L{OpenSSHClientTestCase.execute}, except it runs the 'conch' command line tool, not 'ssh'. z[-p {} -l testuser --known-hosts kh_test --user-authentications publickey -a -i dsa_test -v r2 PYTHONPATHr)env)rr3rarrryrqrr4renvironcopypathsepr'rrrrrrrr5r) r9r<rr conchArgsryr;r9rgr: encodedEnvvarvals r)rzCmdLineClientTests.executesd  I >>+'')..  &,  ) ,9  9 .cb_check_logs ++-J MM.* 5r(rz--logz --logfilez--host-key-algorithmszssh-rsa)r<rrkr)rrmktemprr]rrr)r9rurcrts` @r)test_runWithLogFilez&CmdLineClientTests.test_runWithLogFile s{  6##DKKM2 LL(+- '    d&& 5 l#r(ct|jdt}|j|jd|S)zH Do not use --host-key-algorithms flag on command line. r)r<rrrrbs r)%test_runWithNoHostAlgorithmsSpecifiedz8CmdLineClientTests.test_runWithNoHostAlgorithmsSpecified&s; LL(2I2K   d&& 5r()rN) r$r%r&r;r platformTyperFrrwryr'r(r)rcrcs,w&2# J6 r(rc)conch)Trr,rCr itertoolsrunittestrzope.interfacertwisted.conch.errorrtwisted.conch.test.keydatarrr r twisted.conch.test.test_sshr twisted.credr twisted.internetrrrtwisted.internet.errorrtwisted.internet.taskrtwisted.internet.utilsrtwisted.pythonrrrtwisted.python.filepathrtwisted.python.procutilsrtwisted.python.reflectrtwisted.trial.unittestrrrr ImportErrorrtwisted.conch.avatarrtwisted.conch.ssh.sessionr r!r"twisted.conch.interfacestwisted.conch.scripts.conch_StdioInteractingSessionr?errEr3rr5r=rrHFactoryr[ProcessProtocolr]rwrrrrrrr#r.r?r]rarcr'r(r)rs   &* 7557-211,*05 ^, .LL1  7R 7" ;""$-8-( ,8   ,(""(.h66(.VI2!9!9I2X>h//><4M.M.`/+/l XA )A A H::+2@&@&FY 35GY x?4F&o/A8 Q(Qq  " "!fG  s*G6GGGG/ G**G/