U
    Â“«jv}  ã                   @   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 zddlmZ W n ek
r´   dZY nX eZzddlmZ W n ek
râ   dZY nX eZzddlZW n ek
�r   dZY nX eZzddl m!Z" W n ek
�r>   e#Z!Y nX e"Z!zddl$m%Z%m&Z&m'Z'm(Z( W n ek
�rv   Y nX G dd„ de!ƒZ)G dd„ de)ƒZ*G dd„ dƒZ+edk�rÊddl,Z,e, -def ¡ n G dd„ deƒZ.e /e.e)e'j0¡ G dd„ deƒZ1ee dƒG dd„ de1ƒƒZ2G dd„ dƒZ3ee dƒG d d!„ d!eƒƒZ4ee d"ƒG d#d$„ d$eƒƒZ5ee dƒee d"ƒG d%d&„ d&eƒƒƒZ6ee d"ƒG d'd(„ d(eƒƒZ7dS ))z.
Tests for L{twisted.conch.ssh.filetransfer}.
é    N)ÚskipIf)Úassert_thatÚequal_to)Údefer)ÚConnectionLost)ÚStringTransport)Úloopback)Ú
components)ÚFilePath)ÚTestCase)Úunix)ÚSFTPServerForUnixConchUser)Ú	ConchUser)ÚcommonÚ
connectionÚfiletransferÚsessionc                   @   s   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   Ú
SSHSessionZchannelLookupr   ÚFileTransferServerZsubsystemLookup©Úself© r   úH/tmp/pip-unpacked-wheel-59kc99xd/twisted/conch/test/test_filetransfer.pyr   >   s    
zTestAvatar.__init__c                 O   s~   zt |ƒ}W n  tk
r,   |||fg}Y nX |D ]F}|d }t|ƒdkrR|d pTd}t|ƒdkrj|d pli }|||Ž}q2|S )Nr   é   r   é   )ÚiterÚ	TypeErrorÚlen)r   ÚfÚargsÚkwÚiÚfuncÚrr   r   r   Ú
_runAsUserC   s    zTestAvatar._runAsUserN)Ú__name__Ú
__module__Ú__qualname__r   r(   r   r   r   r   r   =   s   r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚFileTransferTestAvatarc                 C   s   t  | ¡ || _d S ©N)r   r   ÚhomeDir)r   r.   r   r   r   r   Q   s    
zFileTransferTestAvatar.__init__c                 C   s   t t ¡ ƒ | jj¡S r-   )r
   ÚosÚgetcwdÚpreauthChildr.   Úpathr   r   r   r   Ú
getHomeDirU   s    z!FileTransferTestAvatar.getHomeDirN)r)   r*   r+   r   r3   r   r   r   r   r,   P   s   r,   c                   @   s   e Zd Zdd„ ZdS )ÚConchSessionForTestAvatarc                 C   s
   || _ d S r-   ©Úavatar)r   r6   r   r   r   r   Z   s    z"ConchSessionForTestAvatar.__init__N)r)   r*   r+   r   r   r   r   r   r4   Y   s   r4   zNtwisted.conch.unix imported %r, but doesn't define SFTPServerForUnixConchUser'c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚFileTransferForTestAvatarc                 C   s   ddiS )Nó	   conchTestó   ext datar   )r   ÚversionZotherExtr   r   r   Ú
gotVersionm   s    z$FileTransferForTestAvatar.gotVersionc                 C   s   |dkrdS t ‚d S )Nó   testExtendedRequestó   bar)ÚNotImplementedError)r   ZextNameÚextDatar   r   r   ÚextendedRequestp   s    z)FileTransferForTestAvatar.extendedRequestN)r)   r*   r+   r;   r@   r   r   r   r   r7   l   s   r7   c                   @   s   e Zd Zdd„ ZdS )ÚSFTPTestBasec              
   C   s  t |  ¡ ƒ| _| j d¡| _| j d¡ d¡ | j d¡jdd��6}| d¡ tdd	ƒ�}| | d
