
    ϪfB                       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 	 ddl7Z7 ee*jr                         G d d             Z: G d de      Z; ee       G d d             Z< ee       G d d             Z= ee       G d d             Z> G d d      Z? e4j                  e=e;ej6                          e4j                  e<e;e!j2                         y# e8$ r dZ7Y w xY w) 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                  $    e Zd Z	 	 	 	 	 	 	 	 ddZy)UnixSSHRealmc                    t        |t              st        d      t        |j	                               }|d   ||j
                  fS )Nz5UNIX SSH realm does not authorize anonymous sessions.r   )
isinstancebytesr   UnixConchUserdecodelogout)selfusernamemind
interfacesusers        4/usr/lib/python3/dist-packages/twisted/conch/unix.pyrequestAvatarzUnixSSHRealm.requestAvatar5   s@     (E*UVVX__./!}dDKK//    N)r(   zbytes | Tuple[()]r)   objectr*   zportal._InterfaceItselfreturnzATuple[portal._InterfaceItself, UnixConchUser, Callable[[], None]])__name__
__module____qualname__r-    r.   r,   r    r    3   s.    	0#	0 	0 -		0
 
K	0r.   r    c                  F    e Zd ZddZd Zd Zd Zd Zd Zd Z	ddZ
d	 Zy
)r$   c                   t        j                  |        || _        t        j                  | j                        | _        | j
                  d   g}t        j                         D ]  \  }}}}||v s|j                  |        || _	        i | _
        | j                  j                  t        j                  t        j                   d       | j"                  j                  dt$        j&                  i       y )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userlists          r,   r8   zUnixConchUser.__init__B   s    4  ||DMM2\\!_25,,. 	.Ixh8#	   	 	!!#..!+!G!G	
 	##Wl.M.M$NOr.   c                     | j                   dd S )N      r;   r'   s    r,   getUserGroupIdzUnixConchUser.getUserGroupIdW   s    ||Aa  r.   c                    | j                   S N)r?   rP   s    r,   getOtherGroupszUnixConchUser.getOtherGroupsZ   s    r.   c                     | j                   d   S )N   rO   rP   s    r,   
getHomeDirzUnixConchUser.getHomeDir]       ||Ar.   c                     | j                   d   S )N   rO   rP   s    r,   getShellzUnixConchUser.getShell`   rX   r.   c           	     ~   t        j                  |      \  }}ddlm} 	 | j	                  |j
                  |t        j                  | j                  ||ft         j                        |      }|| j                  ||f<   |dk(  r+|j                         d   }dt        j                  d|      fS y# t        $ r Y yw xY w)Nr   reactor)	interfacerM      z>L)r   unpackGlobal_tcpip_forwardtwisted.internetr^   
_runAsUser	listenTCPSSHListenForwardingFactoryconn SSHListenServerForwardingChannelr@   getHoststructpackBaseException)r'   data
hostToBind
portToBindr^   listeners         r,   global_tcpip_forwardz"UnixConchUser.global_tcpip_forwardc   s    !+!F!Ft!L
J,	!!55II,??
 % ' 	H 8@DNNJ
34Q%--/2
&++dJ777  		s   AB0 0	B<;B<c                    t        j                  |      \  }}| j                  j                  ||fd       }|sy| j                  ||f= | j	                  |j
                         y)Nr   r`   )r   ra   r@   getrc   stopListening)r'   rl   rm   rn   ro   s        r,   global_cancel_tcpip_forwardz)UnixConchUser.global_cancel_tcpip_forward|   s^    !+!F!Ft!L
J>>%%z:&>ENNJ
34../r.   c                    | j                   j                         D ]  }| j                  |j                          | j                  j                  d| j                  t        | j                                y )Nz,avatar {username} logging out ({nlisteners}))r(   
nlisteners)r@   valuesrc   rs   _loginfor(   len)r'   ro   s     r,   r&   zUnixConchUser.logout   s[    --/ 	4HOOH223	4		:]]4>>* 	 	
r.   c                   t        j                         }t        j                         }t        j                         }| j	                         \  }}t        j
                  d       t        j                  d       t        j                  | j                                t        j
                  |       t        j                  |       	 t        |      }	 |D ]A  }	|	d   }
