o
    ¯b¦@  ã                   @   sÌ  d 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 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)m*Z* ddl+m,Z, zddl-Z-W n e.y—   dZ-Y nw ee$j/ƒG dd„ dƒƒZ0G dd„ deƒZ1eeƒG dd„ dƒƒZ2eeƒG dd„ dƒƒZ3eeƒG dd„ dƒƒZ4G dd„ dƒZ5e* 6e3e1ej¡ e* 6e2e1ej¡ dS )z
A UNIX SSH server.
é    N)Úimplementer)Úttymodes)Ú	ConchUser)Ú
ConchError)ÚISessionÚ	ISFTPFileÚISFTPServer)ÚlsLine)ÚfiletransferÚ
forwardingÚsession)Ú
FXF_APPENDÚ	FXF_CREATÚFXF_EXCLÚFXF_READÚ	FXF_TRUNCÚ	FXF_WRITE)Úportal)ÚProcessExitedAlready)ÚLogger)Ú
components)ÚnativeStringc                   @   s   e Zd Zdd„ ZdS )ÚUnixSSHRealmc                 G   s   t |ƒ}|d ||jfS ©Nr   )ÚUnixConchUserÚlogout)ÚselfÚusernameÚmindÚ
interfacesÚuser© r!   ú4/usr/lib/python3/dist-packages/twisted/conch/unix.pyÚrequestAvatar0   s   zUnixSSHRealm.requestAvatarN)Ú__name__Ú
__module__Ú__qualname__r#   r!   r!   r!   r"   r   .   s    r   c                   @   sT   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S )r   c                 C   sŠ   t  | ¡ || _t | j¡| _| jd g}t ¡ D ]\}}}}||v r(| |¡ q|| _	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Ú	listenersÚchannelLookupÚupdater   Ú
SSHSessionr   ÚopenConnectForwardingClientÚsubsystemLookupr
   ÚFileTransferServer)r   r   ÚlÚ	groupnameÚpasswordÚgidÚuserlistr!   r!   r"   r(   6   s    

€þÿzUnixConchUser.__init__c                 C   s   | j dd… S )Né   é   ©r+   ©r   r!   r!   r"   ÚgetUserGroupIdI   s   zUnixConchUser.getUserGroupIdc                 C   s   | j S ©N)r/   r?   r!   r!   r"   ÚgetOtherGroupsL   s   zUnixConchUser.getOtherGroupsc                 C   ó
   | j d S )Né   r>   r?   r!   r!   r"   Ú
getHomeDirO   ó   
zUnixConchUser.getHomeDirc                 C   rC   )Né   r>   r?   r!   r!   r"   ÚgetShellR   rF   zUnixConchUser.getShellc                 C   s�   t  |¡\}}ddlm} z| j|j|t  | j||ft j¡|d�}W n
 t	y,   Y dS w || j
