U
    W[?                     @   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 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 m!Z!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z,m-Z- zddl.Z.W n e/k
r.   dZ.Y nX ee$j0G dd dZ1G dd deZ2ee G dd dZ3ee!G dd dZ4ee"G dd dZ5G dd dZ6e(7e4e2ej! e(7e3e2ej  dS )z
A UNIX SSH server.
    N)implementer)ttymodes)	ConchUser)
ConchError)lsLine)session
forwardingfiletransfer)FXF_READ	FXF_WRITE
FXF_APPEND	FXF_CREAT	FXF_TRUNCFXF_EXCL)ISessionISFTPServer	ISFTPFile)portal)ProcessExitedAlready)
componentslog)	_bytesChrnativeStringc                   @   s   e Zd Zdd ZdS )UnixSSHRealmc                 G   s   t |}|d ||jfS Nr   )UnixConchUserlogout)selfusernameZmindZ
interfacesuser r    4/usr/lib/python3/dist-packages/twisted/conch/unix.pyrequestAvatar+   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 ]\}}}}||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grpZgetgrallappendotherGroups	listenersZchannelLookupupdater   Z
SSHSessionr   ZopenConnectForwardingClientZsubsystemLookupr	   ZFileTransferServer)r   r   lZ	groupnameZpasswordgidZuserlistr    r    r!   r'   3   s"    
zUnixConchUser.__init__c                 C   s   | j dd S )N      r*   r   r    r    r!   getUserGroupIdE   s    zUnixConchUser.getUserGroupIdc                 C   s   | j S N)r-   r5   r    r    r!   getOtherGroupsI   s    zUnixConchUser.getOtherGroupsc                 C   s
   | j d S )N   r4   r5   r    r    r!   
getHomeDirM   s    zUnixConchUser.getHomeDirc                 C   s
   | j d S )N   r4   r5   r    r    r!   getShellQ   s    zUnixConchUser.getShellc                 C   s   t |\}}ddlm} z*| j|j|t | j||ft j|d}W n   Y dS X || j	||f< |dkr|
 d }dtd|fS dS d S )Nr   reactor)Z	interfacer2      z>L)r   unpackGlobal_tcpip_forwardtwisted.internetr>   
_runAsUserZ	listenTCPZSSHListenForwardingFactoryconnZ SSHListenServerForwardingChannelr.   getHoststructpack)r   data
hostToBind
portToBindr>   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   r?   )r   r@   r.   getrB   stopListening)r   rG   rH   rI   rJ   r    r    r!   global_cancel_tcpip_forwardk   s    z)UnixConchUser.global_cancel_tcpip_forwardc                 C   s:   | j  D ]}| |j q
td| jt| j f  d S )Nzavatar %s logging out (%i))r.   valuesrB   rM   r   msgr   len)r   rJ   r    r    r!   r   u   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 pd}t|	dkr|	d pi }|
||}qW 5 t d t d t | t | t | X |S )Nr   r?   r    r2   )osgeteuidgetegid	getgroupsr6   setegidseteuid	setgroupsr8   iter	TypeErrorrQ   )r   fargskweuidegidgroupsuidr1   ifuncrr    r    r!   rB   ~   s2    







zUnixConchUser._runAsUserN)r#   r$   r%   r'   r6   r8   r:   r<   rK   rN   r   rB   r    r    r    r!   r   1   s   
	r   c                   @   sh   e Zd 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   r=   PATHz/bin:/usr/bin:/usr/local/bin)rA   r>   _reactoravatarenvironptyptyTuple)r   rh   r>   r    r    r!   r'      s    
z#SSHSessionForUnixConchUser.__init__r?   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Lr2   r9   g    .Ar   )!utmprh   rC   	transportgetPeerhostrE   ZunpacksocketZ	inet_atonrk   timeintZ	UtmpEntryZUSER_PROCESSZDEAD_PROCESSZut_typerj   pidZut_pidZut_lineZut_idZut_tvr   Zut_userZ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 )NZTERMZSSH_TTY)ri   winSizemodesrj   openptyrR   ttynamerk   )r   ZtermZ
windowSizer~   ZmasterZslaver   r    r    r!   getPty   s    


z!SSHSessionForUnixConchUser.getPtyc           	   
   C   s8  | j std td| j \}}| j }| j }| jj| j	d< || j	d< || j	d< t
