U
    �Acj¯B  ã                   @  s  d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZ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mZmZ dd
lmZ ddlmZm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 zddl7Z7W n e8k
�rj   dZ7Y nX ee*j9ƒG dd„ dƒƒZ:G dd„ deƒZ;eeƒG dd„ dƒƒZ<eeƒG dd„ dƒƒZ=eeƒG dd„ dƒƒZ>G dd„ dƒZ?e4 @e=e;ej¡ e4 @e<e;e!j¡ dS ) z
A UNIX SSH server.
é    )ÚannotationsN)ÚCallableÚDictÚTuple)Úimplementer)Úttymodes)Ú	ConchUser)Ú
ConchError)ÚISessionÚ	ISFTPFileÚISFTPServer)ÚlsLine)ÚfiletransferÚ
forwardingÚsession)Ú
FXF_APPENDÚ	FXF_CREATÚFXF_EXCLÚFXF_READÚ	FXF_TRUNCÚ	FXF_WRITE)Úportal)ÚLoginDenied)ÚProcessExitedAlready)ÚIListeningPort)ÚLogger)Ú
components)ÚnativeStringc                   @  s    e Zd Zdddddœdd„ZdS )	ÚUnixSSHRealmzbytes | Tuple[()]Úobjectzportal._InterfaceItselfzATuple[portal._InterfaceItself, UnixConchUser, Callable[[], None]])ÚusernameÚmindÚ
interfacesÚreturnc                 G  s.   t |tƒstdƒ‚t| ¡ ƒ}|d ||jfS )Nz5UNIX SSH realm does not authorize anonymous sessions.r   )Ú
isinstanceÚbytesr   ÚUnixConchUserÚdecodeÚlogout)Úselfr    r!   r"   Úuser© r+   ú6/tmp/pip-unpacked-wheel-nrvc_22y/twisted/conch/unix.pyÚrequestAvatar5   s    
zUnixSSHRealm.requestAvatarN)Ú__name__Ú
__module__Ú__qualname__r-   r+   r+   r+   r,   r   3   s   r   c                   @  sb   e Zd Zdddœdd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Z	ddœdd„Z
dd„ ZdS )r&   ÚstrÚNone)r    r#   c                 C  sŠ   t  | ¡ || _t | j¡| _| jd g}t ¡ D ]\}}}}||kr2| |¡ q2|| _	i | _
| j tjtjdœ¡ | j dtji¡ d S )Né   )s   sessions   direct-tcpips   sftp)r   Ú__init__r    ÚpwdÚgetpwnamÚpwdDataÚgrpÚgetgrallÚappendÚotherGroupsÚ	listenersZchannelLookupÚupdater   Z
SSHSessionr   ZopenConnectForwardingClientZsubsystemLookupr   ZFileTransferServer)r)   r    ÚlZ	groupnameÚpasswordÚgidZuserlistr+   r+   r,   r4   B   s     
þþÿzUnixConchUser.__init__c                 C  s   | j dd… S )Né   é   ©r7   ©r)   r+   r+   r,   ÚgetUserGroupIdW   s    zUnixConchUser.getUserGroupIdc                 C  s   | j S ©N)r;   rD   r+   r+   r,   ÚgetOtherGroupsZ   s    zUnixConchUser.getOtherGroupsc                 C  s
   | j d S )Né   rC   rD   r+   r+   r,   Ú