||f< |dkrF| ¡ d }dt d|¡fS dS )Nr   ©Úreactor)Ú	interfacer<   é   z>L)r   ÚunpackGlobal_tcpip_forwardÚtwisted.internetrJ   Ú
_runAsUserÚ	listenTCPÚSSHListenForwardingFactoryÚconnÚ SSHListenServerForwardingChannelÚBaseExceptionr0   ÚgetHostÚstructÚpack)r   ÚdataÚ
hostToBindÚ
portToBindrJ   Úlistenerr!   r!   r"   Úglobal_tcpip_forwardU   s*   ý
ø
ÿz"UnixConchUser.global_tcpip_forwardc                 C   sD   t  |¡\}}| j ||fd ¡}|sdS | j||f= |  |j¡ dS )Nr   rL   )r   rM   r0   ÚgetrO   ÚstopListening)r   rX   rY   rZ   r[   r!   r!   r"   Úglobal_cancel_tcpip_forwardn   s   z)UnixConchUser.global_cancel_tcpip_forwardc                 C   s:   | j  ¡ D ]}|  |j¡ q| jjd| jt| j ƒd� d S )Nz,avatar {username} logging out ({nlisteners}))r   Ú
nlisteners)r0   ÚvaluesrO   r^   Ú_logÚinfor   Úlen)r   r[   r!   r!   r"   r   w   s   
ýzUnixConchUser.logoutc              	   O   sD  t  ¡ }t  ¡ }t  ¡ }|  ¡ \}}t  d¡ t  d¡ t  |  ¡ ¡ t  |¡ t  |¡ zt	|ƒ}W n t
yB   |||fg}Y nw zD|D ]%}	|	d }
t|	ƒdkrV|	d pWd}t|	ƒdkrb|	d pci }|
|i |¤Ž}qFW t  d¡ t  d¡ t  |¡ t  |¡ t  |¡ |S t  d¡ t  d¡ t  |¡ t  |¡ t  |¡ w )Nr   rL   r!   r<   )ÚosÚgeteuidÚgetegidÚ	getgroupsr@   ÚsetegidÚseteuidÚ	setgroupsrB   ÚiterÚ	TypeErrorrd   )r   ÚfÚargsÚkwÚeuidÚegidÚgroupsÚuidr:   ÚiÚfuncÚrr!   r!   r"   rO   �   s@   



ÿü





û


zUnixConchUser._runAsUserN)r$   r%   r&   r(   r@   rB   rE   rH   r\   r_   r   rO   r!   r!   r!   r"   r   5   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u 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   rI   ÚPATHz/bin:/usr/bin:/usr/local/bin)rN   rJ   Ú_reactorÚavatarÚenvironÚptyÚptyTuple)r   r{   rJ   r!   r!   r"   r(   ¢   s   

z#SSHSessionForUnixConchUser.__init__rL   c                 C   s  t sd S | jjjj ¡ j}t dt 	|¡¡\}| j
d dd … }t ¡ }t|ƒ}t|| d ƒ}t  ¡ }|r9t jp;t j|_| jj|_||_|dd … |_||f|_|rg| jj|_t |¡d |_|dddf|_t  t j¡}	|	 |¡ |	 ¡  t  t j ¡}
|
 |¡ |
 ¡  d S )NÚLr<   rD   g    €„.Aéüÿÿÿr   )!Úutmpr{   rR   Ú	transportÚgetPeerÚhostrV   ÚunpackÚsocketÚ	inet_atonr~   ÚtimeÚintÚ	UtmpEntryÚUSER_PROCESSÚDEAD_PROCESSÚut_typer}   ÚpidÚut_pidÚut_lineÚut_idÚut_tvr   Úut_userÚgethostbyaddrÚut_hostÚ
ut_addr_v6Ú
UtmpRecordÚ	UTMP_FILEÚ	pututlineÚendutentÚ	WTMP_FILE)r   ÚloggedInÚ	ipAddressÚpackedIpÚ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ÚTERMÚSSH_TTY)r|   ÚwinSizeÚmodesr}   Úopenptyre   Úttynamer~   )r   ÚtermÚ
windowSizerª   ÚmasterÚslaver¬   r!   r!   r"   ÚgetPtyÌ   s   


z!SSHSessionForUnixConchUser.getPtyc           	   
   C   sB  | 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
g| j¢R Ž ¡ | 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ú-©ÚusePTYÚ4HrL   )&r~   rb   Úerrorr   r{   r@   rE   rH   r   r|   re   ÚpathÚbasenamerR   r‚   rƒ   rU   r„   ÚportÚgetPtyOwnershiprz   ÚspawnProcessr}   r¦   ÚfcntlÚioctlÚfilenoÚttyÚ
TIOCSWINSZrV   rW   r©   rª   ÚsetModesÚwriteÚoldWriteÚ
_writeHackÚsetTcpNoDelay)	r   Úprotort   r:   ÚhomeDirÚshellÚ	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rD|  ¡  | jj|||| j|||| jpSdd�| _| jre|  ¡  | jre|  ¡  | j jjj d¡ d S )	Nz/bin/shr³   z-crµ   r¶   r   r¸   rL   )r{   r@   rE   rH   r|   rR   r‚   rƒ   rU   r„   r¾   r~   r¿   rz   rÀ   r}   r¦   rª   rÆ   rÊ   )
r   rË   Úcmdrt   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 t  |¡ t  |¡ d S t  |¡ t  |¡ w )Nr<   rD   r   )
re   Ústatr~   r{   r@   rf   rg   ri   rj   Úchown)r   ÚttyGidrt   r:   rq   rr   r!   r!   r"   r¿     s   