¡¡ W 5 Q R X W 5 Q R X | j d¡ d¡ | j d¡jdd��}| d¡ W 5 Q R X | j d¡jdd��}| d¡ W 5 Q R X | j d¡jdd��}| d¡ W 5 Q R X d S )NÚextraZtestDirectoryTÚ	testfile1Úwb)Úmodeó   aaaaaaaaaabbbbbbbbbbz/dev/urandomÚrbi   i¤  ZtestRemoveFileó   aZtestRenameFilez.testHiddenFile)	r
   ÚmktempÚtestDirÚchildÚmakedirsÚopenÚwriteÚreadÚchmod)r   r"   Úf2r   r   r   ÚsetUp{   s    
$zSFTPTestBase.setUpN)r)   r*   r+   rR   r   r   r   r   rA   z   s   rA   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d-d.„ ƒZejd/d0„ ƒZd1S )2ÚOurServerOurClientTestsc                    s˜   t  ˆ ¡ tˆ jƒˆ _tjˆ jd�ˆ _t 	ˆ j¡}t 
¡ ˆ _d ˆ _d ˆ _‡ fdd„}|ˆ j_t 	ˆ j¡}ˆ j |¡ ˆ j |¡ |ˆ _|ˆ _ˆ  ¡  d S )Nr5   c                    s   | ˆ _ |ˆ _d S r-   )Ú_serverVersionÚ_extData)ZserverVersionr?   r   r   r   Ú_œ   s    z(OurServerOurClientTests.setUp.<locals>._)rA   rR   r,   rJ   r6   r   r   Úserverr   ZLoopbackRelayÚFileTransferClientÚclientrT   rU   ZgotServerVersionÚmakeConnectionÚclientTransportÚserverTransportÚ_emptyBuffers)r   r[   rV   r\   r   r   r   rR   ‘   s    

zOurServerOurClientTests.setUpc                 C   s*   | j js| jjr&| j  ¡  | j ¡  q d S r-   )r\   Úbufferr[   ÚclearBufferr   r   r   r   r]   ª   s    
z%OurServerOurClientTests._emptyBuffersc                 C   s,   | j  ¡  | j ¡  | j  ¡  | j ¡  d S r-   )r\   ÚloseConnectionr[   r_   r   r   r   r   ÚtearDown¯   s    


z OurServerOurClientTests.tearDownc                 C   s$   |   | jd¡ |   | jddi¡ d S )Né   r8   r9   )ÚassertEqualrT   rU   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   ÚISFTPServerZ
providedByrW   rY   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 r-   ©Úappend)Úfd)ÚclosedÚoldCloser   r   ÚcloseÎ   s    
zJOurServerOurClientTests.test_openedFileClosedWithConnection.<locals>.closern   c                    s`   ˆj j| jdd …  j}ˆj ¡  ˆj ¡  ˆj ¡  ˆj ¡  ˆ ˆj ji ¡ ˆ 	|ˆ ¡ d S )Né   )
rW   Ú	openFilesÚhandlerk   r\   r`   r[   r_   rc   ZassertIn)ÚopenFilerk   )rl   r   r   r   Ú_fileOpenedÔ   s    