getHomeDir]   s    zUnixConchUser.getHomeDirc                 C  s
   | j d S )Né   rC   rD   r+   r+   r,   ÚgetShell`   s    zUnixConchUser.getShellc                 C  s–   t  |¡\}}ddlm} z*| j|j|t  | j||ft j¡|d�}W n t	k
rZ   Y dS X || j
||f< |dkrŽ| ¡ d }dt d|¡fS dS d S )Nr   ©Úreactor)Z	interfacerA   é   z>L)r   ÚunpackGlobal_tcpip_forwardÚtwisted.internetrM   Ú
_runAsUserZ	listenTCPZSSHListenForwardingFactoryÚconnZ SSHListenServerForwardingChannelÚBaseExceptionr<   ÚgetHostÚstructÚpack)r)   ÚdataÚ
hostToBindÚ
portToBindrM   Úlistenerr+   r+   r,   Úglobal_tcpip_forwardc   s(    ýø

z"UnixConchUser.global_tcpip_forwardc                 C  sD   t  |¡\}}| j ||fd ¡}|s(dS | j||f= |  |j¡ dS )Nr   rN   )r   rO   r<   ÚgetrQ   ÚstopListening)r)   rW   rX   rY   rZ   r+   r+   r,   Úglobal_cancel_tcpip_forward|   s    z)UnixConchUser.global_cancel_tcpip_forward)r#   c                 C  s:   | j  ¡ D ]}|  |j¡ q
| jjd| jt| j ƒd� d S )Nz,avatar {username} logging out ({nlisteners}))r    Z
nlisteners)r<   ÚvaluesrQ   r]   Ú_logÚinfor    Úlen)r)   rZ   r+   r+   r,   r(   …   s    ýzUnixConchUser.logoutc              	   O  s  t  ¡ }t  ¡ }t  ¡ }|  ¡ \}}t  d¡ t  d¡ t  |  ¡ ¡ t  |¡ t  |¡ zt	|ƒ}W n  t
k
r†   |||fg}Y nX zP|D ]F}	|	d }
t|	ƒdkr®|	d p°d}t|	ƒdkrÆ|	d pÈi }|
||Ž}qŽW 5 t  d¡ t  d¡ t  |¡ t  |¡ t  |¡ X |S )Nr   rN   r+   rA   )ÚosÚgeteuidÚgetegidÚ	getgroupsrE   ÚsetegidÚseteuidÚ	setgroupsrG   ÚiterÚ	TypeErrorrb   )r)   ÚfÚargsÚkwÚeuidÚegidÚgroupsÚuidr@   ÚiÚfuncÚrr+   r+   r,   rQ   �   s2    







zUnixConchUser._runAsUserN)r.   r/   r0   r4   rE   rG   rI   rK   r[   r^   r(   rQ   r+   r+   r+   r,   r&   A   s   	
r&   c                   @  sn   e Zd Zeƒ Zddd„Zd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S )ÚSSHSessionForUnixConchUserNc                 C  s:   |dkrddl m} || _|| _ddi| _d| _d| _dS )a  
        Construct an C{SSHSessionForUnixConchUser}.

        @param avatar: The L{UnixConchUser} for whom this is an SSH session.
        @param reactor: An L{IReactorProcess} used to handle shell and exec
            requests. Uses the default reactor if None.
        Nr   rL   ÚPATHz/bin:/usr/bin:/usr/local/bin)rP   rM   Ú_reactorÚavatarÚenvironÚptyÚptyTuple)r)   ry   rM   r+   r+   r,   r4   °   s    
z#SSHSessionForUnixConchUser.__init__rN   c                 C  s  t sd S | jjjj ¡ j}t dt 	|¡¡\}| j
d dd … }t ¡ }t|ƒ}t|| d ƒ}t  ¡ }|rrt jpvt j|_| jj|_||_|dd … |_||f|_|rÎ| jj|_t |¡d |_|dddf|_t  t j¡}	|	 |¡ |	 ¡  t  t j ¡}
|
 |¡ |
 ¡  d S )NÚLrA   rH   g    €„.Aéüÿÿÿr   )!Úutmpry   rR   Ú	transportÚgetPeerÚhostrU   ÚunpackÚsocketÚ	inet_atonr|   ÚtimeÚintZ	UtmpEntryZUSER_PROCESSZDEAD_PROCESSZut_typer{   ÚpidZut_pidZut_lineZut_idZut_tvr    Zut_userÚgethostbyaddrZut_hostZ
ut_addr_v6Z
UtmpRecordZ	UTMP_FILEZ	pututlineZendutentZ	WTMP_FILE)r)   ZloggedInZ	ipAddressZpackedIpZttyNameÚtÚt1Út2ÚentryÚaÚbr+   r+   r,   ÚaddUTMPEntryÀ   s0    




z'SSHSessionForUnixConchUser.addUTMPEntryc                 C  sF   || j d< || _|| _t ¡ \}}t |¡}|| j d< |||f| _d S )NÚTERMZSSH_TTY)rz   ÚwinSizeÚmodesr{   Úopenptyrc   Úttynamer|   )r)   ZtermZ
windowSizer“   ZmasterZslaver•   r+   r+   r,   ÚgetPtyÚ   s    


z!SSHSessionForUnixConchUser.getPtyc           	   
   C  s@  | j s| j d¡ tdƒ‚| j ¡ \}}| j ¡ }| j ¡ }| jj| j	d< || j	d< || j	d< t
j |¡}| jjjj ¡ }| jjjj ¡ }|j› d|j› d|j› �| j	d< |  ¡  | jj||d|› �g| j	|||| j d	�| _|  ¡  t | j ¡ tjtjd| jžŽ ¡ | j �r|  !¡  |jj"| _#| j$|j_"| jjjj %d¡ d S )Nz'tried to get shell without pty, failingzno ptyÚUSERÚHOMEÚSHELLú Ú
SSH_CLIENTú-©ZusePTYÚ4HrN   )rž   )&r|   r`   Úerrorr	   ry   rE   rI   rK   r    rz   rc   ÚpathÚbasenamerR   r€   r�   rT   r‚   ÚportÚgetPtyOwnershiprx   ÚspawnProcessr{   r�   ÚfcntlÚioctlÚfilenoÚttyÚ
TIOCSWINSZrU   rV   r’   r“   ÚsetModesÚwriteÚoldWriteÚ
_writeHackÚsetTcpNoDelay)	r)   Úprotorr   r@   ÚhomeDirÚshellZ	shellExecÚpeerr‚   r+   r+   r,   Ú	openShellã   s>    



 
ø
"