ÿz*SSHSessionForUnixConchUser.getPtyOwnershipc           	      C   s  | j }t | ¡ ¡}| jD ]n\}}|tjvrqtj| }t|ƒdkrF|\}}tt|ƒs,qt	t|ƒ}|r<|| |B ||< q|| | @ ||< q|dkrVt	td|› �ƒ|tj
< q|dkrft	td|› �ƒ|tj< qtt|ƒslqt	t|ƒ}t|fƒ|tj |< qt | ¡ tj|¡ d S )Nr<   ÚOSPEEDÚBÚISPEED)r}   rÄ   Ú	tcgetattrrÃ   rª   r   ÚTTYMODESrd   ÚhasattrÚgetattrr×   rÙ   ÚbytesÚCCÚ	tcsetattrÚTCSANOW)	r   r}   ÚattrÚmodeÚ	modeValueÚttyModeÚflagÚttyAttrÚttyvalr!   r!   r"   rÆ     s.   





z#SSHSessionForUnixConchUser.setModesc                 C   s   | j r
| j  ¡  d S d S rA   )r}   Ú
closeStdinr?   r!   r!   r"   ÚeofReceived8  s   ÿz&SSHSessionForUnixConchUser.eofReceivedc              	   C   s’   | j r tj | j d ¡r t | j d ¡d }t | j d d|¡ | jrAz| j d¡ W n tt	fy6   Y nw | j 
¡  |  d¡ | j d¡ d S )Nr<   rD   r   ÚHUPzshell closed)r~   re   r¼   ÚexistsrÔ   rÕ   r}   ÚsignalProcessÚOSErrorr   ÚloseConnectionr¦   rb   rc   )r   ÚttyGIDr!   r!   r"   Úclosed<  s   ÿ

z!SSHSessionForUnixConchUser.closedc                 C   s0   || _ t | j ¡ tjtjdg| j ¢R Ž ¡ d S )Nrº   )	r©   rÁ   rÂ   r}   rÃ   rÄ   rÅ   rV   rW   )r   r©   r!   r!   r"   ÚwindowChangedI  s   *z(SSHSessionForUnixConchUser.windowChangedc                 C   s\   | j dur't | j  ¡ ¡d }|tj@ s'|tj@ r'| jjj 	ddt
|ƒ  ¡ |  |¡ dS )zF
        Hack to send ignore messages when we aren't echoing.
        Nr'   ú é   )r}   rÄ   rÚ   rÃ   ÚECHOÚICANONr{   rR   r‚   Ú
sendIgnorerd   rÈ   )r   rX   râ   r!   r!   r"   rÉ   M  s
   