j|}| jjjj }| jjjj }d|j|j|jf | j	d< |   | jj||d|f 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 ptyZUSERHOMEZSHELL%s %s %s
SSH_CLIENTz-%sZusePTY4Hr?   )r   )&rk   r   rP   r   rh   r6   r:   r<   r   ri   rR   pathbasenamerC   ro   rp   rD   rq   portgetPtyOwnershiprg   spawnProcessrj   r|   fcntlioctlfilenotty
TIOCSWINSZrE   rF   r}   r~   setModeswriteoldWrite
_writeHacksetTcpNoDelay)	r   protora   r1   homeDirshellZ	shellExecpeerrq   r    r    r!   	openShell   sJ    




    
    

z$SSHSessionForUnixConchUser.openShellc           
   
   C   s   | j  \}}| j  }| j  p$d}|| jd< |d|f}| j jjj }| j jjj }	d|j	|j
|	j
f | jd< | jr|   | jj|||| j|||| jpdd| _| jr|   | jr|   | j jjjd d S )	Nz/bin/shr   z-cr   r   r   r   r?   )rh   r6   r:   r<   ri   rC   ro   rp   rD   rq   r   rk   r   rg   r   rj   r|   r~   r   r   )
r   r   cmdra   r1   r   r   Zcommandr   rq   r    r    r!   execCommand   s:    


        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 )Nr2   r9   r   )
rR   statrk   rh   r6   rS   rT   rV   rW   chown)r   ZttyGidra   r1   r^   r_   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rt	td|f |tj
< q|dkrt	td|f |tj< qtt|sqt	t|}t||tj |< qt| tj| d S )Nr2   OSPEEDzB%sISPEED)rj   r   	tcgetattrr   r~   r   ZTTYMODESrQ   hasattrgetattrr   r   chrZCCZ	tcsetattrZTCSANOW)	r   rj   attrmodeZ	modeValueZttyModeflagZttyAttrZttyvalr    r    r!   r     s.    





z#SSHSessionForUnixConchUser.setModesc                 C   s   | j r| j   d S r7   )rj   Z
closeStdinr5   r    r    r!   eofReceived0  s    z&SSHSessionForUnixConchUser.eofReceivedc              	   C   s   | j r@tj| j d r@t| j d d }t| j d d| | jrz| jd W n tt	fk
rn   Y nX | j
  | d td d S )Nr2   r9   r   ZHUPzshell closed)rk   rR   r   existsr   r   rj   ZsignalProcessOSErrorr   ZloseConnectionr|   r   rP   )r   ZttyGIDr    r    r!   closed5  s    

z!SSHSessionForUnixConchUser.closedc                 C   s,   || _ t| j tjtjd| j   d S )Nr   )r   )	r}   r   r   rj   r   r   r   rE   rF   )r   r}   r    r    r!   windowChangedC  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.
        Nr&       )rj   r   r   r   ZECHOZICANONrh   rC   ro   Z
sendIgnorerQ   r   )r   rG   r   r    r    r!   r   J  s
    
z%SSHSessionForUnixConchUser._writeHack)N)r?   )r#   r$   r%   r'   r|   r   r   r   r   r   r   r   r   r   r    r    r    r!   re      s   


re   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 r7   )rh   )r   rh   r    r    r!   r'   X  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()
        ra   r1   permissionsatimemtimeN)rR   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)sizera   r1   r   r   r   )st_sizest_uidst_gidst_modert   st_atimest_mtimer   sr    r    r!   	_getAttrsi  s    z$SFTPServerForUnixConchUser._getAttrsc                 C   s"   | j  }tjt|jt|S r7   )rh   r:   rR   r   joinr   )r   r   homer    r    r!   _absPatht  s    
z#SFTPServerForUnixConchUser._absPathc                 C   s   i S r7   r    )r   ZotherVersionextDatar    r    r!   
gotVersiony  s    z%SFTPServerForUnixConchUser.gotVersionc                 C   s   t | | |||S r7   )UnixSFTPFiler   )r   filenameflagsr   r    r    r!   openFile}  s    z#SFTPServerForUnixConchUser.openFilec                 C   s   |  |}| jtj|S r7   )r   rh   rB   rR   remove)r   r   r    r    r!   
removeFile  s    
z%SFTPServerForUnixConchUser.removeFilec                 C   s&   |  |}|  |}| jtj||S r7   )r   rh   rB   rR   rename)r   Zoldpathnewpathr    r    r!   
renameFile  s    

