o
    ¯bm  ã                   @   s’  d Z ddlZddlZddlZddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ zddlmZ W n ey_   dZY nw eZzddlmZ W n eyu   dZY nw eZzddl Z!W n ey‰   dZ Y nw e!Z zddl"m#Z$ W n eyŸ   e%Z#Y nw e$Z#zddl&m'Z'm(Z(m)Z)m*Z* W n	 ey¹   Y nw G dd„ de#ƒZ+G dd„ de+ƒZ,G dd„ dƒZ-edu râddl.Z.e. /def ¡ nG dd„ deƒZ0e 1e0e+e)j2¡ G dd„ deƒZ3ee dƒG dd„ de3ƒƒZ4G dd „ d ƒZ5ee dƒG d!d"„ d"eƒƒZ6ee  d#ƒG d$d%„ d%eƒƒZ7ee  d#ƒG d&d'„ d'eƒƒZ8ee  d#ƒG d(d)„ d)eƒƒZ9dS )*z.
Tests for L{twisted.conch.ssh.filetransfer}.
é    N)ÚskipIf)Úassert_thatÚequal_to)Údefer)ÚConnectionLost)Úloopback)Ú
components)Ú	_PY37PLUS)ÚFilePath)ÚStringTransport)ÚTestCase)Úunix)ÚSFTPServerForUnixConchUser)Ú	ConchUser)ÚcommonÚ
connectionÚfiletransferÚsessionc                   @   ó   e Zd Zdd„ Zdd„ ZdS )Ú
TestAvatarc                 C   s&   t  | ¡ tj| jd< tj| jd< d S )Nó   sessionó   sftp)r   Ú__init__r   Ú
SSHSessionÚchannelLookupr   ÚFileTransferServerÚsubsystemLookup©Úself© r   úF/usr/lib/python3/dist-packages/twisted/conch/test/test_filetransfer.pyr   ?   s   
zTestAvatar.__init__c                 O   s€   zt |ƒ}W n ty   |||fg}Y nw |D ]%}|d }t|ƒdkr(|d p)d}t|ƒdkr4|d p5i }||i |¤Ž}q|S )Nr   é   r   é   )ÚiterÚ	TypeErrorÚlen)r   ÚfÚargsÚkwÚiÚfuncÚrr   r   r    Ú
_runAsUserD   s   ÿzTestAvatar._runAsUserN)Ú__name__Ú
__module__Ú__qualname__r   r,   r   r   r   r    r   >   s    r   c                   @   r   )ÚFileTransferTestAvatarc                 C   s   t  | ¡ || _d S ©N)r   r   ÚhomeDir)r   r2   r   r   r    r   R   s   

zFileTransferTestAvatar.__init__c                 C   s   t t ¡ ƒ | jj¡S r1   )r
   ÚosÚgetcwdÚpreauthChildr2   Úpathr   r   r   r    Ú