t        |	      dkD  xr |	d   xs d}t        |	      dkD  xr |	d   xs i } |
|i |}C 	 t        j
                  d       t        j                  d       t        j                  |       t        j
                  |       t        j                  |       S # t        $ r	 |||fg}Y w xY w# t        j
                  d       t        j                  d       t        j                  |       t        j
                  |       t        j                  |       w xY w)Nr   r`   r4   rM   )osgeteuidgetegid	getgroupsrQ   setegidseteuid	setgroupsrT   iter	TypeErrorrz   )r'   fargskweuidegidgroupsuidrJ   ifuncrs               r,   rc   zUnixConchUser._runAsUser   s   zz|zz|&&(S


1


1
T((*+


3


3	 QA	 &t1vz*ad0bVaZ(AaD.B$%"%	& JJqMJJqMLL JJtJJt  	 T2A	  JJqMJJqMLL JJtJJts    F AF FFA+HN)r(   strr0   None)r0   r   )r1   r2   r3   r8   rQ   rT   rW   r[   rp   rt   r&   rc   r4   r.   r,   r$   r$   A   s0    P*! 2
r.   r$   c                  `    e Zd Z e       ZddZddZd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zy)SSHSessionForUnixConchUserNc                ^    |ddl m} || _        || _        ddi| _        d| _        d| _        y)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)rb   r^   _reactoravatarenvironptyptyTuple)r'   r   r^   s      r,   r8   z#SSHSessionForUnixConchUser.__init__   s5     ?0 >?r.   c                   t         sy | j                  j                  j                  j                  j	                         j
                  }t        j                  dt        j                  |            \  }| j                  d   dd  }t        j                         }t        |      }t        ||z
  dz        }t        j                         }|xr t         j                  xs t         j                  |_        | j"                  j$                  |_        ||_        |dd  |_        ||f|_        |rC| j                  j.                  |_        t        j2                  |      d   |_        |dddf|_        t        j8                  t         j:                        }	|	j=                  |       |	j?                          t        j8                  t         j@                        }
|
j=                  |       |
j?                          y )NLrM   rV   g    .Ar   )!utmpr   rf   	transportgetPeerhostri   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bs              r,   addUTMPEntryz'SSHSessionForUnixConchUser.addUTMPEntry   sk   KK$$..88@@BGG	mmC)9)9))DE--"12&IIKV!b&C   6T%6%6K$:K:Kxx||bcl2h KK00EM"00;A>EM (!Q2EOODNN+	E	

OODNN+	E	

r.   c                    || j                   d<   || _        || _        t        j                         \  }}t        j                  |      }|| j                   d<   |||f| _        y )NTERMSSH_TTY)r   winSizemodesr   openptyr|   ttynamer   )r'   term
windowSizer   masterslaver   s          r,   getPtyz!SSHSessionForUnixConchUser.getPty   sW    #V!
**U#")Y0r.   c           
        | j                   s&| j                  j                  d       t        d      | j                  j                         \  }}| j                  j                         }| j                  j                         }| j                  j                  | j                  d<   || j                  d<   || j                  d<   t        j                  j                  |      }| j                  j                  j                  j                  j                         }| j                  j                  j                  j                  j!                         }|j"                   d|j$                   d|j$                   | j                  d<   | j'                          | j(                  j+                  ||d| g| j                  |||| j                   	      | _        | j/                          t1        j2                  | j,                  j5                         t6        j8                  t;        j<                  d
g| j>                          | j@                  r| jC                          |j                  jD                  | _#        | jH                  |j                  _"        | j                  j                  j                  j                  jK                  d       y )Nz'tried to get shell without pty, failingzno ptyUSERHOMESHELL 
SSH_CLIENT-usePTY4Hr`   )&r   rx   errorr
   r   rQ   rW   r[   r(   r   r|   pathbasenamerf   r   r   rh   r   portgetPtyOwnershipr   spawnProcessr   r   fcntlioctlfilenotty
TIOCSWINSZri   rj   r   r   setModeswriteoldWrite
_writeHacksetTcpNoDelay)	r'   protor   rJ   homeDirshell	shellExecpeerr   s	            r,   	openShellz$SSHSessionForUnixConchUser.openShell   s   }}IIOOEFX&&;;--/S++((*$$&#{{33V&V %WGG$$U+	{{))33;;={{))33;;=(,		{!DII;a		{%K\"==--_LL== . 	
 	DHHOO%s~~v{{47W$,,7WX::MMO-- $"",,::1=r.   c                   | j                   j                         \  }}| j                   j                         }| j                   j                         xs d}|| j                  d<   |d|f}| j                   j
                  j                  j                  j                         }| j                   j
                  j                  j                  j                         }	|j                   d|j                   d|	j                   | j                  d<   | j                  r| j                          | j                  j                  |||| j                  |||| j                  xs d      | _        | j                  r,| j!                          | j"                  r| j%                          | j                   j
                  j                  j                  j'                  d       y )	Nz/bin/shr   z-cr   r   r   r   r`   )r   rQ   rW   r[   r   rf   r   r   rh   r   r   r   r   r   r   r   r   r   r   r   )