z%SFTPServerForUnixConchUser.renameFilec                 C   s,   |  |}| jtj|ff| j||ffgS r7   )r   rh   rB   rR   mkdirr   r   r    r    r!   makeDirectory  s    
z(SFTPServerForUnixConchUser.makeDirectoryc                 C   s   |  |}| jtj| d S r7   )r   rh   rB   rR   rmdirr   r   r    r    r!   removeDirectory  s    
z*SFTPServerForUnixConchUser.removeDirectoryc                 C   s   t | | |S r7   )UnixSFTPDirectoryr   r   r    r    r!   openDirectory  s    z(SFTPServerForUnixConchUser.openDirectoryc                 C   s:   |  |}|r | jtj|}n| jtj|}| |S r7   )r   rh   rB   rR   r   lstatr   )r   r   ZfollowLinksr   r    r    r!   getAttrs  s
    
z#SFTPServerForUnixConchUser.getAttrsc                 C   s    |  |}| j| j|| d S r7   )r   rh   rB   r   r   r    r    r!   setAttrs  s    
z#SFTPServerForUnixConchUser.setAttrsc                 C   s   |  |}| jtj|S r7   )r   rh   rB   rR   readlinkr   r    r    r!   readLink  s    
z#SFTPServerForUnixConchUser.readLinkc                 C   s&   |  |}|  |}| jtj||S r7   )r   rh   rB   rR   symlink)r   ZlinkPathZ
targetPathr    r    r!   makeLink  s    

z#SFTPServerForUnixConchUser.makeLinkc                 C   s   t j| |S r7   )rR   r   realpathr   r   r    r    r!   realPath  s    z#SFTPServerForUnixConchUser.realPathc                 C   s   t d S r7   NotImplementedError)r   ZextNamer   r    r    r!   extendedRequest  s    z*SFTPServerForUnixConchUser.extendedRequestN)r#   r$   r%   r'   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r    r    r!   r   V  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   rR   O_RDONLYO_WRONLYO_RDWRr   O_APPENDr   O_CREATr   O_TRUNCr   O_EXCLrh   rB   openr   fd)r   r   r   r   r   Z	openFlagsr   r   r    r    r!   r'     s0    



zUnixSFTPFile.__init__c                 C   s   | j jtj| jS r7   )r   rh   rB   rR   closer   r5   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 r   )r   rh   rB   rR   lseekr   read)r   offsetZ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   rh   rB   rR   r   r   r   )r   r   rG   r    r    r!   
writeChunk  s
    zUnixSFTPFile.writeChunkc                 C   s    | j jtj| j}| j |S r7   )r   rh   rB   rR   fstatr   r   r   r    r    r!   r     s    zUnixSFTPFile.getAttrsc                 C   s   t d S r7   r   )r   r   r    r    r!   r     s    zUnixSFTPFile.setAttrsN)	r#   r$   r%   r'   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 r7   )r   rh   rB   rR   listdirfilesdir)r   r   Z	directoryr    r    r!   r'     s    zUnixSFTPDirectory.__init__c                 C   s   | S r7   r    r5   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   rh   rB   rR   r   r   r   r   r   r   )r   r[   r   Zlongnamer   r    r    r!   __next__  s    
 
zUnixSFTPDirectory.__next__c                 C   s
   g | _ d S r7   )r   r5   r    r    r!   r     s    zUnixSFTPDirectory.closeN)r#   r$   r%   r'   r   r   nextr   r    r    r    r!   r     s
   r   )8__doc__r   r+   rR   rj   r(   rr   rE   rs   r   Zzope.interfacer   Ztwisted.conchr   Ztwisted.conch.avatarr   Ztwisted.conch.errorr   Ztwisted.conch.lsr   Ztwisted.conch.sshr   r   r	   Ztwisted.conch.ssh.filetransferr
   r   r   r   r   r   Ztwisted.conch.interfacesr   r   r   Ztwisted.credr   Ztwisted.internet.errorr   Ztwisted.pythonr   r   Ztwisted.python.compatr   r   r   rn   ImportErrorZIRealmr   r   re   r   r   r   ZregisterAdapterr    r    r    r!   <module>   s\    
k :f7    