getHomeDirV   s   z!FileTransferTestAvatar.getHomeDirN)r-   r.   r/   r   r7   r   r   r   r    r0   Q   s    r0   c                   @   ó   e Zd Zdd„ ZdS )ÚConchSessionForTestAvatarc                 C   s
   || _ d S r1   ©Úavatar)r   r;   r   r   r    r   [   ó   
z"ConchSessionForTestAvatar.__init__N)r-   r.   r/   r   r   r   r   r    r9   Z   ó    r9   zNtwisted.conch.unix imported %r, but doesn't define SFTPServerForUnixConchUser'c                   @   r   )ÚFileTransferForTestAvatarc                 C   s   ddiS )Nó	   conchTestó   ext datar   )r   ÚversionÚotherExtr   r   r    Ú
gotVersionn   s   z$FileTransferForTestAvatar.gotVersionc                 C   s   |dkrdS t ‚)Nó   testExtendedRequestó   bar)ÚNotImplementedError)r   ÚextNameÚextDatar   r   r    ÚextendedRequestq   s   z)FileTransferForTestAvatar.extendedRequestN)r-   r.   r/   rC   rI   r   r   r   r    r>   m   s    r>   c                   @   r8   )ÚSFTPTestBasec              	   C   sx  t |  ¡ ƒ| _| j d¡| _| j d¡ d¡ | j d¡jdd*}| d¡ tdd	ƒ}| | d
¡¡ W d   ƒ n1 s?w   Y  W d   ƒ n1 sNw   Y  | j d¡ d¡ | j d¡jdd}| d¡ W d   ƒ n1 svw   Y  | j d¡jdd}| d¡ W d   ƒ n1 s•w   Y  | j d¡jdd}| d¡ W d   ƒ d S 1 sµw   Y  d S )NÚextraÚtestDirectoryTÚ	testfile1Úwb)Úmodeó   aaaaaaaaaabbbbbbbbbbz/dev/urandomÚrbi   i¤  ÚtestRemoveFileó   aÚtestRenameFilez.testHiddenFile)	r
   ÚmktempÚtestDirÚchildÚmakedirsÚopenÚwriteÚreadÚchmod)r   r&   Úf2r   r   r    ÚsetUp|   s(   
ÿ€þÿÿ"ÿzSFTPTestBase.setUpN)r-   r.   r/   r^   r   r   r   r    rJ   {   r=   rJ   z can't run on non-posix computersc                   @   sð   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zejeed-ƒd.d/„ ƒƒZejd0d1„ ƒZejd2d3„ ƒZd4S )5ÚOurServerOurClientTestsc                    s˜   t  ˆ ¡ tˆ jƒˆ _tjˆ jdˆ _t 	ˆ j¡}t 
¡ ˆ _d ˆ _d ˆ _‡ fdd„}|ˆ j_t 	ˆ j¡}ˆ j |¡ ˆ j |¡ |ˆ _|ˆ _ˆ  ¡  d S )Nr:   c                    s   | ˆ _ |ˆ _d S r1   )Ú_serverVersionÚ_extData)ÚserverVersionrH   r   r   r    Ú_   s   
z(OurServerOurClientTests.setUp.<locals>._)rJ   r^   r0   rV   r;   r   r   Úserverr   ÚLoopbackRelayÚFileTransferClientÚclientr`   ra   ÚgotServerVersionÚmakeConnectionÚclientTransportÚserverTransportÚ_emptyBuffers)r   rj   rc   rk   r   r   r    r^   ’   s   

zOurServerOurClientTests.setUpc                 C   s<   | j js| jjr| j  ¡  | j ¡  | j js| jjsd S d S r1   )rk   Úbufferrj   ÚclearBufferr   r   r   r    rl   «   s   

þz%OurServerOurClientTests._emptyBuffersc                 C   s,   | j  ¡  | j ¡  | j  ¡  | j ¡  d S r1   )rk   ÚloseConnectionrj   rn   r   r   r   r    ÚtearDown°   s   


z OurServerOurClientTests.tearDownc                 C   s$   |   | jd¡ |   | jddi¡ d S )Né   r?   r@   )ÚassertEqualr`   ra   r   r   r   r    Útest_serverVersion¶   s   z*OurServerOurClientTests.test_serverVersionc                 C   s&   |   tj | jj¡d| jj›¡ dS )z:
        It implements the ISFTPServer interface.
        zISFTPServer not provided by N)Ú
assertTruer   ÚISFTPServerÚ
providedByrd   rg   r   r   r   r    Útest_interface_implementationº   s   þz5OurServerOurClientTests.test_interface_implementationc                    sb   ˆj  dtjtjB i ¡}ˆ ¡  tj‰g ‰ ‡ ‡fdd„}ˆ td|¡ ‡ ‡fdd„}| 	|¡ |S )zW
        A file opened with C{openFile} is closed when the connection is lost.
        ó	   testfile1c                    s   ˆ   | ¡ ˆ| ƒ d S r1   ©Úappend)Úfd)ÚclosedÚoldCloser   r    ÚcloseÏ   ó   