r'   r   cmdr   rJ   r   r   commandr   r   s
             r,   execCommandz&SSHSessionForUnixConchUser.execCommand  sj   ;;--/S++((*$$&3)&V$${{))33;;={{))33;;=(,		{!DII;a		{%K\"==  "==--LL==%A . 	
 ==zz"",,::1=r.   c                (   t        j                  | j                  d         d   }| j                  j	                         \  }}t        j
                         t        j                         }}t        j                  d       t        j                  d       	 t        j                  | j                  d   ||       t        j                  |       t        j                  |       y # t        j                  |       t        j                  |       w xY w)NrM   rV   r   )
r|   statr   r   rQ   r}   r~   r   r   chown)r'   ttyGidr   rJ   r   r   s         r,   r   z*SSHSessionForUnixConchUser.getPtyOwnership  s    q)*1-;;--/SZZ\2::<d


1


1	HHT]]1%sF3JJtJJt JJtJJts   $C% %,Dc                   | j                   }t        j                   |j                               }| j                  D ]  \  }}|t
        j                  vrt
        j                  |   }t        |      dk(  rA|\  }}t        t        |      sQt        t        |      }|r||   |z  ||<   o||   | z  ||<   ||dk(  r%t        t        d|       |t        j                  <   |dk(  r%t        t        d|       |t        j                  <   t        t        |      st        t        |      }t        |f      |t        j                     |<    t        j                   |j                         t        j                  |       y )NrM   OSPEEDBISPEED)r   r   	tcgetattrr   r   r   TTYMODESrz   hasattrgetattrr   r   r#   CC	tcsetattrTCSANOW)	r'   r   attrmode	modeValuettyModeflagttyAttrttyvals	            r,   r   z#SSHSessionForUnixConchUser.setModes+  sF   hh}}ZSZZ\*#zz 	;OD)8,,,''-G7|q  'gsG, g.!%df!4DJ!%dvg!5DJH$#*3!I;#@SZZ H$#*3!I;#@SZZ sG, g.',i\':SVVV$+	;, 	jcjjlCKK6r.   c                R    | j                   r| j                   j                          y y rS   )r   
closeStdinrP   s    r,   eofReceivedz&SSHSessionForUnixConchUser.eofReceivedF  s    88HH! r.   c                   | j                   rut        j                  j                  | j                   d         rIt        j                  | j                   d         d   }t        j
                  | j                   d   d|       | j                  rG	 | j                  j                  d       | j                  j                          | j                  d       | j                  j                  d       y # t        t        f$ r Y Xw xY w)NrM   rV   r   HUPzshell closed)r   r|   r   existsr   r   r   signalProcessOSErrorr   loseConnectionr   rx   ry   )r'   ttyGIDs     r,   closedz!SSHSessionForUnixConchUser.closedJ  s    ==RWW^^DMM!,<=WWT]]1-.q1FHHT]]1%q&188&&u- HH##%a 		~&	 12 s   C1 1DDc                    || _         t        j                  | j                  j	                         t
        j                  t        j                  dg| j                           y )Nr   )	r   r   r   r   r   r   r   ri   rj   )r'   r   s     r,   windowChangedz(SSHSessionForUnixConchUser.windowChangedW  s:    DHHOO%s~~v{{47W$,,7WXr.   c                f   | j                   t        j                  | j                   j                               d   }|t        j                  z  sQ|t        j
                  z  r>| j                  j                  j                  j                  ddt        |      z   z         | j                  |       y)zF
        Hack to send ignore messages when we aren't echoing.
        Nr7       )r   r   r   r   ECHOICANONr   rf   r   