z$SSHSessionForUnixConchUser.openShellc           
   
   C  sà   | j  ¡ \}}| j  ¡ }| j  ¡ p$d}|| jd< |d|f}| j jjj ¡ }| j jjj ¡ }	|j	› d|j
› d|	j
› �| jd< | jrˆ|  ¡  | jj|||| j|||| jp¦dd�| _| jrÊ|  ¡  | jrÊ|  ¡  | j jjj d¡ d S )	Nz/bin/shr˜   z-crš   r›   r   r�   rN   )ry   rE   rI   rK   rz   rR   r€   r�   rT   r‚   r¢   r|   r£   rx   r¤   r{   r�   r“   rª   r®   )
r)   r¯   Úcmdrr   r@   r°   r±   Úcommandr²   r‚   r+   r+   r,   ÚexecCommand  s2    


 ø
z&SSHSessionForUnixConchUser.execCommandc              	   C  s|   t  | jd ¡d }| j ¡ \}}t  ¡ t  ¡  }}t  d¡ t  d¡ zt  	| jd ||¡ W 5 t  |¡ t  |¡ X d S )NrA   rH   r   )
rc   Ústatr|   ry   rE   rd   re   rg   rh   Úchown)r)   ZttyGidrr   r@   ro   rp   r+   r+   r,   r£     s    


z*SSHSessionForUnixConchUser.getPtyOwnershipc           	      C  s  | j }t | ¡ ¡}| jD ]Ü\}}|tjkr.qtj| }t|ƒdkrŒ|\}}tt|ƒsXqt	t|ƒ}|rx|| |B ||< qö|| | @ ||< q|dkr¬t	td|› �ƒ|tj
< q|dkrÌt	td|› �ƒ|tj< qtt|ƒsØqt	t|ƒ}t|fƒ|tj |< qt | ¡ tj|¡ d S )NrA   ÚOSPEEDÚBÚISPEED)r{   r¨   Ú	tcgetattrr§   r“   r   ZTTYMODESrb   ÚhasattrÚgetattrr¹   r»   r%   ÚCCÚ	tcsetattrÚTCSANOW)	r)   r{   ÚattrÚmodeZ	modeValueZttyModeÚflagZttyAttrZttyvalr+   r+   r,   rª   +  s.    





z#SSHSessionForUnixConchUser.setModesc                 C  s   | j r| j  ¡  d S rF   )r{   Z
closeStdinrD   r+   r+   r,   ÚeofReceivedF  s    z&SSHSessionForUnixConchUser.eofReceivedc              	   C  s”   | j r@tj | j d ¡r@t | j d ¡d }t | j d d|¡ | jr„z| j d¡ W n tt	fk
rn   Y nX | j 
¡  |  d¡ | j d¡ d S )NrA   rH   r   ZHUPzshell closed)r|   rc   r    Úexistsr·   r¸   r{   ZsignalProcessÚOSErrorr   ZloseConnectionr�   r`   ra   )r)   ZttyGIDr+   r+   r,   ÚclosedJ  s    

z!SSHSessionForUnixConchUser.closedc                 C  s,   || _ t | j ¡ tjtjd| j žŽ ¡ d S )Nrž   )rž   )	r’   r¥   r¦   r{   r§   r¨   r©   rU   rV   )r)   r’   r+   r+   r,   ÚwindowChangedW  s    z(SSHSessionForUnixConchUser.windowChangedc                 C  s\   | j dk	rNt | j  ¡ ¡d }|tj@ sN|tj@ rN| jjj 	ddt
|ƒ  ¡ |  |¡ dS )zF
        Hack to send ignore messages when we aren't echoing.
        Nr3   ú é   )r{   r¨   r¼   r§   ÚECHOÚICANONry   rR   r€   Z
sendIgnorerb   r¬   )r)   rW   rÂ   r+   r+   r,   r­   [  s
    
z%SSHSessionForUnixConchUser._writeHack)N)rN   )r.   r/   r0   r   r`   r4   r�   r–   r³   r¶   r£   rª   rÅ   rÈ   rÉ   r­   r+   r+   r+   r,   rv   ¬   s   

	!rv   c                   @  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#S )$ÚSFTPServerForUnixConchUserc                 C  s
   || _ d S rF   )ry   )r)   ry   r+   r+   r,   r4   h  s    z#SFTPServerForUnixConchUser.__init__c                 C  sj   d|kr&d|kr&t  ||d |d ¡ d|kr>t  ||d ¡ d|krfd|krft  ||d |d f¡ dS )zl
        NOTE: this function assumes it runs as the logged-in user:
        i.e. under _runAsUser()
        rr   r@   ÚpermissionsÚatimeÚmtimeN)rc   r¸   ÚchmodÚutime©r)   r    Úattrsr+   r+   r,   Ú	_setAttrsk  s    z$SFTPServerForUnixConchUser._setAttrsc                 C  s&   |j |j|j|jt|jƒt|jƒdœS )N)Úsizerr   r@   rÏ   rÐ   rÑ   )Úst_sizeÚst_uidÚst_gidÚst_moder‡   Úst_atimeÚst_mtime©r)   Úsr+   r+   r,   Ú	_getAttrsw  s    úz$SFTPServerForUnixConchUser._getAttrsc                 C  s"   | j  ¡ }tj t|jƒt|ƒ¡S rF   )ry   rI   rc   r    Újoinr   )r)   r    Úhomer+   r+   r,   Ú_absPath�  s    