z%SSHSessionForUnixConchUser._writeHackrA   )rL   )r$   r%   r&   r   rb   r(   r¦   r±   rÐ   rÓ   r¿   rÆ   rê   rñ   rò   rÉ   r!   r!   r!   r"   rx   ž   s    

	!rx   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 rA   )r{   )r   r{   r!   r!   r"   r(   Z  rF   z#SFTPServerForUnixConchUser.__init__c                 C   sr   d|v rd|v rt  ||d |d ¡ d|v rt  ||d ¡ d|v r5d|v r7t  ||d |d f¡ dS dS dS )zl
        NOTE: this function assumes it runs as the logged-in user:
        i.e. under _runAsUser()
        rt   r:   ÚpermissionsÚatimeÚmtimeN)re   rÕ   ÚchmodÚutime©r   r¼   Úattrsr!   r!   r"   Ú	_setAttrs]  s   ÿz$SFTPServerForUnixConchUser._setAttrsc                 C   s&   |j |j|j|jt|jƒt|jƒdœS )N)Úsizert   r:   rù   rú   rû   )Úst_sizeÚst_uidÚst_gidÚst_moder‰   Úst_atimeÚst_mtime©r   Úsr!   r!   r"   Ú	_getAttrsi  s   úz$SFTPServerForUnixConchUser._getAttrsc                 C   s"   | j  ¡ }tj t|jƒt|ƒ¡S rA   )r{   rE   re   r¼   Újoinr   )r   r¼   Úhomer!   r!   r"   Ú_absPaths  s   
z#SFTPServerForUnixConchUser._absPathc                 C   s   i S rA   r!   )r   ÚotherVersionÚextDatar!   r!   r"   Ú
gotVersionw  ó   z%SFTPServerForUnixConchUser.gotVersionc                 C   s   t | |  |¡||ƒS rA   )ÚUnixSFTPFiler  )r   ÚfilenameÚflagsrÿ   r!   r!   r"   ÚopenFilez  ó   z#SFTPServerForUnixConchUser.openFilec                 C   ó   |   |¡}| j tj|¡S rA   )r  r{   rO   re   Úremove)r   r  r!   r!   r"   Ú
removeFile}  ó   
z%SFTPServerForUnixConchUser.removeFilec                 C   s&   |   |¡}|   |¡}| j tj||¡S rA   )r  r{   rO   re   Úrename)r   ÚoldpathÚnewpathr!   r!   r"   Ú
renameFile�  ó   

z%SFTPServerForUnixConchUser.renameFilec                 C   s,   |   |¡}| j tj|ff| j||ffg¡S rA   )r  r{   rO   re   Úmkdirr   rþ   r!   r!   r"   ÚmakeDirectory†  s   
ÿz(SFTPServerForUnixConchUser.makeDirectoryc                 C   s   |   |¡}| j tj|¡ d S rA   )r  r{   rO   re   Úrmdir©r   r¼   r!   r!   r"   ÚremoveDirectoryŒ  s   
z*SFTPServerForUnixConchUser.removeDirectoryc                 C   s   t | |  |¡ƒS rA   )ÚUnixSFTPDirectoryr  r#  r!   r!   r"   ÚopenDirectory�  s   z(SFTPServerForUnixConchUser.openDirectoryc                 C   s:   |   |¡}|r| j tj|¡}n| j tj|¡}|  |¡S rA   )r  r{   rO   re   rÔ   Úlstatr
  )r   r¼   ÚfollowLinksr	  r!   r!   r"   ÚgetAttrs“  s
   

z#SFTPServerForUnixConchUser.getAttrsc                 C   s    |   |¡}| j | j||¡ d S rA   )r  r{   rO   r   rþ   r!   r!   r"   ÚsetAttrs›  s   
z#SFTPServerForUnixConchUser.setAttrsc                 C   r  rA   )r  r{   rO   re   Úreadlinkr#  r!   r!   r"   ÚreadLinkŸ  r  z#SFTPServerForUnixConchUser.readLinkc                 C   s&   |   |¡}|   |¡}| j tj||¡S rA   )r  r{   rO   re   Úsymlink)r   ÚlinkPathÚ
targetPathr!   r!   r"   ÚmakeLink£  r  z#SFTPServerForUnixConchUser.makeLinkc                 C   s   t j |  |¡¡S rA   )re   r¼   Úrealpathr  r#  r!   r!   r"   ÚrealPath¨  s   z#SFTPServerForUnixConchUser.realPathc                 C   ó   t ‚rA   ©ÚNotImplementedError)r   ÚextNamer  r!   r!   r"   ÚextendedRequest«  r  z*SFTPServerForUnixConchUser.extendedRequestN)r$   r%   r&   r(   r   r
  r  r  r  r  r  r!  r$  r&  r)  r*  r,  r0  r2  r7  r!   r!   r!   r"   rø   X  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r#|t@ dkr#tj}|t@ tkr2|t@ tkr2tj}|t@ tkr=|tjO }|t	@ t	krH|tj