sendIgnorerz   r   )r'   rl   r  s      r,   r   z%SSHSessionForUnixConchUser._writeHack[  sy     88==!23A6D#((?tcjj'8  **55fCI6NOdr.   rS   )r`   )r1   r2   r3   r   rx   r8   r   r   r   r   r   r   r  r  r  r   r4   r.   r,   r   r      sB    8D 41>B>6
76"'Yr.   r   c                  r    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zy)SFTPServerForUnixConchUserc                    || _         y rS   )r   )r'   r   s     r,   r8   z#SFTPServerForUnixConchUser.__init__h  s	    r.   c                    d|v r!d|v rt        j                  ||d   |d          d|v rt        j                  ||d          d|v r$d|v rt        j                  ||d   |d   f       yyy)zl
        NOTE: this function assumes it runs as the logged-in user:
        i.e. under _runAsUser()
        r   rJ   permissionsatimemtimeN)r|   r   chmodutimer'   r   attrss      r,   	_setAttrsz$SFTPServerForUnixConchUser._setAttrsk  sv    
 E>eunHHT5<u6E!HHT5/0e5 0HHTE'NE'N;< !1r.   c                    |j                   |j                  |j                  |j                  t	        |j
                        t	        |j                        dS )N)sizer   rJ   r   r!  r"  )st_sizest_uidst_gidst_moder   st_atimest_mtimer'   ss     r,   	_getAttrsz$SFTPServerForUnixConchUser._getAttrsw  s>    II888899__
 	
r.   c                    | j                   j                         }t        j                  j	                  t        |j                        t        |            S rS   )r   rW   r|   r   joinr   )r'   r   homes      r,   _absPathz#SFTPServerForUnixConchUser._absPath  s7    {{%%'ww||L3\$5GHHr.   c                    i S rS   r4   )r'   otherVersionextDatas      r,   
gotVersionz%SFTPServerForUnixConchUser.gotVersion  s    	r.   c                <    t        | | j                  |      ||      S rS   )UnixSFTPFiler6  )r'   filenameflagsr&  s       r,   openFilez#SFTPServerForUnixConchUser.openFile  s    D$--"95%HHr.   c                x    | j                  |      }| j                  j                  t        j                  |      S rS   )r6  r   rc   r|   remove)r'   r=  s     r,   
removeFilez%SFTPServerForUnixConchUser.removeFile  s+    ==*{{%%bii::r.   c                    | j                  |      }| j                  |      }| j                  j                  t        j                  ||      S rS   )r6  r   rc   r|   rename)r'   oldpathnewpaths      r,   
renameFilez%SFTPServerForUnixConchUser.renameFile  s;    --(--({{%%bii'BBr.   c                    | j                  |      }| j                  j                  t        j                  |ff| j
                  ||ffg      S rS   )r6  r   rc   r|   mkdirr'  r%  s      r,   makeDirectoryz(SFTPServerForUnixConchUser.makeDirectory  sG    }}T"{{%%hh 4>>D%="AB
 	
r.   c                z    | j                  |      }| j                  j                  t        j                  |       y rS   )r6  r   rc   r|   rmdirr'   r   s     r,   removeDirectoryz*SFTPServerForUnixConchUser.removeDirectory  s(    }}T"rxx.r.   c                8    t        | | j                  |            S rS   )UnixSFTPDirectoryr6  rM  s     r,   openDirectoryz(SFTPServerForUnixConchUser.openDirectory  s     t}}T':;;r.   c                    | j                  |      }|r+| j                  j                  t        j                  |      }n*| j                  j                  t        j
                  |      }| j                  |      S rS   )r6  r   rc   r|   r   lstatr2  )r'   r   followLinksr1  s       r,   getAttrsz#SFTPServerForUnixConchUser.getAttrs  sV    }}T"&&rww5A&&rxx6A~~a  r.   c                t    | j                  |      }| j                  j                  | j                  ||       y rS   )r6  r   rc   r'  r%  s      r,   setAttrsz#SFTPServerForUnixConchUser.setAttrs  s*    }}T"t~~tU;r.   c                x    | j                  |      }| j                  j                  t        j                  |      S rS   )r6  r   rc   r|   readlinkrM  s     r,   readLinkz#SFTPServerForUnixConchUser.readLink  s+    }}T"{{%%bkk488r.   c                    | j                  |      }| j                  |      }| j                  j                  t        j                  ||      S rS   )r6  r   rc   r|   symlink)r'   linkPath
targetPaths      r,   makeLinkz#SFTPServerForUnixConchUser.makeLink  s;    ==*]]:.
{{%%bjj*hGGr.   c                ^    t         j                  j                  | j                  |            S rS   )r|   r   realpathr6  rM  s     r,   realPathz#SFTPServerForUnixConchUser.realPath  s     wwd 344r.   c                    t         rS   NotImplementedError)r'   extNamer9  s      r,   extendedRequestz*SFTPServerForUnixConchUser.extendedRequest      !!r.   N)r1   r2   r3   r8   r'  r2  r6  r:  r?  rB  rG  rJ  rN  rQ  rU  rW  rZ  r_  rb  rg  r4   r.   r,   r  r  f  s[    
=
II;C

/<!<9H
5"r.   r  c                  0    e Zd Zd Zd Zd Zd Zd Zd Zy)r<  c                   || _         d}|t        z  t        k(  r|t        z  dk(  rt        j                  }|t        z  t        k(  r|t        z  dk(  rt        j
                  }|t        z  t        k(  r |t        z  t        k(  rt        j                  }|t        z  t        k(  r|t        j                  z  }|t        z  t        k(  r|t        j                  z  }|t        z  t        k(  r|t        j                  z  }|t        z  t        k(  r|t        j                  z  }d|v r	|d   }|d= nd}|j                  j!                  t        j"                  |||      }|r'|j                  j!                  |j$                  ||       || _        y )Nr   r   i  )serverr   r   r|   O_RDONLYO_WRONLYO_RDWRr   O_APPENDr   O_CREATr   O_TRUNCr   O_EXCLr   rc   openr'  fd)r'   rk  r=  r>  r&  	openFlagsr  rt  s           r,   r8   zUnixSFTPFile.__init__  sC   	8x'EI,=,BI9	)eh.>!.CI9	)eh.>(.J		I:+$I9	)#I9	)#I8x'"IE!'Dm$D]]%%bggxDIMM$$V%5%5xGr.   c                ~    | j                   j                  j                  t        j                  | j
                        S rS   )rk  r   rc   r|   closert  rP   s    r,   rw  zUnixSFTPFile.close  s'    {{!!,,RXXtww??r.   c                    | j                   j                  j                  t        j                  | j
                  |dfft        j                  | j
                  |ffg      S Nr   )rk  r   rc   r|   lseekrt  read)r'   offsetlengths      r,   	readChunkzUnixSFTPFile.readChunk  sM    {{!!,,hh&!,-$''69J/KL
 	
r.   c                    | j                   j                  j                  t        j                  | j
                  |dfft        j                  | j
                  |ffg      S ry  )rk  r   rc   r|   rz  rt  r   )r'   r|  rl   s      r,   
writeChunkzUnixSFTPFile.writeChunk  sL    {{!!,,hh&!,-477D//JK
 	
r.   c                    | j                   j                  j                  t        j                  | j
                        }| j                   j                  |      S rS   )rk  r   rc   r|   fstatrt  r2  r0  s     r,   rU  zUnixSFTPFile.getAttrs  s;    KK))"((DGG<{{$$Q''r.   c                    t         rS   rd  )r'   r&  s     r,   rW  zUnixSFTPFile.setAttrs  rh  r.   N)	r1   r2   r3   r8   rw  r~  r  rU  rW  r4   r.   r,   r<  r<    s!    6@



("r.   r<  c                  (    e Zd Zd Zd Zd ZeZd Zy)rP  c                ~    || _         |j                  j                  t        j                  |      | _        || _        y rS   )rk  r   rc   r|   listdirfilesdir)r'   rk  	directorys      r,   r8   zUnixSFTPDirectory.__init__  s,    ]]--bjj)D
r.   c                    | S rS   r4   rP   s    r,   __iter__zUnixSFTPDirectory.__iter__  s    r.   c                p   	 | j                   j                  d      }| j                  j                  j	                  t
        j                  t
        j                  j                  | j                  |            }t        ||      }| j                  j                  |      }|||fS # t        $ r t        w xY wry  )r  poprk  r   rc   r|   rS  r   r4  r  r   r2  
IndexErrorStopIteration)r'   r   r1  longnamer&  s        r,   __next__zUnixSFTPDirectory.__next__  s    	(

q!A ""--bhhTXXq8QRAa|HKK))!,Ex''  	 	 s   B% %B5c                    g | _         y rS   )r  rP   s    r,   rw  zUnixSFTPDirectory.close  s	    
r.   N)r1   r2   r3   r8   r  r  nextrw  r4   r.   r,   rP  rP    s    
	( Dr.   rP  )A__doc__
__future__r   r   r<   r|   r   r9   r   ri   r   r   typingr   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.cred.errorr   twisted.internet.errorr   twisted.internet.interfacesr   twisted.loggerr   twisted.pythonr   twisted.python.compatr   r   ImportErrorIRealmr    r$   r   r  r<  rP  registerAdapterr4   r.   r,   <module>r     se   #  
 	 
 
    
 ( ( & " * * E E # ? ?    * 7 6 ! % .
 V]]
0 
0 
0hI hV Xv v vr [S" S" S"l Y." ." ."b 4 
  |/G/G 
  5}gFVFV W{  Ds   $E E"!E"