Ϫfv}vdZddlZddlZddlZddlmZddlmZmZddl m Z ddl m Z ddl mZddlmZdd lmZdd lmZdd lmZ dd lmZeZ dd lmZeZ ddlZeZ ddl m!Z"e"Z! ddl$m%Z%m&Z&m'Z'm(Z(Gdde!Z)Gdde)Z*GddZ+eddl,Z,e,jZdedn)GddeZ.ej^e.e)e'j`GddeZ1ee dGdde1Z2Gdd Z3ee dGd!d"eZ4ee d#Gd$d%eZ5ee dee d#Gd&d'eZ6ee d#Gd(d)eZ7y#e$rdZY1wxYw#e$rdZY6wxYw#e$rdZY=wxYw#e$re#Z!YBwxYw#e$rYAwxYw)*z. Tests for L{twisted.conch.ssh.filetransfer}. N)skipIf) assert_thatequal_to)defer)ConnectionLost)StringTransport)loopback) components)FilePath)TestCase)unix)SFTPServerForUnixConchUser) ConchUser)common connection filetransfersessionceZdZdZdZy) TestAvatarctj|tj|jd<t j |jd<y)Nsessionsftp)r__init__r SSHSession channelLookuprFileTransferServersubsystemLookupselfs F/usr/lib/python3/dist-packages/twisted/conch/test/test_filetransfer.pyrzTestAvatar.__init__>s<4 )0););:&(4(G(GW%c t|}|D]A}|d}t|dkDxr|dxsd}t|dkDxr|dxsi}||i|}CS#t$r |||fg}YYwxYw)Nr)iter TypeErrorlen)rfargskwifuncrs r _runAsUserzTestAvatar._runAsUserCs QA "AQ4Dq6A:&!A$,"DQ!$!*Bd!b!A  "  T2A s AA'&A'N)__name__ __module__ __qualname__rr/r$r!r rr=s H r!rceZdZdZdZy)FileTransferTestAvatarc<tj|||_yN)rrhomeDir)rr7s r rzFileTransferTestAvatar.__init__QsD! r!cttjj|jj Sr6)r osgetcwd preauthChildr7pathrs r getHomeDirz!FileTransferTestAvatar.getHomeDirUs( $11$,,2C2CDDr!N)r0r1r2rr=r$r!r r4r4Ps Er!r4ceZdZdZy)ConchSessionForTestAvatarc||_yr6avatar)rrBs r rz"ConchSessionForTestAvatar.__init__Zs  r!N)r0r1r2rr$r!r r?r?Ysr!r?ztwisted.conch.unix imported z0, but doesn't define SFTPServerForUnixConchUser'ceZdZdZdZy)FileTransferForTestAvatarc ddiS)N conchTestext datar$)rversionotherExts r gotVersionz$FileTransferForTestAvatar.gotVersionms  +. .r!c|dk(ryt)NtestExtendedRequestbar)NotImplementedError)rextNameextDatas r extendedRequestz)FileTransferForTestAvatar.extendedRequestps00% %r!N)r0r1r2rJrQr$r!r rDrDls  / &r!rDceZdZdZy) SFTPTestBasec6t|j|_|jjd|_|jjdj d|jjdj d5}|j dt dd 5}|j |jd dddddd|jjdjd |jjd j d5}|j d ddd|jjdj d5}|j d ddd|jjdj d5}|j d dddy#1swY xYw#1swYxYw#1swYxYw#1swYuxYw#1swYyxYw)Nextra testDirectoryT testfile1wb)modeaaaaaaaaaabbbbbbbbbbz /dev/urandomrbiitestRemoveFileatestRenameFilez.testHiddenFile) r mktemptestDirchildmakedirsopenwritereadchmod)rr)f2s r setUpzSFTPTestBase.setUp{s . ||))'2  ?+44T: \\   , 1 1t 1 < , GG) *nd+ ,r *+ , , ;'--e4 \\   0 1 6 6D 6 A Q GGDM  \\   0 1 6 6D 6 A Q GGDM  \\   1 2 7 7T 7 B a GGDM   , , , ,       sHG*2!GG*8G7=HHG' "G**G47HH HN)r0r1r2rhr$r!r rSrSzsr!rSz can't run on non-posix computersceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZej4dZej4dZy)OurServerOurClientTestscLtjtj_t j j_tjj}t j_ d_ d_ fd}|j_tjj}jj|jj||_|_j%y)NrAc"|_|_yr6)_serverVersion_extData) serverVersionrPrs r _z(OurServerOurClientTests.setUp.._s"/D #DMr!)rSrhr4r`rBrrserverr LoopbackRelayFileTransferClientclientrmrngotServerVersionmakeConnectionclientTransportserverTransport _emptyBuffers)rrwrprxs` r rhzOurServerOurClientTests.setUps4 ,T\\: "55T[[I "00="557 "  $() $"00= ""?3 ""?3.. r!c"|jjs|jjrc|jj|jj|jjrK|jjrbyyr6)rxbufferrw clearBufferrs r ryz%OurServerOurClientTests._emptyBufferssb""))T-A-A-H-H  , , .  , , .""))T-A-A-H-Hr!c|jj|jj|jj|jjyr6)rxloseConnectionrwr|rs r tearDownz OurServerOurClientTests.tearDownsJ ++- ++- ((* ((*r!cx|j|jd|j|jddiy)NrFrG) assertEqualrmrnrs r test_serverVersionz*OurServerOurClientTests.test_serverVersions1 ,,a0 {(CDr!c|jtjj|jj d|jj y)z: It implements the ISFTPServer interface. zISFTPServer not provided by N) assertTruer ISFTPServer providedByrqrtrs r test_interface_implementationz5OurServerOurClientTests.test_interface_implementationsC   $ $ / / 0B0B C*4;;+=+=*@ A r!c0jjdtjtjzi}j t jgfd}jt d|fd}|j||S)zW A file opened with C{openFile} is closed when the connection is lost. testfile1c8j||yr6append)fdclosedoldCloses r closezJOurServerOurClientTests.test_openedFileClosedWithConnection..closes MM"  RLr!rcjj|jddj}jj j j jjj jjjjij|y)N) rq openFileshandlerrxr~rwr|rassertIn)openFilerrrs r _fileOpenedzPOurServerOurClientTests.test_openedFileClosedWithConnection.._fileOpeneds&&xqr':;>>B  / / 1  / / 1  , , .  , , .   T[[22B 7 MM"f %r!) rtrrFXF_READ FXF_WRITEryr9rpatch addCallback)rdrrrrs` @@r #test_openedFileClosedWithConnectionz;OurServerOurClientTests.test_openedFileClosedWithConnections| KK ,//,2H2HH"  88  2w& & k"r!cjjd}jfd}|j||S)zh A directory opened with C{openDirectory} is close when the connection is lost. c"jjjjjjjjj j j iyr6)rxr~rwr|rrqopenDirs)openDirrs r _getFileszSOurServerOurClientTests.test_openedDirectoryClosedWithConnection.._getFilesse  / / 1  / / 1  , , .  , , .   T[[112 6r!rt openDirectoryryr)rrrs` r (test_openedDirectoryClosedWithConnectionz@OurServerOurClientTests.test_openedDirectoryClosedWithConnections= KK % %b )  7 i r!cjjdtjtjzi}j fd}fdfdfd|j ||S)Nrcj|tj||}|j||Sr6)rr ISFTPFiler)rr _readChunk _writeChunkrs r rz._fileOpeneds;   X|'='=h'G H8$A MM+x 0Hr!c|jdd}j|jjd|S)NrrZ readChunkryrr)rrrs r rz;OurServerOurClientTests.test_openFileIO.._readChunks;""1b)A    MM$**,A BHr!cp|jdd}j|j||S)Nrs cccccccccc) writeChunkryr)rprr _readChunk2rs r rz._writeChunks4##B 2A    MM+x 0Hr!c|jdd}j|jjd|S)Nrsaaaaaaaaaabbbbbbbbbbccccccccccrrprrrs r rz._readChunk2 s;""1b)A    MM$**,M NHr!rtrrrrryr)rrrrrrs` @@@r test_openFileIOz'OurServerOurClientTests.test_openFileIOsd KK ,//,2H2HH"          k"r!cjjdtjtjzi}j fdfdfd}|j ||S)NrcH|j}j|Sr6)getAttrsryrs r _getAttrszBOurServerOurClientTests.test_closedFileGetAttrs.._getAttrss"!!#A    Hr!c(j|Sr6)flushLoggedErrors)r)rs r _errz=OurServerOurClientTests.test_closedFileGetAttrs.._errs  " " $Hr!c|j}j|j||jj |t j Sr6)rryr addErrback assertFailurer SFTPError)rrrrrs r _closez?OurServerOurClientTests.test_closedFileGetAttrs.._close"sN A    MM)X . LL %%a)?)?@ @r!r)rrrrrs` @@r test_closedFileGetAttrsz/OurServerOurClientTests.test_closedFileGetAttrss` KK ,//,2H2HH"      A fr!cjjdtjtjzi}j fd}fd|j |S)Nrcj|j}j|j|Sr6rryr)rr _getAttrs2rs r rzBOurServerOurClientTests.test_openFileAttributes.._getAttrs2s.!!#A    MM* %Hr!cjjd}j|jj||SNrrtrryrr)attrs1rrs r rzCOurServerOurClientTests.test_openFileAttributes.._getAttrs28s< $$\2A    MM$**F 3Hr!r)rrrrs` @r test_openFileAttributesz/OurServerOurClientTests.test_openFileAttributes,sX KK ,//,2H2HH"      }}Y''r!cjjdtjtjzi}j fd}fdfd|j ||S)Nrcj|j}j|j|Sr6r)rr _setAttrsrs r rz@OurServerOurClientTests.test_openFileSetAttrs.._getAttrsHs.!!#A    MM) $Hr!cd|d<jjd|}j|j|jj||S)Nratimer)rtsetAttrsryrr)attrsrrrs r rz@OurServerOurClientTests.test_openFileSetAttrs.._setAttrsNsSE'N $$\59A    MM* % MM$**E 2Hr!c^jjd}j|Srrtrryrprrs r rzAOurServerOurClientTests.test_openFileSetAttrs.._getAttrs2Vs( $$\2A    Hr!r)rrrrrs` @@r test_openFileSetAttrsz-OurServerOurClientTests.test_openFileSetAttrs@sa KK ,//,2H2HH"       i r!cXijjjfd}|jj_jjdtjtj zddi}j fd}|j|S)z Check that L{filetransfer.FileTransferClient.openFile} can send extended attributes, that should be extracted server side. By default, they are ignored, so we just verify they are correctly parsed. c:j||||Sr6)update)filenameflagsr oldOpenFilesavedAttributess r rzIOurServerOurClientTests.test_openFileExtendedAttributes..openFilegs  " "5 )x6 6r!rext_foorMc.jddiy)NrrMr)ignrrs r checkzFOurServerOurClientTests.test_openFileExtendedAttributes..checkts   _y&.A Br!)rqrtrrrrryr)rrrrrrs` @@r test_openFileExtendedAttributesz7OurServerOurClientTests.test_openFileExtendedAttributes^s kk((11  7'/ # KK   ! !L$:$: :     C}}U##r!cjjd}jfd}|j||j|j |t j S)NtestRemoveFilec^jjd}j|S)Nr)rt removeFilery)ignoredrrs r _removeFilez._removeFile}s) &&'89A    Hr!)rtrryrrrr)rrrs` r test_removeFilez'OurServerOurClientTests.test_removeFileys\ KK !2 3   k" k"!!!\%;%;<._renames: &&'8:LMA    MM, .Hr!cjjd}j|jj|y)Nrr)rprrrs r rz=OurServerOurClientTests.test_renameFile.._testRenameds8 $$%78A    MM$**E 2r!)rtrryr)rrrrs` @r test_renameFilez'OurServerOurClientTests.test_renameFiles? KK !2 3    3 }}W%%r!c|jjd}|j|j|tj SNtestMakeDirectoryrtrryrrrrrs r test_directoryBadz)OurServerOurClientTests.test_directoryBads< KK !5 6 !!!\%;%;<._getAttrss) $$%9:A    Hr!c^jjd}j|Sr)rtremoveDirectoryryrs r _removeDirectoryzHOurServerOurClientTests.test_directoryCreation.._removeDirectorys) ++,@AA    Hr!)rt makeDirectoryryrrrr)rrrrs` r test_directoryCreationz.OurServerOurClientTests.test_directoryCreationsp KK % %&:B ?    i  &' i !!!\%;%;<._getFiles..appends Qr!)r maybeDeferrednextryrr)rrrrrrrs` r rz=OurServerOurClientTests.test_openDirectory.._getFilessU ##GLL1A    MM& ! MM) $ LL )Hr!ctttd}|jj|gdy)Nr)s.testHiddenFiles testDirectoryrrr)listzipsortr)rfsrrs r _checkFilesz?OurServerOurClientTests.test_openDirectory.._checkFiless:d3;'*+B GGI    r!cH|j}j|Sr6)rry)rprrrs r rz:OurServerOurClientTests.test_openDirectory.._closes A    Hr!r)rrrrrrs` @@@r test_openDirectoryz*OurServerOurClientTests.test_openDirectorysV KK % %c *     i  k"r!c|jjd}|j|j|tj S)NtestLinkrrs r test_linkDoesntExistz,OurServerOurClientTests.test_linkDoesntExists; KK  - !!!\%;%;<._getFirstAttrss* $$[!4A    Hr!cjjd}j|jj||Srr) firstAttrsrrs r _getSecondAttrszEOurServerOurClientTests.test_linkSharesAttrs.._getSecondAttrss< $$\2A    MM$**J 7Hr!rtmakeLinkryr)rrrrs` r test_linkSharesAttrsz,OurServerOurClientTests.test_linkSharesAttrssL KK l ;     n%}}_--r!cjjdd}jfd}fd}|j||j||S)NrrcLjjd}jtt j j jj}|jd}|jj|j|SNrrW) rtreadLinkryr r9r:r;r`r<rarr)rprtestFilers r _readLinkz8OurServerOurClientTests.test_linkPath.._readLinks $$[1A     ,99$,,:K:KLH~~k2H MM$**HMM :Hr!cLjjd}jtt j j jj}|jd}|jj|j|Sr ) rtrealPathryr r9r:r;r`r<rarr)rprtestLinkrs r _realPathz8OurServerOurClientTests.test_linkPath.._realPathr$r!r)rrr#r(s` r test_linkPathz%OurServerOurClientTests.test_linkPathsN KK l ;    i  i r!c|jjdd}|j|j|jd|j|j |S)NrLsfoorM)rtrQryrr_cbTestExtendedRequestrs r test_extendedRequestz,OurServerOurClientTests.test_extendedRequest sP KK ' '(> G  d&&/ d112r!c|jjdd}|j|j|tS)NstestBadRequestr!)rtrQryrrN)rrrs r r+z.OurServerOurClientTests._cbTestExtendedRequests9 KK ' '(93 ? !!!%899r!c#tK|jjd}|j|}|j}|j||j }d}|j dt ||j t|dd|j ||ddyw)zJ Using client.openDirectory as an iterator is deprecated. r!zeUsing twisted.conch.ssh.filetransfer.ClientDirectory as an iterator was deprecated in Twisted 18.9.0.r#rcategorymessageN)rtrryr  flushWarningsrr(DeprecationWarning)rrroneFilewarningsr0s r $test_openDirectoryIteratorDeprecatedz._slowRead9s2   ^R 0 A  ! !& )Hr!dr#N)rtrrrryrqrvaluesrrr(assertNoResultrxr~r|rw assertFalse connectedfailureResultOfrr)rrfhr< serverSideFhr;s` @r $test_closedConnectionCancelsRequestsz.DummyTransportc||_yr6) transportrs r rzMFileTransferCloseTests.buildServerConnection..DummyTransport.__init__is !%r!cyr6r$)rkinddatas r sendPacketzOFileTransferCloseTests.buildServerConnection..DummyTransport.sendPacketlsr!cy)Nzdummy transportr$rs r logPrefixzNFileTransferCloseTests.buildServerConnection..DummyTransport.logPrefixos(r!N)r0r1r2rrXrZr$r!r DummyTransportrRhs &  )r!r[)r SSHConnectionrTrB)rconnr[s r buildServerConnectionz,FileTransferCloseTests.buildServerConnectioncs;'') ) )() $  r!cHd_|jfd}||_y)NFc$d_|y)NT)connectionLostFired)reasonorigConnectionLostrs r connectionLostzFFileTransferCloseTests.interceptConnectionLost..connectionLostzs'+D $ v &r!)rard)r sftpServerrdrcs` @r interceptConnectionLostz.FileTransferCloseTests.interceptConnectionLostvs&#( '66 '%3 !r!c<|j|jdy)Nz*sftpServer's connectionLost was not called)rrars r assertSFTPConnectionLostz/FileTransferCloseTests.assertSFTPConnectionLosts   $ $&R r!c@tjt|j}|j t j d|jjj}|j||j|jy)ze Closing a session should notify an SFTP subsystem launched by that session. )r]rBrN) rrrIrBrequest_subsystemrNSrtrTprotorf closeReceivedrh)r testSessionres r test_sessionClosez(FileTransferCloseTests.test_sessionClosesv ((hjM  %%fii&89 ''1177  $$Z0 !!# %%'r!c|j}tjdtjdddzz}|j ||j d}|jtjd|jjj}|j||j||jtjdd|jy)zy A client sending CHANNEL_CLOSE should trigger closeReceived on the associated channel instance. r>LrrrN)r^rrkstructpackssh_CHANNEL_OPENchannelsrjrtrTrlrfssh_CHANNEL_CLOSErhrr]packetsessionChannelres r %test_clientClosesChannelOnConnnectionzFileTransferCloseTests.test_stopConnectionServiceClosesChannels))+:&T1)=)AA f%q)((7);<#**44::  $$Z0  %%'r!N) r0r1r2rhr^rfrhrorzr}r$r!r rNrN^s%#&3 (((0(r!rNzCannot run without cryptographyceZdZdZgdZdZy)ConstantsTestsag Tests for the constants used by the SFTP protocol implementation. @ivar filexferSpecExcerpts: Excerpts from the draft-ietf-secsh-filexfer-02.txt (draft) specification of the SFTP protocol. There are more recent drafts of the specification, but this one describes version 3, which is what conch (and OpenSSH) implements. )a The following values are defined for packet types. #define SSH_FXP_INIT 1 #define SSH_FXP_VERSION 2 #define SSH_FXP_OPEN 3 #define SSH_FXP_CLOSE 4 #define SSH_FXP_READ 5 #define SSH_FXP_WRITE 6 #define SSH_FXP_LSTAT 7 #define SSH_FXP_FSTAT 8 #define SSH_FXP_SETSTAT 9 #define SSH_FXP_FSETSTAT 10 #define SSH_FXP_OPENDIR 11 #define SSH_FXP_READDIR 12 #define SSH_FXP_REMOVE 13 #define SSH_FXP_MKDIR 14 #define SSH_FXP_RMDIR 15 #define SSH_FXP_REALPATH 16 #define SSH_FXP_STAT 17 #define SSH_FXP_RENAME 18 #define SSH_FXP_READLINK 19 #define SSH_FXP_SYMLINK 20 #define SSH_FXP_STATUS 101 #define SSH_FXP_HANDLE 102 #define SSH_FXP_DATA 103 #define SSH_FXP_NAME 104 #define SSH_FXP_ATTRS 105 #define SSH_FXP_EXTENDED 200 #define SSH_FXP_EXTENDED_REPLY 201 Additional packet types should only be defined if the protocol version number (see Section ``Protocol Initialization'') is incremented, and their use MUST be negotiated using the version number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY packets can be used to implement vendor-specific extensions. See Section ``Vendor-Specific-Extensions'' for more details. a The flags bits are defined to have the following values: #define SSH_FILEXFER_ATTR_SIZE 0x00000001 #define SSH_FILEXFER_ATTR_UIDGID 0x00000002 #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004 #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008 #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000 a The `pflags' field is a bitmask. The following bits have been defined. #define SSH_FXF_READ 0x00000001 #define SSH_FXF_WRITE 0x00000002 #define SSH_FXF_APPEND 0x00000004 #define SSH_FXF_CREAT 0x00000008 #define SSH_FXF_TRUNC 0x00000010 #define SSH_FXF_EXCL 0x00000020 a Currently, the following values are defined (other values may be defined by future versions of this protocol): #define SSH_FX_OK 0 #define SSH_FX_EOF 1 #define SSH_FX_NO_SUCH_FILE 2 #define SSH_FX_PERMISSION_DENIED 3 #define SSH_FX_FAILURE 4 #define SSH_FX_BAD_MESSAGE 5 #define SSH_FX_NO_CONNECTION 6 #define SSH_FX_CONNECTION_LOST 7 #define SSH_FX_OP_UNSUPPORTED 8 ci}|jD]]}|jD]H}tjd|}|st |j dd||j d<J_|j t|dkDd|jD]%\}}|j|tt|'y)z The constants used by the SFTP protocol implementation match those found by searching through the spec. z)^\s*#define SSH_([A-Z_]+)\s+([0-9x]*)\s*$r%rr#z,No constants found (the test must be buggy).N) filexferSpecExcerpts splitlinesrematchintgrouprr(itemsrgetattrr)r constantsexcerptlinemkvs r test_constantsAgainstSpecz(ConstantsTests.test_constantsAgainstSpecs  00 ?G**, ?HHI4P,/ A,>Iaggaj) ? ?   NQ  N OO% :DAq   Q a 8 9 :r!N)r0r1r2__doc__rrr$r!r rrsJX:r!rceZdZdZdZdZy)RawPacketDataServerTestsz Tests for L{filetransfer.FileTransferServer} which explicitly craft certain less common situations to exercise their handling. cJtjt|_y)NrA)rrrftsrs r rhzRawPacketDataServerTests.setUp9s22*,Gr!ct}|jj|d}d}tjt dg|ztj|z}|jj |tjt dg|zt gdztjdztjdz}t|jt|y) zl A close request with an unknown handle receives an FX_NO_SUCH_FILE error response. s1234sinvalid handlere)rrrr%sNo such file or directoryr!N) rrrvrrkbytes dataReceivedrvaluer)rrT requestIdrrexpecteds r test_closeInvalidHandlez0RawPacketDataServerTests.test_closeInvalidHandle<s $%   * "  1#J ii   e$99 3%L   ,    II2 3 4 IIcN  &  OO  X  r!N)r0r1r2rrhrr$r!r rr1s H1 r!rc:eZdZdZdZdZdZdZdZdZ dZ y ) RawPacketDataTestsz Tests for L{filetransfer.FileTransferClient} which explicitly craft certain less common protocol messages to exercise their handling. c6tj|_yr6)rrsftcrs r rhzRawPacketDataTests.setUpws224r!cntj}|j|j||jj d<t jddtjtjdztjdz}|jj||S)a/ A STATUS packet containing a result code, a message, and a language is parsed to produce the result of an outstanding request L{Deferred}. @see: U{section 9.1} of the SFTP Internet-Draft. r#!LLmsglang) rr8r_cbTestPacketSTATUSr openRequestsrrrsrFX_OKrrk packet_STATUSrrrWs r test_packetSTATUSz$RawPacketDataTests.test_packetSTATUSzs NN  d../#$a KKq,"4"4 5ii ii  ! t$r!cX|j|dd|j|ddy)z{ Assert that the result is a two-tuple containing the message and language from the STATUS packet. rrr#rNrrresults r rz&RawPacketDataTests._cbTestPacketSTATUSs, F+ G,r!ctj}|j|j||jj d<t jddtj}|jj||S)az A STATUS packet containing only a result code can also be parsed to produce the result of an outstanding request L{Deferred}. Such packets are sent by some SFTP implementations, though not strictly legal. @see: U{section 9.1} of the SFTP Internet-Draft. r#r) rr8r_cbTestPacketSTATUSShortrrrrrsrrrrs r test_packetSTATUSShortz)RawPacketDataTests.test_packetSTATUSShortse NN  d334#$a {{5!\%7%78 t$r!cX|j|dd|j|ddy)z Assert that the result is a two-tuple containing empty strings, since the STATUS packet had neither a message nor a language. rr!r#Nrrs r rz+RawPacketDataTests._cbTestPacketSTATUSShorts, C( C(r!cBtj}|j|j||jj d<t jddtjtjdz}|jj||S)a A STATUS packet containing a result code and a message but no language can also be parsed to produce the result of an outstanding request L{Deferred}. Such packets are sent by some SFTP implementations, though not strictly legal. @see: U{section 9.1} of the SFTP Internet-Draft. r#rr) rr8r_cbTestPacketSTATUSWithoutLangrrrrrsrrrrkrrs r test_packetSTATUSWithoutLangz/RawPacketDataTests.test_packetSTATUSWithoutLangss NN  d99:#$a {{5!\%7%78699V;LL t$r!cX|j|dd|j|ddy)z Assert that the result is a two-tuple containing the message from the STATUS packet and an empty string, since the language was missing. rrr#r!Nrrs r rz1RawPacketDataTests._cbTestPacketSTATUSWithoutLangs, F+ C(r!N) r0r1r2rrhrrrrrrr$r!r rrps* 5&- )")r!r)8rr9rrrunittestrhamcrestrrtwisted.internetrtwisted.internet.errorrtwisted.internet.testingrtwisted.protocolsr twisted.pythonr twisted.python.filepathr twisted.trial.unittestr twisted.conchr _unix ImportErrortwisted.conch.unixr_SFTPServerForUnixConchUser cryptography _cryptographytwisted.conch.avatarr _ConchUserobjecttwisted.conch.sshrrrrrr4r?r4warnrDregisterAdapterrrSrjrIrNrrrr$r!r rsM   *"14&%,++ D= "=!(!L<I KK &EZE %HMM   &$>&J!:|/G/G 8*D45F0lF06F0R  D45d(Xd(6d(NL;<e:Xe:=e:TD45L;<: x: =6: zL;<S)S)=S)m D&!%&LI  sZE7FF!F!* F/7FFFFFF!F,+F,/F87F8