O }|t@ tkrS|tjO }|t@ tkr^|tjO }d|v rj|d }|d= nd}|j tj|||¡}|r�|j |j||¡ || _d S )Nr   rù   iÿ  )Úserverr   r   re   ÚO_RDONLYÚO_WRONLYÚO_RDWRr   ÚO_APPENDr   ÚO_CREATr   ÚO_TRUNCr   ÚO_EXCLr{   rO   Úopenr   Úfd)r   r8  r  r  rÿ   Ú	openFlagsrã   rA  r!   r!   r"   r(   ±  s0   




zUnixSFTPFile.__init__c                 C   s   | j j tj| j¡S rA   )r8  r{   rO   re   ÚcloserA  r?   r!   r!   r"   rC  Ì  r  zUnixSFTPFile.closec                 C   ó,   | j j tj| j|dfftj| j|ffg¡S r   )r8  r{   rO   re   ÚlseekrA  Úread)r   ÚoffsetÚlengthr!   r!   r"   Ú	readChunkÏ  ó    ÿzUnixSFTPFile.readChunkc                 C   rD  r   )r8  r{   rO   re   rE  rA  rÇ   )r   rG  rX   r!   r!   r"   Ú
writeChunkÔ  rJ  zUnixSFTPFile.writeChunkc                 C   s    | j j tj| j¡}| j  |¡S rA   )r8  r{   rO   re   ÚfstatrA  r
  r  r!   r!   r"   r)  Ù  s   zUnixSFTPFile.getAttrsc                 C   r3  rA   r4  )r   rÿ   r!   r!   r"   r*  Ý  r  zUnixSFTPFile.setAttrsN)	r$   r%   r&   r(   rC  rI  rK  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 rA   )r8  r{   rO   re   ÚlistdirÚfilesÚdir)r   r8  Ú	directoryr!   r!   r"   r(   â  s   
zUnixSFTPDirectory.__init__c                 C   s   | S rA   r!   r?   r!   r!   r"   Ú__iter__ç  r  zUnixSFTPDirectory.__iter__c                 C   sb   z| j  d¡}W n	 ty   t‚w | jj tjtj	 
| j|¡¡}t||ƒ}| j |¡}|||fS r   )rN  ÚpopÚ
IndexErrorÚStopIterationr8  r{   rO   re   r'  r¼   r  rO  r	   r
  )r   rn   r	  Úlongnamerÿ   r!   r!   r"   Ú__next__ê  s   ÿ

zUnixSFTPDirectory.__next__c                 C   s
   g | _ d S rA   )rN  r?   r!   r!   r"   rC  ÷  rF   zUnixSFTPDirectory.closeN)r$   r%   r&   r(   rQ  rV  ÚnextrC  r!   r!   r!   r"   r%  á  s    r%  )7Ú__doc__rÁ   r,   re   r}   r)   r†   rV   rˆ   rÄ   Úzope.interfacer   Útwisted.conchr   Útwisted.conch.avatarr   Útwisted.conch.errorr   Útwisted.conch.interfacesr   r   r   Útwisted.conch.lsr	   Útwisted.conch.sshr
   r   r   Útwisted.conch.ssh.filetransferr   r   r   r   r   r   Útwisted.credr   Útwisted.internet.errorr   Útwisted.loggerr   Útwisted.pythonr   Útwisted.python.compatr   r�   ÚImportErrorÚIRealmr   r   rx   rø   r  r%  ÚregisterAdapterr!   r!   r!   r"   Ú<module>   sV    ÿi :V1ÿ