z#SFTPServerForUnixConchUser._absPathc                 C  s   i S rF   r+   )r)   ZotherVersionÚextDatar+   r+   r,   Ú
gotVersion…  s    z%SFTPServerForUnixConchUser.gotVersionc                 C  s   t | |  |¡||ƒS rF   )ÚUnixSFTPFilerã   )r)   ÚfilenameÚflagsrÕ   r+   r+   r,   ÚopenFileˆ  s    z#SFTPServerForUnixConchUser.openFilec                 C  s   |   |¡}| j tj|¡S rF   )rã   ry   rQ   rc   Úremove)r)   rç   r+   r+   r,   Ú
removeFile‹  s    
z%SFTPServerForUnixConchUser.removeFilec                 C  s&   |   |¡}|   |¡}| j tj||¡S rF   )rã   ry   rQ   rc   Úrename)r)   ÚoldpathÚnewpathr+   r+   r,   Ú
renameFile�  s    

z%SFTPServerForUnixConchUser.renameFilec                 C  s,   |   |¡}| j tj|ff| j||ffg¡S rF   )rã   ry   rQ   rc   ÚmkdirrÖ   rÔ   r+   r+   r,   ÚmakeDirectory”  s    
ÿz(SFTPServerForUnixConchUser.makeDirectoryc                 C  s   |   |¡}| j tj|¡ d S rF   )rã   ry   rQ   rc   Úrmdir©r)   r    r+   r+   r,   ÚremoveDirectoryš  s    
z*SFTPServerForUnixConchUser.removeDirectoryc                 C  s   t | |  |¡ƒS rF   )ÚUnixSFTPDirectoryrã   ró   r+   r+   r,   ÚopenDirectoryž  s    z(SFTPServerForUnixConchUser.openDirectoryc                 C  s:   |   |¡}|r | j tj|¡}n| j tj|¡}|  |¡S rF   )rã   ry   rQ   rc   r·   Úlstatrà   )r)   r    ZfollowLinksrß   r+   r+   r,   ÚgetAttrs¡  s
    
z#SFTPServerForUnixConchUser.getAttrsc                 C  s    |   |¡}| j | j||¡ d S rF   )rã   ry   rQ   rÖ   rÔ   r+   r+   r,   ÚsetAttrs©  s    
z#SFTPServerForUnixConchUser.setAttrsc                 C  s   |   |¡}| j tj|¡S rF   )rã   ry   rQ   rc   Úreadlinkró   r+   r+   r,   ÚreadLink­  s    
z#SFTPServerForUnixConchUser.readLinkc                 C  s&   |   |¡}|   |¡}| j tj||¡S rF   )rã   ry   rQ   rc   Úsymlink)r)   ZlinkPathZ
targetPathr+   r+   r,   ÚmakeLink±  s    