zPOurServerOurClientTests.test_openedFileClosedWithConnection.<locals>._fileOpened)
rY   rr   r   ÚFXF_READÚ	FXF_WRITEr]   r/   rn   ÚpatchÚaddCallback)r   Údrn   rs   r   )rl   rm   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 r-   )r\   r`   r[   r_   rc   rW   ZopenDirs©ÚopenDirr   r   r   Ú	_getFilesè   s
    



zSOurServerOurClientTests.test_openedDirectoryClosedWithConnection.<locals>._getFiles©rY   ÚopenDirectoryr]   rw   )r   rx   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 )
Nrh   c                    s*   ˆ  | t | ¡¡ ˆ | ƒ}| ˆ| ¡ |S r-   )rc   r   Z	ISFTPFilerw   ©rr   rx   )Ú
_readChunkÚ_writeChunkr   r   r   rs   ø   s    z<OurServerOurClientTests.test_openFileIO.<locals>._fileOpenedc                    s&   |   dd¡}ˆ  ¡  | ˆ jd¡ |S )Nr   é   rF   ©Ú	readChunkr]   rw   rc   r�   r   r   r   r‚   þ   s    z;OurServerOurClientTests.test_openFileIO.<locals>._readChunkc                    s$   |  dd¡}ˆ ¡  | ˆ |¡ |S )Nr„   s
   cccccccccc)Z
writeChunkr]   rw   ©rV   rr   rx   )Ú_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ˆ   
  s    z<OurServerOurClientTests.test_openFileIO.<locals>._readChunk2©rY   rr   r   rt   ru   r]   rw   )r   rx   rs   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 )Nrh   c                    s   |  ¡ }ˆ  ¡  |S r-   )ÚgetAttrsr]   r‡   r   r   r   Ú	_getAttrs  s    zBOurServerOurClientTests.test_closedFileGetAttrs.<locals>._getAttrsc                    s   ˆ   ¡  | S r-   )ZflushLoggedErrors©r"   r   r   r   Ú_err  s    z=OurServerOurClientTests.test_closedFileGetAttrs.<locals>._errc                    s4   |   ¡ }ˆ ¡  | ˆ| ¡ | ˆ ¡ ˆ |tj¡S r-   )rn   r]   rw   Ú
addErrbackÚassertFailurer   Ú	SFTPErrorr�   ©r�   r�   r   r   r   Ú_close"  s
    
z?OurServerOurClientTests.test_closedFileGetAttrs.<locals>._closerŠ   )r   rx   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 )Nrh   c                    s   |   ¡ }ˆ ¡  | ˆ ¡ |S r-   ©rŒ   r]   rw   r�   ©Ú
_getAttrs2r   r   r   r�   2  s    
zBOurServerOurClientTests.test_openFileAttributes.<locals>._getAttrsc                    s&   ˆ j  d¡}ˆ  ¡  | ˆ j| ¡ |S ©Nrh   ©rY   rŒ   r]   rw   rc   )Zattrs1rx   r   r   r   r˜   8  s    zCOurServerOurClientTests.test_openFileAttributes.<locals>._getAttrs2rŠ   ©r   rx   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 )Nrh   c                    s   |   ¡ }ˆ ¡  | ˆ ¡ |S r-   r–   r�   )Ú	_setAttrsr   r   r   r�   H  s    
z@OurServerOurClientTests.test_openFileSetAttrs.<locals>._getAttrsc                    s:   d| d< ˆj  d| ¡}ˆ ¡  | ˆ ¡ | ˆj| ¡ |S )Nr   Úatimerh   )rY   ZsetAttrsr]   rw   rc   ©Úattrsrx   r—   r   r   r�   N  s    
z@OurServerOurClientTests.test_openFileSetAttrs.<locals>._setAttrsc                    s   ˆ j  d¡}ˆ  ¡  |S r™   ©rY   rŒ   r]   ©rV   rx   r   r   r   r˜   V  s    zAOurServerOurClientTests.test_openFileSetAttrs.<locals>._getAttrs2rŠ   r›   r   )r˜   r�   r   r   Útest_openFileSetAttrs@  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 r-   )Úupdate)ÚfilenameÚflagsr    )ÚoldOpenFileÚsavedAttributesr   r   rr   g  s    
zIOurServerOurClientTests.test_openFileExtendedAttributes.<locals>.openFilerh   Úext_foor=   c                    s   ˆ  ˆ ddi¡ d S )Nr©   r=   ©rc   )Zign)r¨   r   r   r   Úcheckt  s    zFOurServerOurClientTests.test_openFileExtendedAttributes.<locals>.check)rW   rY   rr   r   rt   ru   r]   rw   )r   rr   rx   r«   r   )r§   r¨   r   r   Útest_openFileExtendedAttributes^  s    


ýz7OurServerOurClientTests.test_openFileExtendedAttributesc                    sB   ˆ j  d¡}ˆ  ¡  ‡ fdd„}| |¡ | |¡ ˆ  |tj¡S )Nó   testRemoveFilec                    s   ˆ j  d¡}ˆ  ¡  |S )Nr­   )rY   Z
removeFiler]   )Úignoredrx   r   r   r   Ú_removeFile}  s    z<OurServerOurClientTests.test_removeFile.<locals>._removeFile)rY   rŒ   r]   rw   r‘   r   r’   )r   rx   r¯   r   r   r   Útest_removeFiley  s    

z'OurServerOurClientTests.test_removeFilec                    s8   ˆj  d¡}ˆ ¡  ‡ ‡fdd„}‡fdd„‰ | |¡S )Nó   testRenameFilec                    s&   ˆj  dd¡}ˆ ¡  | ˆ | ¡ |S )Nr±   ó   testRenamedFile)rY   Z
renameFiler]   rw   rŸ   ©Ú_testRenamedr   r   r   Ú_renameŠ  s    z8OurServerOurClientTests.test_renameFile.<locals>._renamec                    s&   ˆ j  d¡}ˆ  ¡  | ˆ j|¡ d S )Nr²   rš   )rV   r    rx   r   r   r   r´   �  s    z=OurServerOurClientTests.test_renameFile.<locals>._testRenamed)rY   rŒ   r]   rw   )r   rx   rµ   r   r³   r   Útest_renameFile†  s
    z'OurServerOurClientTests.test_renameFilec                 C   s"   | j  d¡}|  ¡  |  |tj¡S ©Nó   testMakeDirectory©rY   rŒ   r]   r‘   r   r’   ©r   rx   r   r   r   Útest_directoryBad—  s    z)OurServerOurClientTests.test_directoryBadc                    sZ   ˆ j  di ¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡ | |¡ ˆ  |tj¡S )Nr¸   c                    s   ˆ j  d¡}ˆ  ¡  |S r·   r¡   r¢   r   r   r   r�      s    zAOurServerOurClientTests.test_directoryCreation.<locals>._getAttrsc                    s   ˆ j  d¡}ˆ  ¡  |S r·   )rY   ZremoveDirectoryr]   r¢   r   r   r   Ú_removeDirectory©  s    zHOurServerOurClientTests.test_directoryCreation.<locals>._removeDirectory)rY   ZmakeDirectoryr]   rw   r‘   r   r’   )r   rx   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 r-   ri   rŽ   )Úfilesr|   r   r   rj   ¹  s    
zMOurServerOurClientTests.test_openDirectory.<locals>._getFiles.<locals>.append)r   ZmaybeDeferredÚnextr]   rw   r�   )r|   rj   rx   ©r”   r}   r¿   r   r{   r   r}   ¸  s    

z=OurServerOurClientTests.test_openDirectory.<locals>._getFilesc                    s6   t t tˆ Ž ƒd ƒ}| ¡  ˆ |dddddg¡ d S )Nr   s   .testHiddenFiles   testDirectoryr­   r±   rh   )ÚlistÚzipÚsortrc   )r®   Úfs)r¿   r   r   r   Ú_checkFilesÄ  s    ûþz?OurServerOurClientTests.test_openDirectory.<locals>._checkFilesc                    s   |  ¡ }ˆ  ¡  |S r-   )rn   r]   )rV   r|   rx   r   r   r   r”   Ò  s    z:OurServerOurClientTests.test_openDirectory.<locals>._closer~   )r   rx   rÆ   r   rÁ   r   Útest_openDirectory³  s    

z*OurServerOurClientTests.test_openDirectoryc                 C   s"   | j  d¡}|  ¡  |  |tj¡S )Nó   testLinkr¹   rº   r   r   r   Útest_linkDoesntExistÛ  s    z,OurServerOurClientTests.test_linkDoesntExistc                    sB   ˆ j  dd¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡S )NrÈ   rh   c                    s   ˆ j  dd¡}ˆ  ¡  |S )NrÈ   r   r¡   r¢   r   r   r   Ú_getFirstAttrsä  s    zDOurServerOurClientTests.test_linkSharesAttrs.<locals>._getFirstAttrsc                    s&   ˆ j  d¡}ˆ  ¡  | ˆ j| ¡ |S r™   rš   )Z
firstAttrsrx   r   r   r   Ú_getSecondAttrsé  s    zEOurServerOurClientTests.test_linkSharesAttrs.<locals>._getSecondAttrs©rY   ZmakeLinkr]   rw   )r   rx   rÊ   rË   r   r   r   Útest_linkSharesAttrsà  s    
z,OurServerOurClientTests.test_linkSharesAttrsc                    sF   ˆ j  dd¡}ˆ  ¡  ‡ fdd„}‡ fdd„}| |¡ | |¡ |S )NrÈ   rh   c                    sH   ˆ j  d¡}ˆ  ¡  tt ¡ ƒ ˆ jj¡}| 	d¡}| 
ˆ j|j¡ |S ©NrÈ   rC   )rY   ZreadLinkr]   r
   r/   r0   r1   rJ   r2   rK   rw   rc   )rV   rx   ZtestFiler   r   r   Ú	_readLinkö  s    
z8OurServerOurClientTests.test_linkPath.<locals>._readLinkc                    sH   ˆ j  d¡}ˆ  ¡  tt ¡ ƒ ˆ jj¡}| 	d¡}| 
ˆ j|j¡ |S rÎ   )rY   ZrealPathr]   r
   r/   r0   r1   rJ   r2   rK   rw   rc   )rV   rx   ZtestLinkr   r   r   Ú	_realPathþ  s    
z8OurServerOurClientTests.test_linkPath.<locals>._realPathrÌ   )r   rx   rÏ   rÐ   r   r   r   Útest_linkPathò  s    

z%OurServerOurClientTests.test_linkPathc                 C   s4   | j  dd¡}|  ¡  | | jd¡ | | j¡ |S )Nr<   s   foor=   )rY   r@   r]   rw   rc   Ú_cbTestExtendedRequestrº   r   r   r   Útest_extendedRequest
  s
    z,OurServerOurClientTests.test_extendedRequestc                 C   s"   | j  dd¡}|  ¡  |  |t¡S )Ns   testBadRequestr¾   )rY   r@   r]   r‘   r>   )r   r®   rx   r   r   r   rÒ     s    z.OurServerOurClientTests._cbTestExtendedRequestc                 c   sx   | 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)rY   r   r]   rÀ   ZflushWarningsrc   r!   ÚDeprecationWarning)r   rx   r|   ZoneFileÚwarningsrÕ   r   r   r   Ú$test_openDirectoryIteratorDeprecated  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.
        rh   c                    s"   ˆ  ˆ g ¡ t ¡ }ˆ  | ¡ |S r-   )rc   r   ÚDeferredrj   )ÚoffsetÚlengthrx   ©ZgotReadRequestr   r   r   Ú	_slowRead9  s    
zOOurServerOurClientTests.test_closedConnectionCancelsRequests.<locals>._slowReadéd   éÈ   r   N)rY   rr   r   rt   r]   rW   rp   Úvaluesr†   rc   r!   ZassertNoResultr\   r`   r_   r[   ZassertFalseÚ	connectedZfailureResultOfr   rŒ   )r   rx   ÚfhrÝ   ZserverSideFhr   rÜ   r   Ú$test_closedConnectionCancelsRequests+  s(    



z<OurServerOurClientTests.test_closedConnectionCancelsRequestsN)r)   r*   r+   rR   r]   ra   rd   rg   ry   r€   r‹   r•   rœ   r£   r¬   r°   r¶   r»   r½   rÇ   rÉ   rÍ   rÑ   rÓ   rÒ   r   ZinlineCallbacksrØ   rã   r   r   r   r   rS   �   s4   	!(
rS   c                   @   s   e Zd Zdd„ ZdS )ÚFakeConnc                 C   s   d S r-   r   )r   Zchannelr   r   r   Ú	sendCloseZ  s    zFakeConn.sendCloseN)r)   r*   r+   rå   r   r   r   r   rä   Y  s   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 r-   )r   r6   r   r   r   r   rR   `  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 r-   )Ú	transportr   r   r   r   r   i  s    zMFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.__init__c                 S   s   d S r-   r   )r   ÚkindÚdatar   r   r   Ú
sendPacketl  s    zOFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.sendPacketc                 S   s   dS )Nzdummy transportr   r   r   r   r   Ú	logPrefixo  s    zNFileTransferCloseTests.buildServerConnection.<locals>.DummyTransport.logPrefixN)r)   r*   r+   r   rê   rë   r   r   r   r   ÚDummyTransporth  s   rì   )r   ZSSHConnectionrç   r6   )r   Úconnrì   r   r   r   ÚbuildServerConnectionc  s
    

z,FileTransferCloseTests.buildServerConnectionc                    s$   dˆ_ |j‰ ‡ ‡fdd„}||_d S )NFc                    s   dˆ_ ˆ | ƒ d S )NT)ÚconnectionLostFired)Úreason©ZorigConnectionLostr   r   r   ÚconnectionLostz  s    zFFileTransferCloseTests.interceptConnectionLost.<locals>.connectionLost)rï   rò   )r   Ú
sftpServerrò   r   rñ   r   ÚinterceptConnectionLostv  s    z.FileTransferCloseTests.interceptConnectionLostc                 C   s   |   | jd¡ d S )Nz*sftpServer's connectionLost was not called)re   rï   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.
        )rí   r6   r   N)r   r   rä   r6   Úrequest_subsystemr   ÚNSrY   rç   Úprotorô   ZcloseReceivedrõ   )r   ZtestSessionró   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   rb   r   N)rî   r   r÷   ÚstructÚpackÚssh_CHANNEL_OPENÚchannelsrö   rY   rç   rø   rô   Zssh_CHANNEL_CLOSErõ   ©r   rí   ÚpacketZsessionChannelró   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   rú   r   rb   r   N)rî   r   r÷   rû   rü   rý   rþ   rö   rY   rç   rø   rô   ZserviceStoppedrõ   rÿ   r   r   r   Ú'test_stopConnectionServiceClosesChannel±  s    



z>FileTransferCloseTests.test_stopConnectionServiceClosesChannelN)
r)   r*   r+   rR   rî   rô   rõ   rù   r  r  r   r   r   r   ræ   ^  s   
ræ   zCannot run without cryptographyc                   @   s$   e Zd ZdZddddg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|ƒ¡ qdd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Úgroupre   r!   Úitemsrc   Úgetattrr   )r   Ú	constantsZexcerptÚlineÚmÚkÚvr   r   r   Útest_constantsAgainstSpec  s    

 ÿz(ConstantsTests.test_constantsAgainstSpecN)r)   r*   r+   Ú__doc__r  r  r   r   r   r   r  Æ  s   
&
ÄLr  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 )Nr5   )r   r   r   Úftsr   r   r   r   rR   9  s    zRawPacketDataServerTests.setUpc                 C   s’   t ƒ }| j |¡ d}d}t tdgƒ| t |¡ ¡}| j |¡ t tdgƒ| tddddgƒ 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 handlero   ée   r   r   s   No such file or directoryr¾   N)
r   r  rZ   r   r÷   ÚbytesZdataReceivedr   Úvaluer   )r   rç   Z	requestIdrq   rn   Úexpectedr   r   r   Útest_closeInvalidHandle<  s6    ÿþýýú	÷óýþz0RawPacketDataServerTests.test_closeInvalidHandleN)r)   r*   r+   r  rR   r  r   r   r   r   r  1  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 r-   )r   rX   Úftcr   r   r   r   rR   w  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Ù   rw   Ú_cbTestPacketSTATUSr  ÚopenRequestsrû   rü   r   ÚFX_OKr   r÷   Úpacket_STATUS©r   rx   ré   r   r   r   Útest_packetSTATUSz  s    ÿþÿz$RawPacketDataTests.test_packetSTATUSc                 C   s$   |   |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   r  r   r  Nrª   ©r   Úresultr   r   r   r  �  s    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   r  )r   rÙ   rw   Ú_cbTestPacketSTATUSShortr  r   rû   rü   r   r!  r"  r#  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ª   r%  r   r   r   r'  ¥  s    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   r  r  )r   rÙ   rw   Ú_cbTestPacketSTATUSWithoutLangr  r   rû   rü   r   r!  r   r÷   r"  r#  r   r   r   Útest_packetSTATUSWithoutLang­  s    
z/RawPacketDataTests.test_packetSTATUSWithoutLangc                 C   s$   |   |d d¡ |   |d d¡ dS )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   r  r   r¾   Nrª   r%  r   r   r   r)  ¾  s    z1RawPacketDataTests._cbTestPacketSTATUSWithoutLangN)r)   r*   r+   r  rR   r$  r  r(  r'  r*  r)  r   r   r   r   r  p  s   r  )8r  r/   r  rû   Zunittestr   Zhamcrestr   r   Ztwisted.internetr   Ztwisted.internet.errorr   Ztwisted.internet.testingr   Ztwisted.protocolsr   Ztwisted.pythonr	   Ztwisted.python.filepathr
   Ztwisted.trial.unittestr   Ztwisted.conchr   Z_unixÚImportErrorZtwisted.conch.unixr   Z_SFTPServerForUnixConchUserZcryptographyZ_cryptographyZtwisted.conch.avatarr   Z
_ConchUserÚobjectZtwisted.conch.sshr   r   r   r   r   r,   r4   r×   Úwarnr7   ZregisterAdapterrf   rA   rS   rä   ræ   r  r  r  r   r   r   r   Ú<module>   sˆ   



	
üÿ		  ÿ
   L
g
j

=