zJOurServerOurClientTests.test_openedFileClosedWithConnection.<locals>.closer~   c                    s`   ˆj j| jdd …  j}ˆj ¡  ˆj ¡  ˆj ¡  ˆj ¡  ˆ ˆj ji ¡ ˆ 	|ˆ ¡ d S )Né   )
rd   Ú	openFilesÚhandler{   rk   ro   rj   rn   rr   ÚassertIn)ÚopenFiler{   )r|   r   r   r    Ú_fileOpenedÕ   s   



zPOurServerOurClientTests.test_openedFileClosedWithConnection.<locals>._fileOpened)
rg   r„   r   ÚFXF_READÚ	FXF_WRITErl   r3   r~   ÚpatchÚaddCallback)r   Údr~   r…   r   )r|   r}   r   r    Ú#test_openedFileClosedWithConnectionÃ   s   ÿ
	z;OurServerOurClientTests.test_openedFileClosedWithConnectionc                    s.   ˆ j  d¡}ˆ  ¡  ‡ fdd„}| |¡ |S )zh
        A directory opened with C{openDirectory} is close when the connection
        is lost.
        Ú c                    s<   ˆ j  ¡  ˆ j ¡  ˆ j  ¡  ˆ j ¡  ˆ  ˆ jji ¡ d S r1   )rk   ro   rj   rn   rr   rd   ÚopenDirs©ÚopenDirr   r   r    Ú	_getFilesé   s
   



zSOurServerOurClientTests.test_openedDirectoryClosedWithConnection.<locals>._getFiles©rg   ÚopenDirectoryrl   r‰   )r   rŠ   r   r   r   r    Ú(test_openedDirectoryClosedWithConnectioná   s
   
z@OurServerOurClientTests.test_openedDirectoryClosedWithConnectionc                    sd   ˆj  dtjtjB i ¡}ˆ ¡  ‡ ‡‡fdd„}‡fdd„‰ ‡‡fdd„‰‡fdd	„‰| |¡ |S )
Nrx   c                    s*   ˆ  | t | ¡¡ ˆ | ƒ}| ˆ| ¡ |S r1   )rr   r   Ú	ISFTPFiler‰   ©r„   rŠ   )Ú
_readChunkÚ_writeChunkr   r   r    r…   ù   s   z<OurServerOurClientTests.test_openFileIO.<locals>._fileOpenedc                    s&   |   dd¡}ˆ  ¡  | ˆ jd¡ |S )Nr   é   rP   ©Ú	readChunkrl   r‰   rr   r•   r   r   r    r–   ÿ   ó   z;OurServerOurClientTests.test_openFileIO.<locals>._readChunkc                    s$   |  dd¡}ˆ ¡  | ˆ |¡ |S )Nr˜   s
   cccccccccc)Ú
writeChunkrl   r‰   ©rc   r„   rŠ   )Ú_readChunk2r   r   r    r—     s   z<OurServerOurClientTests.test_openFileIO.<locals>._writeChunkc                    s&   |  dd¡}ˆ  ¡  | ˆ jd¡ |S )Nr   é   s   aaaaaaaaaabbbbbbbbbbccccccccccr™   r   r   r   r    rž     r›   z<OurServerOurClientTests.test_openFileIO.<locals>._readChunk2©rg   r„   r   r†   r‡   rl   r‰   )r   rŠ   r…   r   )r–   rž   r—   r   r    Útest_openFileIOó   s   ÿ
z'OurServerOurClientTests.test_openFileIOc                    sV   ˆj  dtjtjB i ¡}ˆ ¡  ‡fdd„‰‡fdd„‰ ‡ ‡‡fdd„}| |¡ |S )Nrx   c                    ó   |  ¡ }ˆ  ¡  |S r1   )ÚgetAttrsrl   r   r   r   r    Ú	_getAttrs  ó   zBOurServerOurClientTests.test_closedFileGetAttrs.<locals>._getAttrsc                    s   ˆ   ¡  | S r1   )ÚflushLoggedErrors©r&   r   r   r    Ú_err  s   z=OurServerOurClientTests.test_closedFileGetAttrs.<locals>._errc                    s4   |   ¡ }ˆ ¡  | ˆ| ¡ | ˆ ¡ ˆ |tj¡S r1   )r~   rl   r‰   Ú
addErrbackÚassertFailurer   Ú	SFTPErrorr•   ©r¨   r¤   r   r   r    Ú_close#  s
   
z?OurServerOurClientTests.test_closedFileGetAttrs.<locals>._closer    )r   rŠ   r­   r   r¬   r    Útest_closedFileGetAttrs  s   ÿ
z/OurServerOurClientTests.test_closedFileGetAttrsc                    sD   ˆj  dtjtjB i ¡}ˆ ¡  ‡ ‡fdd„}‡fdd„‰ | |¡S )Nrx   c                    ó   |   ¡ }ˆ ¡  | ˆ ¡ |S r1   ©r£   rl   r‰   r•   ©Ú
_getAttrs2r   r   r    r¤   3  ó   
zBOurServerOurClientTests.test_openFileAttributes.<locals>._getAttrsc                    ó&   ˆ j  d¡}ˆ  ¡  | ˆ j| ¡ |S ©Nrx   ©rg   r£   rl   r‰   rr   )Úattrs1rŠ   r   r   r    r²   9  r›   zCOurServerOurClientTests.test_openFileAttributes.<locals>._getAttrs2r    ©r   rŠ   r¤   r   r±   r    Útest_openFileAttributes-  s   ÿ
z/OurServerOurClientTests.test_openFileAttributesc                    sV   ˆj  dtjtjB i ¡}ˆ ¡  ‡‡fdd„}‡ ‡fdd„‰‡fdd„‰ | |¡ |S )Nrx   c                    r¯   r1   r°   r•   )Ú	_setAttrsr   r   r    r¤   I  r³   z@OurServerOurClientTests.test_openFileSetAttrs.<locals>._getAttrsc                    s:   d| d< ˆj  d| ¡}ˆ ¡  | ˆ ¡ | ˆj| ¡ |S )Nr   Úatimerx   )rg   ÚsetAttrsrl   r‰   rr   ©ÚattrsrŠ   r±   r   r    rº   O  s   
z@OurServerOurClientTests.test_openFileSetAttrs.<locals>._setAttrsc                    ó   ˆ j  d¡}ˆ  ¡  |S rµ   ©rg   r£   rl   ©rc   rŠ   r   r   r    r²   W  ó   zAOurServerOurClientTests.test_openFileSetAttrs.<locals>._getAttrs2r    r¸   r   )r²   rº   r   r    Útest_openFileSetAttrsA  s   ÿ
z-OurServerOurClientTests.test_openFileSetAttrsc                    sb   i ‰ˆj jj‰ ‡ ‡fdd„}|ˆj j_ˆj dtjtjB ddi¡}ˆ ¡  ‡‡fdd„}| |¡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                    s   ˆ  |¡ ˆ | ||ƒS r1   )Úupdate)ÚfilenameÚflagsr¾   )ÚoldOpenFileÚsavedAttributesr   r    r„   h  r   zIOurServerOurClientTests.test_openFileExtendedAttributes.<locals>.openFilerx   Úext_foorE   c                    s   ˆ  ˆ ddi¡ d S )NrÉ   rE   ©rr   )Úign)rÈ   r   r   r    Úchecku  ó   zFOurServerOurClientTests.test_openFileExtendedAttributes.<locals>.check)rd   rg   r„   r   r†   r‡   rl   r‰   )r   r„   rŠ   rÌ   r   )rÇ   rÈ   r   r    Útest_openFileExtendedAttributes_  s   


ý
z7OurServerOurClientTests.test_openFileExtendedAttributesc                    sB   ˆ j  d¡}ˆ  ¡  ‡ fdd„}| |¡ | |¡ ˆ  |tj¡S )Nó   testRemoveFilec                    r¿   )NrÏ   )rg   Ú
removeFilerl   )ÚignoredrŠ   r   r   r    Ú_removeFile~  rÂ   z<OurServerOurClientTests.test_removeFile.<locals>._removeFile)rg   r£   rl   r‰   rª   r   r«   )r   rŠ   rÒ   r   r   r    Útest_removeFilez  s   

z'OurServerOurClientTests.test_removeFilec                    s8   ˆj  d¡}ˆ ¡  ‡ ‡fdd„}‡fdd„‰ | |¡S )Nó   testRenameFilec                    s&   ˆj  dd¡}ˆ ¡  | ˆ | ¡ |S )NrÔ   ó   testRenamedFile)rg   Ú
renameFilerl   r‰   r½   ©Ú_testRenamedr   r   r    Ú_rename‹  s   z8OurServerOurClientTests.test_renameFile.<locals>._renamec                    s&   ˆ j  d¡}ˆ  ¡  | ˆ j|¡ d S )NrÕ   r¶   )rc   r¾   rŠ   r   r   r    rØ   ‘  s   z=OurServerOurClientTests.test_renameFile.<locals>._testRenamed)rg   r£   rl   r‰   )r   rŠ   rÙ   r   r×   r    Útest_renameFile‡  s
   
z'OurServerOurClientTests.test_renameFilec                 C   ó"   | j  d¡}|  ¡  |  |tj¡S ©Nó   testMakeDirectory©rg   r£   rl   rª   r   r«   ©r   rŠ   r   r   r    Útest_directoryBad˜  ó   z)OurServerOurClientTests.test_directoryBadc                    sZ   ˆ j  di ¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡ | |¡ ˆ  |tj¡S )NrÝ   c                    r¿   rÜ   rÀ   rÁ   r   r   r    r¤   ¡  rÂ   zAOurServerOurClientTests.test_directoryCreation.<locals>._getAttrsc                    r¿   rÜ   )rg   ÚremoveDirectoryrl   rÁ   r   r   r    Ú_removeDirectoryª  rÂ   zHOurServerOurClientTests.test_directoryCreation.<locals>._removeDirectory)rg   ÚmakeDirectoryrl   r‰   rª   r   r«   )r   rŠ   r¤   rã   r   r   r    Útest_directoryCreation  s   	


z.OurServerOurClientTests.test_directoryCreationc                    s\   ˆj  d¡}ˆ ¡  g ‰‡ ‡‡‡fdd„‰‡‡fdd„}‡fdd„‰ | ˆ¡ | |¡ |S )Nó    c                    sF   ‡‡ fdd„}t  ˆ j¡}ˆ ¡  | |¡ | ˆ¡ | ˆˆ ¡ |S )Nc                    s   ˆ   | ¡ ˆS r1   ry   r§   )Úfilesr   r   r    rz   º  s   
zMOurServerOurClientTests.test_openDirectory.<locals>._getFiles.<locals>.append)r   ÚmaybeDeferredÚnextrl   r‰   r©   )r   rz   rŠ   ©r­   r   rç   r   rŽ   r    r   ¹  s   

z=OurServerOurClientTests.test_openDirectory.<locals>._getFilesc                    s0   t t tˆ Ž ƒd ƒ}| ¡  ˆ |g d¢¡ d S )Nr   )ó   .testHiddenFileó   testDirectoryrÏ   rÔ   rx   )ÚlistÚzipÚsortrr   )rÑ   Úfs)rç   r   r   r    Ú_checkFilesÅ  s   þz?OurServerOurClientTests.test_openDirectory.<locals>._checkFilesc                    r¢   r1   )r~   rl   )rc   r   rŠ   r   r   r    r­   Ó  r¥   z:OurServerOurClientTests.test_openDirectory.<locals>._closer‘   )r   rŠ   rñ   r   rê   r    Útest_openDirectory´  s   

z*OurServerOurClientTests.test_openDirectoryc                 C   rÛ   )Nó   testLinkrÞ   rß   r   r   r    Útest_linkDoesntExistÜ  rá   z,OurServerOurClientTests.test_linkDoesntExistc                    sB   ˆ j  dd¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡S )Nró   rx   c                    s   ˆ j  dd¡}ˆ  ¡  |S )Nró   r!   rÀ   rÁ   r   r   r    Ú_getFirstAttrså  s   zDOurServerOurClientTests.test_linkSharesAttrs.<locals>._getFirstAttrsc                    r´   rµ   r¶   )Ú
firstAttrsrŠ   r   r   r    Ú_getSecondAttrsê  r›   zEOurServerOurClientTests.test_linkSharesAttrs.<locals>._getSecondAttrs©rg   ÚmakeLinkrl   r‰   )r   rŠ   rõ   r÷   r   r   r    Útest_linkSharesAttrsá  s   

z,OurServerOurClientTests.test_linkSharesAttrsc                    sF   ˆ j  dd¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡ |S )Nró   rx   c                    óH   ˆ j  d¡}ˆ  ¡  tt ¡ ƒ ˆ jj¡}| 	d¡}| 
ˆ j|j¡ |S ©Nró   rM   )rg   ÚreadLinkrl   r
   r3   r4   r5   rV   r6   rW   r‰   rr   )rc   rŠ   ÚtestFiler   r   r    Ú	_readLink÷  ó   
z8OurServerOurClientTests.test_linkPath.<locals>._readLinkc                    rû   rü   )rg   ÚrealPathrl   r
   r3   r4   r5   rV   r6   rW   r‰   rr   )rc   rŠ   ÚtestLinkr   r   r    Ú	_realPathÿ  r   z8OurServerOurClientTests.test_linkPath.<locals>._realPathrø   )r   rŠ   rÿ   r  r   r   r    Útest_linkPathó  s   

z%OurServerOurClientTests.test_linkPathc                 C   s4   | j  dd¡}|  ¡  | | jd¡ | | j¡ |S )NrD   s   foorE   )rg   rI   rl   r‰   rr   Ú_cbTestExtendedRequestrß   r   r   r    Útest_extendedRequest  s
   z,OurServerOurClientTests.test_extendedRequestc                 C   s"   | j  dd¡}|  ¡  |  |t¡S )Ns   testBadRequestræ   )rg   rI   rl   rª   rF   )r   rÑ   rŠ   r   r   r    r    s   z.OurServerOurClientTests._cbTestExtendedRequestz!Broken by PEP 479 and deprecated.c                 c   sš    | j  d¡}|  ¡  |V }tƒ }z!|D ]}|  ¡  |V \}}}| |¡ qW | ¡ }|  ¡  |V  n| ¡ }|  ¡  |V  w |  ¡  |  |h d£¡ dS )z
        Check that the object returned by
        L{filetransfer.FileTransferClient.openDirectory} can be used
        as an iterator.
        ræ   >   rx   rì   rÏ   rÔ   rë   N)rg   r’   rl   ÚsetÚaddr~   rr   )r   rŠ   r   Ú	filenamesr&   rÅ   rc   Ú	fileattrsr   r   r    Útest_openDirectoryIterator  s,   €ýþþz2OurServerOurClientTests.test_openDirectoryIteratorc                 c   sz    | j  d¡}|  ¡  |V }| ¡ }|  ¡  |V  |  ¡ }d}|  dt|ƒ¡ |  t|d d ¡ |  ||d d ¡ dS )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!   r   ÚcategoryÚmessageN)rg   r’   rl   ré   ÚflushWarningsrr   r%   ÚDeprecationWarning)r   rŠ   r   ÚoneFileÚwarningsr  r   r   r    Ú$test_openDirectoryIteratorDeprecatedA  s   €ÿz<OurServerOurClientTests.test_openDirectoryIteratorDeprecatedc                 #   sÐ    ˆj  dtji ¡}ˆ ¡  |V }g ‰ ‡ ‡fdd„}ˆjj ¡ \}||_~| dd¡}ˆ ¡  ˆ 	t
ˆ ƒd¡ ˆ |¡ ˆj ¡  ˆj ¡  ˆj ¡  ˆ ¡  ˆ ˆj j¡ ˆ |t¡ | ¡ }ˆ |t¡ dS )z{
        If there are requests outstanding when the connection
        is closed for any reason, they should fail.
        rx   c                    s"   ˆ  ˆ g ¡ t ¡ }ˆ  | ¡ |S r1   )rr   r   ÚDeferredrz   )ÚoffsetÚlengthrŠ   ©ÚgotReadRequestr   r   r    Ú	_slowReadd  s   
zOOurServerOurClientTests.test_closedConnectionCancelsRequests.<locals>._slowReadéd   éÈ   r!   N)rg   r„   r   r†   rl   rd   r   Úvaluesrš   rr   r%   ÚassertNoResultrk   ro   rn   rj   ÚassertFalseÚ	connectedÚfailureResultOfr   r£   )r   rŠ   Úfhr  ÚserverSideFhr   r  r    Ú$test_closedConnectionCancelsRequestsV  s*   €



z<OurServerOurClientTests.test_closedConnectionCancelsRequestsN) r-   r.   r/   r^   rl   rp   rs   rw   r‹   r“   r¡   r®   r¹   rÃ   rÎ   rÓ   rÚ   rà   rå   rò   rô   rú   r  r  r  r   ÚinlineCallbacksr   r	   r  r  r"  r   r   r   r    r_      s<    	!((
r_   c                   @   r8   )ÚFakeConnc                 C   ó   d S r1   r   )r   Úchannelr   r   r    Ú	sendClose…  ó   zFakeConn.sendCloseN)r-   r.   r/   r'  r   r   r   r    r$  „  r=   r$  c                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚFileTransferCloseTestsc                 C   s   t ƒ | _d S r1   )r   r;   r   r   r   r    r^   ‹  s   zFileTransferCloseTests.setUpc                 C   s,   t  ¡ }G dd„ dƒ}|ƒ |_| j|j_|S )Nc                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )zDFileTransferCloseTests.buildServerConnection.<locals>.DummyTransportc                 S   s
   | | _ d S r1   )Ú	transportr   r   r   r    r   ”  r<   zMFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.__init__c                 S   r%  r1   r   )r   ÚkindÚdatar   r   r    Ú
sendPacket—  r(  zOFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.sendPacketc                 S   s   dS )Nzdummy transportr   r   r   r   r    Ú	logPrefixš  r(  zNFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.logPrefixN)r-   r.   r/   r   r-  r.  r   r   r   r    ÚDummyTransport“  s    r/  )r   ÚSSHConnectionr*  r;   )r   Úconnr/  r   r   r    ÚbuildServerConnectionŽ  s
   

z,FileTransferCloseTests.buildServerConnectionc                    s$   dˆ_ |j‰ ‡ ‡fdd„}||_d S )NFc                    s   dˆ_ ˆ | ƒ d S )NT)ÚconnectionLostFired)Úreason©ÚorigConnectionLostr   r   r    ÚconnectionLost¥  s   zFFileTransferCloseTests.interceptConnectionLost.<locals>.connectionLost)r3  r7  )r   Ú
sftpServerr7  r   r5  r    ÚinterceptConnectionLost¡  s   
z.FileTransferCloseTests.interceptConnectionLostc                 C   s   |   | jd¡ d S )Nz*sftpServer's connectionLost was not called)rt   r3  r   r   r   r    ÚassertSFTPConnectionLost«  s   ÿz/FileTransferCloseTests.assertSFTPConnectionLostc                 C   sJ   t jtƒ | jd}| t d¡¡ |jjj	}|  
|¡ | ¡  |  ¡  dS )ze
        Closing a session should notify an SFTP subsystem launched by that
        session.
        )r1  r;   r   N)r   r   r$  r;   Úrequest_subsystemr   ÚNSrg   r*  Úprotor9  ÚcloseReceivedr:  )r   ÚtestSessionr8  r   r   r    Útest_sessionClose°  s   

z(FileTransferCloseTests.test_sessionClosec                 C   s‚   |   ¡ }t d¡t dd¡d  }| |¡ |jd }| t d¡¡ |jj	j
}|  |¡ |  |¡ | t dd¡¡ |  ¡  dS )zy
        A client sending CHANNEL_CLOSE should trigger closeReceived on the
        associated channel instance.
        r   ú>Lr   rq   r   N)r2  r   r<  ÚstructÚpackÚssh_CHANNEL_OPENÚchannelsr;  rg   r*  r=  r9  Ússh_CHANNEL_CLOSEr:  ©r   r1  ÚpacketÚsessionChannelr8  r   r   r    Ú%test_clientClosesChannelOnConnnectionÄ  s   




z<FileTransferCloseTests.test_clientClosesChannelOnConnnectionc                 C   sn   |   ¡ }t d¡t dd¡d  }| |¡ |jd }| t d¡¡ |jj	j
}|  |¡ | ¡  |  ¡  dS )zP
        Closing an SSH connection should close all sessions within it.
        r   rA  r   rq   r   N)r2  r   r<  rB  rC  rD  rE  r;  rg   r*  r=  r9  ÚserviceStoppedr:  rG  r   r   r    Ú'test_stopConnectionServiceClosesChannelÜ  s   



z>FileTransferCloseTests.test_stopConnectionServiceClosesChannelN)
r-   r.   r/   r^   r2  r9  r:  r@  rJ  rL  r   r   r   r    r)  ‰  s    
r)  zCannot run without cryptographyc                   @   s    e Zd ZdZg d¢Zdd„ ZdS )Ú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
        c                 C   s„   i }| j D ]}| ¡ D ]}t d|¡}|r"t| d¡dƒ|| d¡< qq|  t|ƒdkd¡ | ¡ D ]\}}|  	|t
t|ƒ¡ q2dS )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"   r   r!   z,No constants found (the test must be buggy).N)ÚfilexferSpecExcerptsÚ
splitlinesÚreÚmatchÚintÚgrouprt   r%   Úitemsrr   Úgetattrr   )r   Ú	constantsÚexcerptÚlineÚmÚkÚvr   r   r    Útest_constantsAgainstSpecH  s   
€ýÿÿz(ConstantsTests.test_constantsAgainstSpecN)r-   r.   r/   Ú__doc__rN  r\  r   r   r   r    rM  ñ  s    	LrM  c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚRawPacketDataServerTestszŒ
    Tests for L{filetransfer.FileTransferServer} which explicitly craft
    certain less common situations to exercise their handling.
    c                 C   s   t jtƒ d| _d S )Nr:   )r   r   r   Úftsr   r   r   r    r^   a  rÍ   zRawPacketDataServerTests.setUpc                 C   sŽ   t ƒ }| j |¡ d}d}t tdgƒ| t |¡ ¡}| j |¡ t tdgƒ| tg d¢ƒ t d¡ t d¡ ¡}t| ¡ t	|ƒƒ dS )	zl
        A close request with an unknown handle receives an FX_NO_SUCH_FILE error
        response.
        s   1234s   invalid handler€   ée   )r   r   r   r"   s   No such file or directoryræ   N)
r   r_  ri   r   r<  ÚbytesÚdataReceivedr   Úvaluer   )r   r*  Ú	requestIdr‚   r~   Úexpectedr   r   r    Útest_closeInvalidHandled  s6   ÿþýý
ú	÷óýþz0RawPacketDataServerTests.test_closeInvalidHandleN)r-   r.   r/   r]  r^   rf  r   r   r   r    r^  Z  s    r^  c                   @   sH   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )ÚRawPacketDataTestsz“
    Tests for L{filetransfer.FileTransferClient} which explicitly craft certain
    less common protocol messages to exercise their handling.
    c                 C   s   t  ¡ | _d S r1   )r   rf   Úftcr   r   r   r    r^   Ÿ  s   zRawPacketDataTests.setUpc                 C   sT   t  ¡ }| | j¡ || jjd< t ddtj	¡t
 d¡ t
 d¡ }| j |¡ |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<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
            of the SFTP Internet-Draft.
        r!   ú!LLó   msgó   lang)r   r  r‰   Ú_cbTestPacketSTATUSrh  ÚopenRequestsrB  rC  r   ÚFX_OKr   r<  Úpacket_STATUS©r   rŠ   r,  r   r   r    Útest_packetSTATUS¢  s   ÿþÿz$RawPacketDataTests.test_packetSTATUSc                 C   ó$   |   |d d¡ |   |d d¡ dS )z{
        Assert that the result is a two-tuple containing the message and
        language from the STATUS packet.
        r   rj  r!   rk  NrÊ   ©r   Úresultr   r   r    rl  µ  ó   z&RawPacketDataTests._cbTestPacketSTATUSc                 C   s@   t  ¡ }| | j¡ || jjd< t ddtj	¡}| j 
|¡ |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<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
            of the SFTP Internet-Draft.
        r!   ri  )r   r  r‰   Ú_cbTestPacketSTATUSShortrh  rm  rB  rC  r   rn  ro  rp  r   r   r    Útest_packetSTATUSShort½  s   	z)RawPacketDataTests.test_packetSTATUSShortc                 C   s$   |   |d d¡ |   |d d¡ dS )z—
        Assert that the result is a two-tuple containing empty strings, since
        the STATUS packet had neither a message nor a language.
        r   ræ   r!   NrÊ   rs  r   r   r    rv  Í  ru  z+RawPacketDataTests._cbTestPacketSTATUSShortc                 C   sJ   t  ¡ }| | j¡ || jjd< t ddtj	¡t
 d¡ }| j |¡ |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<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>}
            of the SFTP Internet-Draft.
        r!   ri  rj  )r   r  r‰   Ú_cbTestPacketSTATUSWithoutLangrh  rm  rB  rC  r   rn  r   r<  ro  rp  r   r   r    Útest_packetSTATUSWithoutLangÕ  s   
z/RawPacketDataTests.test_packetSTATUSWithoutLangc                 C   rr  )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.
        r   rj  r!   ræ   NrÊ   rs  r   r   r    rx  æ  ru  z1RawPacketDataTests._cbTestPacketSTATUSWithoutLangN)r-   r.   r/   r]  r^   rq  rl  rw  rv  ry  rx  r   r   r   r    rg  ˜  s    rg  ):r]  r3   rP  rB  Úunittestr   Úhamcrestr   r   Útwisted.internetr   Útwisted.internet.errorr   Útwisted.protocolsr   Útwisted.pythonr   Útwisted.python.compatr	   Útwisted.python.filepathr
   Útwisted.test.proto_helpersr   Útwisted.trial.unittestr   Útwisted.conchr   Ú_unixÚImportErrorÚtwisted.conch.unixr   Ú_SFTPServerForUnixConchUserÚcryptographyÚ_cryptographyÚtwisted.conch.avatarr   Ú
_ConchUserÚobjectÚtwisted.conch.sshr   r   r   r   r   r0   r9   r  Úwarnr>   ÚregisterAdapterru   rJ   r_   r$  r)  rM  r^  rg  r   r   r   r    Ú<module>   s   ÿÿÿÿÿ	üÿ		ÿ
   v

g
h
=