z#SFTPServerForUnixConchUser.makeLinkc                 C  s   t j |  |¡¡S rF   )rc   r    Úrealpathrã   ró   r+   r+   r,   ÚrealPath¶  s    z#SFTPServerForUnixConchUser.realPathc                 C  s   t ‚d S rF   ©ÚNotImplementedError)r)   ZextNamerä   r+   r+   r,   ÚextendedRequest¹  s    z*SFTPServerForUnixConchUser.extendedRequestN)r.   r/   r0   r4   rÖ   rà   rã   rå   ré   rë   rï   rñ   rô   rö   rø   rù   rû   rý   rÿ   r  r+   r+   r+   r,   rÎ   f  s"   
rÎ   c                   @  s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ræ   c                 C  s  || _ d}|t@ tkr(|t@ dkr(tj}|t@ tkrF|t@ dkrFtj}|t@ tkrd|t@ tkrdtj}|t@ tkrz|tjO }|t	@ t	kr�|tj
O }|t@ tkr¦|tjO }|t@ tkr¼|tjO }d|krÔ|d }|d= nd}|j tj|||¡}|�r|j |j||¡ || _d S )Nr   rÏ   iÿ  )Úserverr   r   rc   ÚO_RDONLYÚO_WRONLYÚO_RDWRr   ÚO_APPENDr   ÚO_CREATr   ÚO_TRUNCr   ÚO_EXCLry   rQ   ÚopenrÖ   Úfd)r)   r  rç   rè   rÕ   Z	openFlagsrÃ   r  r+   r+   r,   r4   ¿  s0    



zUnixSFTPFile.__init__c                 C  s   | j j tj| j¡S rF   )r  ry   rQ   rc   Úcloser  rD   r+   r+   r,   r  Ú  s    zUnixSFTPFile.closec                 C  s,   | j j tj| j|dfftj| j|ffg¡S ©Nr   )r  ry   rQ   rc   Úlseekr  Úread)r)   ÚoffsetÚlengthr+   r+   r,   Ú	readChunkÝ  s     ÿzUnixSFTPFile.readChunkc                 C  s,   | j j tj| j|dfftj| j|ffg¡S r  )r  ry   rQ   rc   r  r  r«   )r)   r  rW   r+   r+   r,   Ú
writeChunkâ  s     ÿzUnixSFTPFile.writeChunkc                 C  s    | j j tj| j¡}| j  |¡S rF   )r  ry   rQ   rc   Úfstatr  rà   rÞ   r+   r+   r,   rø   ç  s    zUnixSFTPFile.getAttrsc                 C  s   t ‚d S rF   r   )r)   rÕ   r+   r+   r,   rù   ë  s    zUnixSFTPFile.setAttrsN)	r.   r/   r0   r4   r  r  r  rø   rù   r+   r+   r+   r,   ræ   ½  s   ræ   c                   @  s0   e Zd Zdd„ Zdd„ Zdd„ ZeZdd„ Zd	S )
rõ   c                 C  s"   || _ |j tj|¡| _|| _d S rF   )r  ry   rQ   rc   ÚlistdirÚfilesÚdir)r)   r  Ú	directoryr+   r+   r,   r4   ð  s    zUnixSFTPDirectory.__init__c                 C  s   | S rF   r+   rD   r+   r+   r,   Ú__iter__õ  s    zUnixSFTPDirectory.__iter__c                 C  sl   z| j  d¡}W n tk
r(   t‚Y n@X | jj tjtj	 
| j|¡¡}t||ƒ}| j |¡}|||fS d S r  )r  ÚpopÚ
IndexErrorÚStopIterationr  ry   rQ   rc   r÷   r    rá   r  r   rà   )r)   rl   rß   ÚlongnamerÕ   r+   r+   r,   Ú__next__ø  s    

zUnixSFTPDirectory.__next__c                 C  s
   g | _ d S rF   )r  rD   r+   r+   r,   r    s    zUnixSFTPDirectory.closeN)r.   r/   r0   r4   r  r  Únextr  r+   r+   r+   r,   rõ   ï  s
   rõ   )AÚ__doc__Ú
__future__r   r¥   r8   rc   r{   r5   r„   rU   r†   r¨   Útypingr   r   r   Zzope.interfacer   Ztwisted.conchr   Ztwisted.conch.avatarr   Ztwisted.conch.errorr	   Ztwisted.conch.interfacesr
   r   r   Ztwisted.conch.lsr   Ztwisted.conch.sshr   r   r   Ztwisted.conch.ssh.filetransferr   r   r   r   r   r   Ztwisted.credr   Ztwisted.cred.errorr   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   Ztwisted.loggerr   Ztwisted.pythonr   Ztwisted.python.compatr   r   ÚImportErrorZIRealmr   r&   rv   rÎ   ræ   rõ   ZregisterAdapterr+   r+   r+   r,   Ú<module>   s^    
k :V1  ÿ