ϪfݲdZddlZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddl mZddlmZmZddlmZmZdd lmZdd lmZdd lmZdd lmZed Zer ddlmZm Z m!Z!n GddZ!GddZ"GddZ#ee!jHGddZ%ee!jLGdde%Z'GddZ(Gdde jRZ*GddZ+Gdd Z,Gd!d"e,Z-Gd#d$Z.Gd%d&eeZ/Gd'd(eeZ0Gd)d*eZ1Gd+d,eZ2Gd-d.eZ3Gd/d0eZ4y)1zb Tests for the 'session' channel implementation in twisted.conch.ssh.session. See also RFC 4254. N)skipIf) implementer)defererrorprotocol IPv4Address) ProcessDoneProcessTerminated) componentsfailure)Failure) requireModule)RegistryUsingMixin)TestCase cryptography)common connectionsessionc eZdZddlmZmZmZy)rr)EnvironmentVariableNotPermittedISessionISessionSetEnvN)__name__ __module__ __qualname__twisted.conch.interfacesrrrA/usr/lib/python3/dist-packages/twisted/conch/test/test_session.pyrr"s   rrceZdZdZdZy)SubsystemOnlyAvatarz^ A stub class representing an avatar that is only useful for getting a subsystem. c$|dk(sJtS)z If the other side requests the 'subsystem' subsystem, allow it by returning a MockProtocol to implement it. Otherwise raise an assertion. subsystem) MockProtocolselfnamedatas r lookupSubsystemz#SubsystemOnlyAvatar.lookupSubsystem0s |###~rNrrr__doc__r*rrr r"r"*s  rr"ceZdZdZdZy) StubAvatarz A stub class representing the avatar representing the authenticated user. It implements the I{ISession} interface. cf|dk(r,t|_||j_|jSy)z If the user requests the TestSubsystem subsystem, connect them to a MockProtocol. If they request neither, then None is returned which is interpreted by SSHSession as a failure. TestSubsystemN)r% subsystem packetDatar&s r r*zStubAvatar.lookupSubsystem?s1 # #)^DN(,DNN %>> ! $rNr+rrr r.r.9s  "rr.c:eZdZdZdZdZdZdZdZdZ dZ y ) StubSessionForStubAvatara2 A stub ISession implementation for our StubAvatar. The instance variables generally keep track of method invocations so that we can test that the methods were called. @ivar avatar: the L{StubAvatar} we are adapting. @ivar ptyRequest: if present, the terminal, window size, and modes passed to the getPty method. @ivar windowChange: if present, the window size passed to the windowChangned method. @ivar shellProtocol: if present, the L{SSHSessionProcessProtocol} passed to the openShell method. @ivar shellTransport: if present, the L{EchoTransport} connected to shellProtocol. @ivar execProtocol: if present, the L{SSHSessionProcessProtocol} passed to the execCommand method. @ivar execTransport: if present, the L{EchoTransport} connected to execProtocol. @ivar execCommandLine: if present, the command line passed to the execCommand method. @ivar gotEOF: if present, an EOF message was received. @ivar gotClosed: if present, a closed message was received. c ||_d|_y)z2 Store the avatar we're adapting. N)avatar shellProtocol)r'r6s r __init__z!StubSessionForStubAvatar.__init__es !rc8|dk7r |||f|_ytd)zw If the terminal is 'bad', fail. Otherwise, store the information in the ptyRequest variable. badznot getting a ptyN) ptyRequest RuntimeError)r'terminalwindowmodess r getPtyzStubSessionForStubAvatar.getPtyls& v '7DO23 3rc2|dk(r td||_y)zw If all the window sizes are 0, fail. Otherwise, store the size in the windowChange variable. rrrrznot changing the window sizeN)r< windowChange)r'r>s r windowChangedz&StubSessionForStubAvatar.windowChangedvs \ !=> > &D rc`|j td||_t||_y)z If we have gotten a shell request before, fail. Otherwise, store the process protocol in the shellProtocol variable, connect it to the EchoTransport and store that as shellTransport. Nznot getting a shell this time)r7r< EchoTransportshellTransport)r'pps r openShellz"StubSessionForStubAvatar.openShells1    )>? ?!#D "/"3D rc||_|dk(r||_y|dddk(r,||_t||_|j |ddyt d)z If the command is 'true', store the command, the process protocol, and the transport we connect to the process protocol. Otherwise, just store the command and raise an error. successNsrepeatznot getting a command)execCommandLine execProtocolrF execTransport outReceivedr<)r'rHcommands r execCommandz$StubSessionForStubAvatar.execCommands] ' j "D  Ra[I % "D !.r!2D  NN712; '67 7rcd|_y)z2 Note that EOF has been received. TN)gotEOFr's r eofReceivedz$StubSessionForStubAvatar.eofReceiveds  rcd|_y)z4 Note that close has been received. TN) gotClosedrVs r closedzStubSessionForStubAvatar.closeds rN) rrrr,r8r@rDrIrSrWrZrrr r4r4Ks*0"4' 48  rr4c.eZdZdZfdZdZdZxZS)StubSessionForStubAvatarWithEnva Same as StubSessionForStubAvatar, but supporting environment variables setting. End users would want to have the same class annotated with C{@implementer(session.ISession, session.ISessionSetEnv)}. The interfaces are split for backwards compatibility, so we split it here to test this compatibility too. @ivar environ: a L{dict} of environment variables passed to the setEnv method. c@t||i|_i|_yN)superr8environ environAtPty)r'r6 __class__s r r8z(StubSessionForStubAvatarWithEnv.__init__s   rcv|dk(r td|dk(rtjd||j|<y)ak If the requested environment variable is 'FAIL', fail. If it is 'IGNORED', raise EnvironmentVariableNotPermitted, which should cause it to be silently ignored. Otherwise, store the requested environment variable. (Real applications should normally implement an allowed list rather than a blocked list.) FAILz$disallowed environment variable nameIGNOREDz!ignored environment variable nameN)r<rrr`)r'r(values r setEnvz&StubSessionForStubAvatarWithEnv.setEnvsE 7?EF F Z 993 "'DLL rcB|jj|_y)zs Just a simple implementation which records the current environment when PTY is requested. N)r`copyra)r'term windowSizer?s r r@z&StubSessionForStubAvatarWithEnv.getPtys !LL--/r)rrrr,r8rgr@ __classcell__)rbs@r r\r\s '&0rr\c"eZdZdZdZdZdZy)rFay A transport for a ProcessProtocol which echos data that is sent to it with a Window newline (CR LF) appended to it. If a null byte is in the data, disconnect. When we are asked to disconnect, disconnect the C{ProcessProtocol} with a 0 exit code. @ivar proto: the C{ProcessProtocol} connected to us. @ivar data: a L{bytes} of data written to us. cP||_d|_d|_|j|y)z Initialize our instance variables. @param processProtocol: a C{ProcessProtocol} to connect to ourself. FrN)protorZr)makeConnection)r'processProtocols r r8zEchoTransport.__init__s' %   &&t,rc|xj|z c_|jj||jjdd|vr|jyy)z We got some data. Give it back to our C{ProcessProtocol} with a newline attached. Disconnect if there's a null byte.  N)r)rorQloseConnectionr'r)s r writezEchoTransport.writesN T  t$ w' d?    ! rc N|jryd|_|jj|jj|jj |jj t jtjdddy)z If we're asked to disconnect (and we haven't already) shut down the C{ProcessProtocol} with a 0 exit code. Nr) rZroinConnectionLostoutConnectionLosterrConnectionLost processEndedr rrr rVs r ruzEchoTransport.loseConnectionsp ;;   ##% $$& $$& 0G0G4QU0V WXrN)rrrr,r8rwrurrr rFrFs - " YrrFc&eZdZdZdZdZdZdZy)r%a> A sample Protocol which stores the data passed to it. @ivar packetData: a L{bytes} of data to be sent when the connection is made. @ivar data: a L{bytes} of the data passed to us. @ivar open: True if the channel is open. @ivar reason: if not None, the reason the protocol was closed. rc~d|_d|_d|_|jr|j |jyy)zc Set up the instance variables. If we have any packetData, send it along. rTN)r)openreasonr2 dataReceivedrVs r connectionMadezMockProtocol.connectionMades7    ??   doo . rcj|xj|z c_|jj|dzy)z Store the received data and write it back with a tilde appended. The tilde is appended so that the tests can verify that we processed the data. ~N)r) transportrwrvs r rzMockProtocol.dataReceived"s( T  TD[)rc d|_||_y)z: Close the protocol and store the reason. FN)rr)r'rs r connectionLostzMockProtocol.connectionLost+s  rN)rrrr,r2rrrrrr r%r% sJ /*rr%c>eZdZdZd dZdZdZdZd dZdZ d Z y) StubConnectiona A stub for twisted.conch.ssh.connection.SSHConnection. Record the data that channels send, and when they try to close the connection. @ivar data: a L{dict} mapping C{SSHChannel}s to a C{list} of L{bytes} of data they sent. @ivar extData: a L{dict} mapping L{SSHChannel}s to a C{list} of L{tuple} of (L{int}, L{bytes}) of extended data they sent. @ivar requests: a L{dict} mapping L{SSHChannel}s to a C{list} of L{tuple} of (L{str}, L{bytes}) of channel requests they made. @ivar eofs: a L{dict} mapping L{SSHChannel}s to C{true} if they have sent an EOF. @ivar closes: a L{dict} mapping L{SSHChannel}s to C{true} if they have sent a close. NcXi|_i|_i|_i|_i|_||_y)z4 Initialize our instance variables. N)r)extDatarequestseofsclosesr)r'rs r r8zStubConnection.__init__Ds.     "rcy)z, Return our logging prefix. MockConnectionrrVs r logPrefixzStubConnection.logPrefixOs rc|jj|ry|jj|gj |y)z' Record the sent data. N)rgetr) setdefaultappend)r'channelr)s r sendDatazStubConnection.sendDataUs6 ;;??7 #  Wb)006rc|jj|ry|jj|gj ||fy)z0 Record the sent extended data. N)rrrrr)r'rtyper)s r sendExtendedDatazStubConnection.sendExtendedData]s: ;;??7 #  ,33T4LArc|jj|ry|jj|gj |||f|rt j dSy)z2 Record the sent channel request. N)rrrrrrsucceed)r'rrequestr) wantReplys r sendRequestzStubConnection.sendRequestesT ;;??7 #    "-44gtY5OP ==& & rcZ|jj|ryd|j|<y)z& Record the sent EOF. NT)rrrr'rs r sendEOFzStubConnection.sendEOFos% ;;??7 # ! 'rc"d|j|<y)z( Record the sent close. TN)rrs r sendClosezStubConnection.sendClosews $ Grr^)F) rrrr,r8rrrrrrrrr rr3s+ # 7B'"$rrc6eZdZdZdZdZdZdZdZdZ dZ y ) StubTransportz A stub transport which records the data written. @ivar buf: the data sent to the transport. @type buf: L{bytes} @ivar close: flags indicating if the transport has been closed. @type close: L{bool} rFctdddS)2 Return an arbitrary L{IAddress}. TCP remotehosti"rrVs r getPeerzStubTransport.getPeers5,55rctdddS)rr localhosti'rrVs r getHostzStubTransport.getHosts5+t44rc.|xj|z c_y)z, Record data in the buffer. N)bufrvs r rwzStubTransport.writes Drcd|_y)z6 Note that the connection was closed. TN)closerVs r ruzStubTransport.loseConnections  rcy)z0 Pretend to set C{TCP_NODELAY}. Nr)r'enableds r setTcpNoDelayzStubTransport.setTcpNoDelaysrN) rrrr,rrrrrwrurrrr rr~s, C E6 5    rrceZdZdZdZdZy)StubTransportWithWriteErrz A version of StubTransport which records the error data sent to it. @ivar err: the extended data sent to the transport. @type err: L{bytes} rc.|xj|z c_y)z Record the extended data in the buffer. This was an old interface that allowed the Transports from ISession.openShell() or ISession.execCommand() to receive extended data from the client. N)errrvs r writeErrz"StubTransportWithWriteErr.writeErrs DrN)rrrr,rrrrr rrs CrrceZdZdZdZy) StubClientz A stub class representing the client to a SSHSession. @ivar transport: A L{StubTransport} object which keeps track of the data passed to it. c"t|_yr^)rrrVs r r8zStubClient.__init__s 24rN)rrrr,r8rrr rrs 5rrceZdZdZesdZd dZd dZdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!y)!SessionInterfaceTestsz Tests for the SSHSession class interface. This interface is not ideal, but it is tested in order to maintain backwards compatibility. cannot run without cryptographyctj||j|_|r-t j t ttj|j|_y)z Make an SSHSession object to test. Give the channel some window so that it's allowed to send packets. 500 and 100 are arbitrary values. N) rsetUp getSSHSessionrr registerAdapterr\r.rr'register_adapterss r rzSessionInterfaceTests.setUpsR   &))+   & &/W=M=M ))+ rcTtjddttS)z+ Return a new SSH session. d) remoteWindowremoteMaxPacketconnr6)r SSHSessionrr.rs r rz#SessionInterfaceTests.getSSHSessions(!!!<   rcX|j|jjty)zj Asserts that self.session.session is an instance of StubSessionForStubOldAvatar. N)assertIsInstancerr4rVs r assertSessionIsStubSessionz0SessionInterfaceTests.assertSessionIsStubSessions dll224LMrctjt}|j|jd|j |j |j |jy)z SSHSession initializes its buffer (buf), client, and ISession adapter. The avatar should not need to be adaptable to an ISession immediately. )r6rN)rrobject assertEqualr assertIsNoneclient)r'ss r test_initzSessionInterfaceTests.test_initsL   f - $ !((# !))$rc|jjdt|j_|jjd|j |jjj j dy)z SSHSession.dataReceived() passes data along to a client. If the data comes before there is a client, the data should be discarded. 12N)rrrrrrrrVs r test_client_dataReceivedz.SessionInterfaceTests.test_client_dataReceiveds\ !!$'(l  !!$' ,,66::DArc|jjtjd|jjddt |j_|jjtjd|j |jj jjdy)z SSHSession.extReceived() passed data of type EXTENDED_DATA_STDERR along to the client. If the data comes before there is a client, or if the data is not of type EXTENDED_DATA_STDERR, it is discared. rr3N) r extReceivedrEXTENDED_DATA_STDERRrrrrrrVs r test_client_extReceivedz-SessionInterfaceTests.test_client_extReceiveds   !@!@$G   d+(l    !@!@$G ,,66::DArctx}|j_t|_|jj t jdy)z SSHSession.extReceived() should handle the case where the transport on the client doesn't have a writeErr method. ignoredN)rrrrrrrrr'rs r &test_client_extReceivedWithoutWriteErrz?rc |jt}|jt|dddj |Dcgc] }t |c}z|dj tycc}w)zo Assert that the request we just made raised a RuntimeError (and only a RuntimeError). ryz!Multiple RuntimeErrors raised: %s rN)flushLoggedErrorsr<rlenjoinreprtrap)r'errorsrs r assertRequestRaisedRuntimeErrorz5SessionInterfaceTests.assertRequestRaisedRuntimeErrorsf '' 5  K /ii&9e9: ; q |$:sA4c|jjdd}|j||j|j |jj tj |j|jjj|jj |j|jjdd|jy)z When a client requests a shell, the SSHSession object should get the shell by getting an ISession adapter for the avatar, then calling openShell() with a ProcessProtocol to attach. shellrN) rrrrrrSSHSessionProcessProtocolrr7rr rs r test_requestShellz'SessionInterfaceTests.test_requestShellsll**8S9  '') dll1173T3TU dll**88$,,:M:MN 55hDE ,,.rc|jjdd}|j||j|jj d|j |jjj jd|j |jjj|jddg|j|jjj j|j |jjj|jdgy)z When a client executes a shell, it should be able to give pass data back and forth between the local and the remote side. r rs some datars exit-statussFN) rrrrrrrGr)rrZrrs r test_requestShellWithDataz/SessionInterfaceTests.test_requestShellWithDatas ll**8S9  '') !!"23 --<<AACST  LL   " "4<< 03CW2M   ,,;;BBC  LL   & &t|| 4 9 : rc|jjdtjd}|j ||j |j |jj|j|jjdtjd|j|j|jjtj|j|jjj|jj|j|jjjdy)z When a client requests a command, the SSHSession object should get the command by getting an ISession adapter for the avatar, then calling execCommand with a ProcessProtocol to attach and the command line. execsfailurerKN)rrrrrr rrrrrrrrOrrNrs r test_requestExecz&SessionInterfaceTests.test_requestExecsll**7FIIj4IJ  ,,. $,,--.  44Wfii >STU '') dll1173T3TU dll**779L9LM --==zJrcV|jjdtjd}|j ||j |jj d|j|jjjjd|j|jjj|jgd|jj|jj|jj|j |jjjj|j|jjj|jdgy)zo When a client executes a command, it should be able to give pass data back and forth. rs repeat hello some data)shellorrsrN)rrrrrrrrrPr)rrWrrZrrs r test_requestExecWithDataz.SessionInterfaceTests.test_requestExecWithDatas$ ll**7FIIo4NO  '') !!,/ --;;@@,O  LL   " "4<< 02S    " ""$   ,,::AAB  LL   & &t|| 4 9 : rc P|j|jdtjtt t j|j}|jdt jddd}|j||j|j t|j|j|jdt jddd|j|j j ddgfy) a When a client requests a PTY, the SSHSession object should make the request by getting an ISession adapter for the avatar, then calling getPty with the terminal type, the window size, and any modes the client gave us. Frpty_reqr:ryrsgoodN) doCleanupsrr rr4r.rrrrpackRequest_pty_reqrrr rrr;)r' test_sessionrs r test_requestPtyz%SessionInterfaceTests.test_requestPtys  U +"" $j'2B2B ))+ ** 33FL#N   l224LM ,,.   ( (G77sS  --887LRT:UVrc |j|jjdtjdtjdz|j |jjt |j|j|jjdtjdtjdz|j|jg|j|jjdtjdtjdz|j|jjjddiy) a When a client requests passing an environment variable, the SSHSession object should make the request by getting an ISessionSetEnv adapter for the avatar, then calling setEnv with the environment variable name and value. rrdr:rerNAMEvalueN) rrrrrrr\r rrrr`rVs r test_setEnvz!SessionInterfaceTests.test_setEnvs!  LL ( (71CfiiPVFW1W X  dll224ST ,,.  LL ( ( *- *0EE  //126  LL ( ( '*VYYx-@@  --557JKrc |j}|j|jdtjdtjdz|j|jdtjdtjdz|j |j t|jddd|j jy)zG Multiple setenv requests will share the same session. rKey1Value 1Key2Value2r*r,N) rrrrrrrr\rr`r'r#s r test_setEnvSessionSharez-SessionInterfaceTests.test_setEnvSessionShares))+    ( ( '*VYYz-BB    ( ( '*VYYy-AA  l224ST  9 5|7K7K7S7S rc|j}|jdtjdtjdz|jdtjdtjdz|jdt j ddd |j |jt|jddd |jjy ) z Calling another session service after setenv will provide the previous session with the environment variables. rr*r+r,r-rtermrBrr.N) rrrrrr"rr\rrar/s r test_setEnvMultiplexSharez/SessionInterfaceTests.test_setEnvMultiplexShare2s ))+ $$VVYYw-?&))JBW-WX$$VVYYw-?&))IBV-VW$$ 33G\3O  l224ST  9 5|7K7K7X7X rc J|j|jdtjtt t j|j|j jdtjdtjdzy)z If the avatar does not have an ISessionSetEnv adapter, then a request to pass an environment variable fails gracefully. Frrr&r'N) r!rr rr4r.rrrrrrrVs r %test_setEnvNotProvidingISessionSetEnvz;SessionInterfaceTests.test_setEnvNotProvidingISessionSetEnvDsu  U +"" $j'2B2B   LL ( ( '*VYYx-@@  rc|jjdtjd}|j||j |j |j |jjdtjd|j|jjjdy)z When the client requests to change the window size, the SSHSession object should make the request by getting an ISession adapter for the avatar, then calling windowChanged with the new window size. window_changerBrN) rrpackRequest_window_changerr rrrrCrs r test_requestWindowChangez.SessionInterfaceTests.test_requestWindowChangeVs ll** g?? M   ,,. '')  LL ( ( '"C"CL"Q  --::LIrctj|jj|j_|jj|j |jjj y)z When an EOF is received and an ISession adapter is present, it should be notified of the EOF message. N)rrr6rWrrUrVs r test_eofReceivedz&SessionInterfaceTests.test_eofReceivedisQ '// 0C0CD    "  ,,334rc|jj}|j||j|jjj |jy)zT When a close is received, the session should send a close message. N)rrrrrrrs r test_closeReceivedz(SessionInterfaceTests.test_closeReceivedrsIll((* #  ))00>?rctj|jj|j_|jj|j |jjj y)z When a close is received and an ISession adapter is present, it should be notified of the close message. N)rrr6rZrrYrVs r test_closedz!SessionInterfaceTests.test_closedzsQ '// 0C0CD    ,,667rN)T)"rrrr,rskiprrrrrrrrrrrrrrr rrrrr$r(r0r3r5r9r;r=r?rrr rrs 0 ,  N %B B N44&/  "R0 @ %/  &K$ ,W<L: , $ $J&5@8rrc<eZdZdZesdZdZdZdZdZ dZ dZ y ) SessionWithNoAvatarTestsa  Test for the SSHSession interface. Several of the methods (request_shell, request_exec, request_pty_req, request_env, request_window_change) would create a 'session' instance variable from the avatar if one didn't exist when they were called. rc6tj|tjtt t jt j|_t |j _ |j|j j yr^) rrr rr4r.rrrr6rrVs r rzSessionWithNoAvatarTests.setUpsc  &"" $j'2B2B ))+ (l  $,,../rc|jtjj|jjd|jjzy)zB self.session.session should provide I{ISession}. zISession not provided by %rN)rrr providedByrVs r assertSessionProvidesISessionz6SessionWithNoAvatarTests.assertSessionProvidesISessions@     ' ' (<(< = )DLL,@,@ @ rc\|jjdd|jy)ze If an ISession adapter isn't already present, request_shell should get one. r rN)rrrFrVs r test_requestShellGetsSessionz5SessionWithNoAvatarTests.test_requestShellGetsSessions$ $$Xs3 **,rc|jjdtjd|j y)zd If an ISession adapter isn't already present, request_exec should get one. rrKN)rrrrrFrVs r test_requestExecGetsSessionz4SessionWithNoAvatarTests.test_requestExecGetsSessions- $$Wfii .CD **,rc|jjdtjddd|jy)zg If an ISession adapter isn't already present, request_pty_req should get one. rr2rBrN)rrr"rFrVs r test_requestPtyReqGetsSessionz6SessionWithNoAvatarTests.test_requestPtyReqGetsSessions8 $$ 33G\3O  **,rc|jjdtjd|jy)zm If an ISession adapter isn't already present, request_window_change should get one. r7)ryryryryN)rrr8rFrVs r #test_requestWindowChangeGetsSessionz*_!&&x0_- ++//A gtTl+   2U112rc t}t|_tj|}|j |j d|j|jjd|jtjtjddd|jjtjy)a. L{wrapPRocessProtocol}, when passed a L{Protocol} should return something that follows the L{IProcessProtocol} interface, with connectionMade() mapping to connectionMade(), outReceived() mapping to dataReceived() and processEnded() mapping to connectionLost(). rsdata~rN)r%rrrwrapProcessProtocolrrQrrr}r rrr rr )r'rprocess_protocols r !test_wrapProcessProtocol_Protocolz/WrappersTests.test_wrapProcessProtocol_Protocols >*_"66x@'')$$W- ++//:%% OOE33AtTB C  U445rN)rrrr,rr@rVrZrrr rPrPs 03$6rrPc6eZdZdZesdZdZdZdZdZ dZ y) HelpersTestszM Tests for the 4 helper functions: parseRequest_* and packRequest_*. rc |jtjtjdt j dddddztjt j ddd zdd d gfy ) a1 The payload of a pty-req message is:: string terminal uint32 columns uint32 rows uint32 x pixels uint32 y pixels string modes Modes are:: byte mode number uint32 mode value xterm>4Lryrrr >BLrLrryrr )rarLN)rrparseRequest_pty_reqrrstructpackrVs r test_parseRequest_pty_reqz&HelpersTests.test_parseRequest_pty_reqsq   ( ( (#++eQ1a01))FKKq!456  |fX .  rc tjddd}|j|tjdt j dddddztjt j d d d zy zG See test_parseRequest_pty_req for the payload format. r^rbsr_ryrrr r`rarLNrr"rrrrdrer'packeds r test_packRequest_pty_req_oldz)HelpersTests.test_packRequest_pty_req_oldsr,, l$;    IIh kk%Aq!, -ii E1a01 2 rc tjddd}|j|tjdt j dddddztjt j d d d zy rhrirjs r test_packRequest_pty_reqz%HelpersTests.test_packRequest_pty_req!sr,, l$;    IIh kk%Aq!, -ii E1a01 2 rc ||jtjtjddddddy)a The payload of a window_change request is:: uint32 columns uint32 rows uint32 x pixels uint32 y pixels parseRequest_window_change() returns (rows, columns, x pixels, y pixels). r_ryrrr rbN)rrparseRequest_window_changerdrerVs r test_parseRequest_window_changez,HelpersTests.test_parseRequest_window_change/s4   . .v{{5!Q1/M N  rc ||jtjdtjdddddy)zM See test_parseRequest_window_change for the payload format. rbr_ryrrr N)rrr8rdrerVs r test_packRequest_window_changez+HelpersTests.test_packRequest_window_change?s4   - -l ; KKq!Q * rN) rrrr,rr@rfrlrnrqrsrrr r\r\s* 0 .      rr\c0eZdZdZesdZdZdZdZdZ dZ dZ d Z e eed  d d Ze eed  d d ZdZdZdZdZdZdZdZdZdZe eed ddZe eed ddZy)SSHSessionProcessProtocolTestsz1 Tests for L{SSHSessionProcessProtocol}. rct|_tjt |jdd|_tj |j|_|j j|jy)Nrr)rrr)rrrrrrrHrprVs r rz$SSHSessionProcessProtocolTests.setUpQs\&))/cSV  33DLLA t~~.rc||j|jjj|jy)z8 Assert that C{self.session} is closed. N)rrrrrVs r assertSessionClosedz2SSHSessionProcessProtocolTests.assertSessionClosedYs)  ))00>?rc~|j|jjj|j|y)zO Assert that C{self.session} has sent the C{expectedRequests}. N)rrrr)r'expectedRequestss r assertRequestsEqualz2SSHSessionProcessProtocolTests.assertRequestsEqual_s. **33DLLACSTrcd|j|jj|jy)zy SSHSessionProcessProtocol should set self.session to the session passed to the __init__ method. N)rrHrrVs r rz(SSHSessionProcessProtocolTests.test_inites $,,7rc|j|jjjj |j j y)zu SSHSessionProcessProtocol.getHost() just delegates to its session.conn.transport.getHost(). N)rrrrrrHrVs r test_getHostz+SSHSessionProcessProtocolTests.test_getHostl8 **44<<>@QRrc|j|jjjj |j j y)zu SSHSessionProcessProtocol.getPeer() just delegates to its session.conn.transport.getPeer(). N)rrrrrrHrVs r test_getPeerz+SSHSessionProcessProtocolTests.test_getPeersrrcd|j_|jj|j |j jdy)z SSHSessionProcessProtocol.connectionMade() should check if there's a 'buf' attribute on its session and write it to the transport if so. sbufferN)rrrHrrrrVs r test_connectionMadez2SSHSessionProcessProtocolTests.test_connectionMadezs: %    ++Y7rSIGALRMzNot all signals availablec tjD]K}d|z}tt|}|jj |}|j ||d|||fzMy)zi _getSignalName should return the name of a signal when given the signal number. SIGz %i: %s != %sN)rSUPPORTED_SIGNALSgetattrsignalrH_getSignalNamer)r' signalName signalValuesshNames r test_getSignalNamez1SSHSessionProcessProtocolTests.test_getSignalNamesd "33 J+J!&*5Kgg,,[9G   ^{GZ6X%X   rctjdzt_d|j_|j |jj tjdtjzy)z If there are signals in the signal module which aren't in the SSH RFC, we map their name to [signal name]@[platform]. ryNzSIGTwistedTest@) rNSIGSIGTwistedTestrH_signalValuesToNamesrrsysplatformrVs r !test_getSignalNameWithLocalSignalz@SSHSessionProcessProtocolTests.test_getSignalNameWithLocalSignalsR !' a'+$  GG " "6#8#8 9  , rc|jjd|j|jjj |jdgy)zy When data is passed to the outReceived method, it should be sent to the session's write method. test dataN)rHrQrrrr)rVs r test_outReceivedz/SSHSessionProcessProtocolTests.test_outReceivedsA L) **// = ~Nrc|jjd|j|jjj |jdgy)z{ When data is passed to the write method, it should be sent to the session channel's write method. rN)rHrwrrrr)rVs r test_writez)SSHSessionProcessProtocolTests.test_writes?  l# **// = ~Nrc|jjddg|j|jjj |jdgy)z When a sequence is passed to the writeSequence method, it should be joined together and sent to the session channel's write method. stest rrN)rHrSrrrr)rVs r test_writeSequencez1SSHSessionProcessProtocolTests.test_writeSequencesF x12 **// = ~Nrc|jjd|j|jjj |jdgy)z When data is passed to the errReceived method, it should be sent to the session's writeExtended method. r)ryrN)rH errReceivedrrrrrVs r test_errReceivedz/SSHSessionProcessProtocolTests.test_errReceivedsC L) **224<<@CTBUVrcZ|jj|j|j|jjj v|jj |j|jjj |jy)zv When outConnectionLost and errConnectionLost are both called, we should send an EOF message. N)rHr{rrrrr|rrVs r test_outConnectionLostz5SSHSessionProcessProtocolTests.test_outConnectionLostp !!# ):):)?)??@ !!#  ))..t||<=rcZ|jj|j|j|jjj v|jj |j|jjj |jy)zh Make sure reverse ordering of events in test_outConnectionLost also sends EOF. N)rHr|rrrrr{rrVs r test_errConnectionLostz5SSHSessionProcessProtocolTests.test_errConnectionLostrrc|jj|j|jjj |jy)zp When loseConnection() is called, it should call loseConnection on the session channel. N)rHrurrrrrVs r test_loseConnectionz2SSHSessionProcessProtocolTests.test_loseConnections9    ))00>?rcr|jjtjt dy)zr When connectionLost() is called, it should call loseConnection() on the session channel. rN)rHrr rr rVs r test_connectionLostz2SSHSessionProcessProtocolTests.test_connectionLosts# w{1~>?rc|jjttd|j dt j dddfg|jy)z When processEnded is called, if there is an exit code in the reason it should be sent in an exit-status method. The connection should be closed. Nrz>IrF)rHr}rr r{rdrerxrVs r test_processEndedWithExitCodez6;;tQ3G"O!PQ   "r WCOREDUMPzcan't run this w/o os.WCOREDUMPc L|jjttdtj d|j dtjddztjdztjdzdfg|jy) z When processEnded is called, if there is an exit signal in the reason it should be sent in an exit-signal message. The connection should be closed. ry exit-signalTERMrFN rHr}rr rSIGTERMr{rrrxrVs r 'test_processEndedWithExitSignalCoreDumpzFSSHSessionProcessProtocolTests.test_processEndedWithExitSignalCoreDumps  %a@ A    #IIg&iin%iin%      "rc L|jjttdtj d|j dtjddztjdztjdzdfg|jy) z When processEnded is called, if there is an exit signal in the reason it should be sent in an exit-signal message. If no core was dumped, don't set the core-dump bit. ryrrrrtrFNrrVs r )test_processEndedWithExitSignalNoCoreDumpzHSSHSessionProcessProtocolTests.test_processEndedWithExitSignalNoCoreDumps W%6q&..!%LMN   #IIg&0699S>AFIIcNR     "rN)rrrr,rr@rrxr{rr~rrrhasattrrrrrrrrrrrrrosrrrrr ruruIs 0/@ U 8SS8  * *,GH I   * *,GH  I  OOOW>>@@# K( (*KL#M#. K( (*KL#M#rruceZdZdZesdZdZy)SSHSessionClientTestsza SSHSessionClient is an obsolete class used to connect standard IO to an SSHSession. rctj}t|_|j d|j |jj dy)zL When data is received, it should be sent to the transport. rN)rSSHSessionClientrrrrrrs r test_dataReceivedz'SSHSessionClientTests.test_dataReceived#sF))+(?L) ))--|rsa &330A.*0B+^, ==    ""$ W  ZZZz W # #$-0&>-0%-0`,Y,Y^'8$$'TH$H$V) ) Z & 5 5w8.w8t ?-18?-D*6H*6ZS 8S lN#XN#b=H=r