
    hQG                        d dl mZ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
mZ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mZ dd
lmZ ddlmZ ddlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ erddl,m-Z- ere.Z/ G d de      Z0 G d de      Z1 G d de      Z2 G d de      Z3	 d dlm4Z4  G d de3e4      Z5 G d de6      Z7d Z8y#  Y xY w)    )print_functionunicode_literalsN)AuthenticationFailedDummyAuthorizer)AbstractedFSFilesystemError)
FTPHandler)IOLoop)	FTPServer   )PY2TYPE_CHECKING)VFS)bos)FN_EMB
VF_CAREFULDaemonODictPebkacexclude_dotfilesfsencipnormpybinrelchkrunhooksanitize_fn
set_fpermsvjoinwunlink)SvcHubc                         e Zd Zd fd	Z xZS )FSEc                 :    t         t        |   |       || _        y N)superr   __init__severity)selfmsgr'   	__class__s      C/jellyfin/media/venv/lib/python3.12/site-packages/copyparty/ftpd.pyr&   zFSE.__init__/   s    ot-c2     r   )__name__
__module____qualname__r&   __classcell__r*   s   @r+   r"   r"   .   s    ! !r,   r"   c                   J     e Zd Z fdZd Zd Zd Zd	dZd Zd Z	d Z
 xZS )
FtpAuthc                 8    t         t        |           || _        y r$   )r%   r4   r&   hub)r(   r6   r*   s     r+   r&   zFtpAuth.__init__5   s    gt%'r,   c                 j   dj                  ||      |_        d|_        |j                  d   }|j	                  d      r|dd  }t        |      }| j                  j                  }||v rC||   t        j                         z
  }|dk  rt        j                  d       ||= nt        d      | j                  j                  }| j                  j                  }d}	|dk7  r]d	}	|j                  r	|d
|g}
n||f}
|
D ]=  }|j                  j!                  |j"                  j%                  |      d	      }|s;|}	 n |j&                  r-|	dk(  r(|j(                  |j*                  j-                  |         }	|	rJ|j.                  j0                  j!                  |	      s|j.                  j2                  j!                  |	      s| j                  j4                  }|j6                  r|j9                  ||j                        \  }}|rt        j:                  d       |||<   	 || j                  j<                  j>                  j                  |<   | j                  j<                  j>                  xj@                  dz  c_         t        d      t        d      |	x|_        |_        y #  Y t        d      xY w)Nz{}:{}*r   ::ffff:   zclient unbannedbanned	anonymous :z client banned: invalid passwordsr   zAuthentication failed.)!formatusernameunameaddr
startswithr   r6   banstimelogginginfor   argsasrv	usernamesiacctgetahhashipuipu_iuipu_nmmapvfsareadawritegpwdlimbonkwarningbrokerhttpsrvnban)r(   r@   passwordhandleriprD   rtrH   rI   rA   altszsgrX   s                 r+   validate_authenticationzFtpAuth.validate_authentication9   s=    #>>(H=\\!_==#ABBBZxx}}:bDIIK'BAv./H*844xx}}xx}}{"E~~#+X67) ZZ^^DGGLL$4b9E	 88KK 34ETXX^^//6$((//:M:Me:TAuu66"g&6&67bOO$FG#DH;?//44R8//4494 ''?@@&'?@@+00(&'?@@s   A J$ $J2c                      y)N/ r(   r@   s     r+   get_home_dirzFtpAuth.get_home_dirr   s    r,   c                 j    | j                   j                  }||j                  v xs ||j                  v S r$   )r6   rI   acctrK   )r(   r@   rI   s      r+   has_userzFtpAuth.has_useru   s,    xx}}499$>DJJ(>>r,   c                      y)NTrg   )r(   r@   permpaths       r+   has_permzFtpAuth.has_permy   s    r,   c                      y)N
elradfmwMTrg   rh   s     r+   	get_permszFtpAuth.get_perms|   s    r,   c                 $    dj                  |      S )Nzsup {})r?   rh   s     r+   get_msg_loginzFtpAuth.get_msg_login   s    x((r,   c                      y)Ncyarg   rh   s     r+   get_msg_quitzFtpAuth.get_msg_quit   s    r,   r$   )r.   r/   r0   r&   rd   ri   rl   rp   rs   ru   rx   r1   r2   s   @r+   r4   r4   4   s,    71r?)r,   r4   c                       e Zd Zd Zdd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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)FtpFsc                 V   || _         || _        |j                  | _        |j                  | _        |j                  | _        d| _        d| _        dx| _        x| _        | _	        dx| _
        x| _        | _        dx| _        | _        | j                  | _        | j#                  d       y )Nrf   z/var/lib/emptyF.)hcmd_channelr6   rH   rA   cwdrootcan_read	can_writecan_move
can_deletecan_get	can_upget	can_admincan_dotlistdirlistdirinfochdir)r(   r   r~   s      r+   r&   zFtpFs.__init__   s     &OO$$	 &&
$	9>>>:???$,(--<<

3r,   c                 >    | j                   j                  d||       y )Nftpd)r6   log)r(   r)   cs      r+   r   z	FtpFs.log   s    VS!$r,   c                 j   	 |j                  dd      j                  d      }t        j                  j	                  |      \  }}t        |      r3t        j                  d|       d}t        |j                  |      d      t        |xs dd      }t        ||      }| j                  j                  j                  j                  || j                   ||||      \  }	}
|r|j#                         t$        v r| j&                  j                   |	j(                  j*                  vr`d|	j,                  vrRd|z   }t        ||      }| j                  j                  j                  j                  || j                   ||||      \  }	}
|	j.                  sd	}t        |j                  |            d
|	j,                  v sd|	j,                  v r|	j1                  |
      }|	j3                  |      }d}|st        |j                  |      d      |j5                  d| j&                  j                         \  }}}}}}}}|r|r|r|r|r|r|r|st        |j                  |      d      t        j                  j7                  |	j.                  |
      |	|
fS # t8        $ r}t        t;        |            d }~ww xY w)N\rf   zmalicious vpath: %szUnsupported characters in [{}]r   r=   wo_up_readme_wo_zNo filesystem mounted at [{}]xdevxvolzPermission denied in [{}])replacestriposro   splitr   rF   rY   r"   r?   r   r   r6   rI   rS   rL   rA   lowerr   r}   axsureadflagsrealpath	canonicalchk_ap
can_accessjoinr   str)r(   vpathrwmdrdfntrS   remapavfscrcwcmcd_exs                      r+   v2az	FtpFs.v2a   s'   &	MM$,2237EWW]]5)FBbz 5u=4!((5/1--RX2r*B"bMExx}}((,,UDJJ1aKHCHHJ&(FFLL5"#))3b[b"88==,,00

Aq!QOS<<3!((5/**"f		&9]]3'zz"~/ahhuoq11-1__R-N*BB1aR1R1R1Rahhuoq1177<<c2C<< 	c"g,	s   JJ 	J2J--J2c                 |    | j                  t        j                  j                  | j                  |      ||||      S r$   )r   r   ro   r   r   )r(   r   r   r   r   r   s         r+   rv2az
FtpFs.rv2a   s.     xxTXXu5q!QBBr,   c                     |S r$   rg   )r(   ftppaths     r+   ftp2fszFtpFs.ftp2fs   s    r,   c                     |S r$   rg   )r(   fspaths     r+   fs2ftpzFtpFs.fs2ftp   s    r,   c                 N    d|v r!d|v s|j                  d      rt        dd      y)Nz/.hist/z/up2k.z/dir.txtz Access to this file is forbiddenr   T)endswithr"   r(   ro   s     r+   	validpathzFtpFs.validpath   s.    44==#<<a@@r,   c                    d|v }d|v xs
 d|v xs d|v }| j                  |||      \  }}}| j                  |       |r9	 t        j                  |      }t	        j                         |j
                  z
  }	d}
|r
r	dk\  r|	| j                  j                  k  rd}nG| j                  j                  s| j                  j                  rd}n	 | j                  |dddd       d}|st        d	      t        | j                  |t               t        t        |      || j                  j                         }|r$d
|j"                  v rt%        ||j"                         |S #  d}
d}	Y xY w#  d}Y xY w)Nr   r   a+TFr   zFile already existsfperms)r   r   r   statrE   st_mtimerH   ftp_wtno_del	ftp_no_owr"   r   r   r   openr   iobufr   r   )r(   filenamemoder   r   r   rS   r   sttdneed_unlinkdo_itrets                r+   r   z
FtpFs.open   sP   4K4K53$;5#+YYxA.
CrXXb\YY[2;;."
 RxB$))"2"22!!TYY%8%8"IIhtUDA E /00DHHb*-59dDIIOO4SYY&sCII&
;#"!Es    8E E) E&)E/c           	      l   t        | j                  |      }| j                  j                  j                  j                  || j                  dd      \  }}|j                  |      }	 t        j                  |      }t        j                  |j                        s
t               	 |j                  ||      }|st        dd      || _        |j                  d| j                   j                        \  | _        | _        | _        | _        | _        | _        | _        | _        y #  t        d      xY w)NFNo such file or directoryzPermission deniedr   r=   )r   r   r6   rI   rS   rL   rA   r   r   r   S_ISDIRst_mode	Exceptionr"   r   r   r}   r   r   r   r   r   r   r   r   )r(   ro   nwdrS   r   r   r   r   s           r+   r   zFtpFs.chdir  s    488T"88==$$((djj%GS]]3	3"B<<

+k! , zz"b!)1-- OOB-		
MNMOLNNL#	3122s   (>D& &D3c                 t    | j                  |d      \  }}}t        j                  ||j                         y )NTr   )vf)r   r   makedirsr   )r(   ro   r   rS   r   s        r+   mkdirzFtpFs.mkdir,  s,    YYttY,
CRCII&r,   c                    t        | j                  |      }	 | j                  |dd      \  }}}t        j                  j                  |      st        dd      |j                  || j                  | j                  j                   ddgddggd      \  }}}|D 	cg c]  }	|	d   	 }
}	|
j                  |j                                | j                  st        |
      }
|
j                          |
S c c}	w # t         $ r}t#        |dd      r |j%                  d      rg cY d }~S g }| j&                  j(                  j*                  j,                  j/                         D ]  }d|j0                  v s|j0                  s	 | j&                  j(                  j*                  j3                  |j0                  | j                  dd       |j5                  |j0                         #  Y xY w |j                          |cY d }~S d }~ww xY w)	NTFr   r   )throwr   r'   rf   )r   r   r   r   ro   isdirr"   lsrA   rH   
no_scandirextendkeysr   r   sortr   getattrr   r6   rI   rS   all_volsvaluesr   rL   append)r(   ro   r   r   rS   r   fsrootvfs_ls1vfs_virtxvfs_lsr   r   vns                 r+   r   zFtpFs.listdir0  s   TXXt$*	88E47LBS88>>"%5q99(+

II(((. )/ )%FGX %,,qad,F,MM(--/*<<)&1KKMM -  	r:q){{3	 Chhmm''00779 "((?"((HHMM%%))"((DJJeLJJrxx( HHJJ-	sW   BC8 C3)A	C8 3C8 8
H H"H(AHA!G#"H#G'%H<HHc                     | j                  |d      d   }	 t        j                  |       y # t        $ r(}|j                  t        j
                  k7  r Y d }~y d }~ww xY w)NT)r   r   )r   r   rmdirOSErrorerrnoENOENT)r(   ro   r   es       r+   r   zFtpFs.rmdir^  sQ    YYttY$Q'	IIbM 	ww%,,& '	s   . 	AAAc                 n   | j                   j                  rt        d      t        | j                  |      j                  d      }	 | j                  j                  j                  | j                  | j                  j                  |gg dd       y # t        $ r}t        t        |            d }~ww xY w)Nz/The delete feature is disabled in server configrf   F)rH   r   r"   r   r   lstripr6   up2k	handle_rmrA   r}   cli_ipr   r   )r(   ro   vpr   s       r+   removezFtpFs.removef  s    99GHH$((D!((-	HHMM##DJJtRPUV 	c"g,	s   A	B 	B4B//B4c                    | j                   s"t        d| j                  j                  z         | j                  j
                  rt        d      t        | j                  |      j                  d      }t        | j                  |      j                  d      }	 | j                  j                  j                  | j                  | j                  j                  ||       y # t        $ r}t        t        |            d }~ww xY w)NzNot allowed for user z4The rename/move feature is disabled in server configrf   )r   r"   r}   rA   rH   no_mvr   r   r   r6   r   	handle_mvr   r   r   )r(   srcdstsvpdvpr   s         r+   renamezFtpFs.renamep  s    }}-<==99??LMM488S!((-488S!((-	HHMM##DJJsCH 	c"g,	s   AC" "	D+C??Dc                      y r$   rg   )r(   ro   r   s      r+   chmodzFtpFs.chmod~  s    r,   c                 6   	 | j                  |d      d   }t        j                  |      S # t        $ rb}|j                  r | j                  |      d   }t        j                  |      }t        j
                  |j                        s |cY d }~S d }~ww xY w)NT)r   r   )r   r   r   r"   r'   r   r   )r(   ro   r   r   r   s        r+   r   z
FtpFs.stat  s}    	44(+B88B< 		{{4#B"B<<

+I		s   *- 	BABBBc                 ^    | j                  |d      d   }t        j                  |||f      S )NTr   r   )r   r   utime)r(   ro   timevalr   s       r+   r  zFtpFs.utime  s/    YYttY$Q'yygw/00r,   c                 T    | j                  |      d   }t        j                  |      S Nr   )r   r   r   r(   ro   r   s      r+   lstatzFtpFs.lstat  s"    YYt_Qxx|r,   c                     	 | j                  |      }t        j                  |j                        S # t        $ r}t	        |dd      r Y d }~yd }~ww xY w)Nr'   r   F)r   S_ISREGr   r   r   r(   ro   r   r   s       r+   isfilezFtpFs.isfile  sI    	4B<<

++ 	r:q)		   /2 	AAAc                 h    | j                  |      d   }t        j                  j                  |      S r  )r   r   ro   islinkr  s      r+   r  zFtpFs.islink  s'    YYt_Qxxr""r,   c                     	 | j                  |      }t        j                  |j                        S # t        $ r}t	        |dd      r Y d }~yd }~ww xY w)Nr'   r   T)r   r   r   r   r   r  s       r+   r   zFtpFs.isdir  sI    	4B<<

++ 	r:q)		r  c                 h    | j                  |      d   }t        j                  j                  |      S r  )r   r   ro   getsizer  s      r+   r  zFtpFs.getsize  )    YYt_Qxx##r,   c                 h    | j                  |      d   }t        j                  j                  |      S r  )r   r   ro   getmtimer  s      r+   r  zFtpFs.getmtime  s)    YYt_Qxx  $$r,   c                     |S r$   rg   r   s     r+   r   zFtpFs.realpath  s    r,   c                 h    | j                  |      d   }t        j                  j                  |      S r  )r   r   ro   lexistsr  s      r+   r   zFtpFs.lexists  r  r,   c                      yNr   rg   )r(   uids     r+   get_user_by_uidzFtpFs.get_user_by_uid      r,   c                      yr"  rg   )r(   gids     r+   get_group_by_uidzFtpFs.get_group_by_uid  r%  r,   Nr-   )FFFF)r.   r/   r0   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   r$  r(  rg   r,   r+   rz   rz      s    &% .f C(T.8',\1#$%$r,   rz   c                   2     e Zd ZeZd fd	ZddZd Z xZS )
FtpHandlerc                 T   t         j                  | _        t         j                  | _        d| _        t        rt        j                  | |||       nt        t         |   |||       | j                  }|j                  d      r|dd  }| j                  j                  rS| j                  j                  j                  |      s.t        j                  d|       d| _        |j                          y || _        i | _        | j$                  D cg c]	  }|dvs| c}| _        y c c}w )Nr8   r9   r:   zclient rejected (--ftp-ipa): %sF)CWDXCWD)r*  r6   rH   rA   r   r	   r&   r%   	remote_iprC   
ftp_ipa_nmrR   rF   rY   	connectedcloser   vfs_maplog_cmds_list)r(   connserverioloopcipr   r*   s         r+   r&   zFtpHandler.__init__  s    NN__	
dFF;*d,T66Bnn>>)$ab'C99		(<(<(@(@(EOO=sC"DNJJL  *.););XAq?WaXXs   	D%D%c                 X   t        | j                  j                  |      j                  d      }| j                  j	                  |d      \  }}}|| j
                  |<   |j                  j                  d      }|rt        d d | j                  j                  d|||d| j                  | j                  j                  j                  j                  || j                        dd| j                  t!        j                          d      st#        d      t%        j&                  | ||      }|S )	Nrf   Tr   xbuzxbu.ftpdr=   r   z#Upload blocked by xbu server config)r   fsr   r   r   r2  r   rL   r   r6   r   rA   rI   rS   rs   r   rE   r"   r	   ftp_STOR)	r(   filer   r   r   rS   r   r9  r   s	            r+   r;  zFtpHandler.ftp_STOR  s    $''++t$++C0ww{{2{.CRiimmE"wHHMMJJHHMM''DJJ7KKIIK
" ;<< !!$d3
r,   c           
      b   |j                  dd      }| j                  j                  |d       }|rt        j                  j                  |      \  }}	| j                  j                  j                  j                  || j                  dd      \  }
}|
j                  |      \  }
}| j                  j                  j                  |
j                  |
j                  |
j                   ||	| j"                  t%        j$                         | j                         t'        j(                  | ||||||      S )Nzutf-8r   FT)decoder2  popr   ro   r   r6   rI   rS   rL   rA   get_dbvr   	hash_filer   r   r   r   rE   r	   log_transfer)r(   cmdr   receive	completedelapsedbytesr   r   r   rS   r   s               r+   rB  zFtpHandler.log_transfer  s     __Wi0\\b$'WW]]2&FBxx}}((,,RUDIHC{{3'HCHHMM##						

	 &&#x)We
 	
r,   r$   r   )	r.   r/   r0   rz   abstracted_fsr&   r;  rB  r1   r2   s   @r+   r*  r*    s    M
Y8<
r,   r*  )TLS_FTPHandlerc                       e Zd Zy)SftpHandlerN)r.   r/   r0   rg   r,   r+   rK  rK  *  s    r,   rK  c                       e Zd Zd Zy)Ftpdc                    || _         |j                  | _        g }| j                  j                  r+|j                  t        | j                  j                  g       | j                  j
                  rW	 t        }| j                  j                  _        d|_        d|_        |j                  || j                  j
                  g       |D ]Z  }|\  }}|xt        _         |_         |j                  xt        _        |_        t!        |      xt        _        |_        | j                  j$                  r| j                  j$                  j'                  d      D cg c]  }t)        |       c}\  }	}
| j                  j                  rN| j                  j
                  r8t)        |
|	z
  dz        }|| j                  j                  k(  r|	|z   }
n|	|dz   z  }	t+        t-        |	|
dz               |_        | j                  j0                  s@| j                  j0                  |_        ] t5        j6                  d      }|j9                  | j                  j:                  rt4        j<                  nt4        j>                         | j                  j@                  }d|v r|j                  d       |D cg c]  }|jC                  d	      r| }}| j                  jD                  r|D cg c]	  }d
|vs| }}|s|jG                  d       y t+        tI        jJ                  |            }tM               }|D ]%  }|D ]  \  }}	 tO        |t)        |      f||         ' tQ        |jR                  d       y #  d}t        |j                  t                     t        j                  d       Y 7xY wc c}w c c}w c c}w #  |dk7  sd|vr Y xY w)NzZ
ftps requires pyopenssl;
please run the following:

  {} -m pip install --user pyopenssl
r   T-   	pyftpdlibz::z0.0.0.0)zunix:zfd:r>   z0cannot start ftp-server; no compatible IPs in -iftp)*r6   rH   rR  r   r*  ftpsrK  printr?   r   sysexitcertcertfiletls_control_requiredtls_data_requiredr4   
authorizerftp_prr   intlistrangepassive_portsftp_natmasquerade_addressrF   	getLoggersetLevelftpvDEBUGINFOirC   ftp4fatalr   fromkeysr
   r   r   loop)r(   r6   hsh1r   h_lph2lpr   p1p2r   lgripsr6  r_   r}   s                    r+   r&   zFtpd.__init__2  s   HH	99==IIz499==1299>>  ))..BK&*B##'B IIr499>>*+ 	:DFB&))JNRV(+0JObg4;CL@J!BMyy*.))*:*:*@*@*EFQ#a&FB99==TYY^^R"WM*ATYY]]*!Va!e#'b"q&(9#: yy  (,		(9(9%'	:* ,diinnW]]',,Giikk3;JJy!DQQ\\2B%CqDD99>>!2S\12C2IIHI5>>#&' 	B 2r3r7mQ7	 	v{{E"wuahhuo& G* E 3Y$c/ +:s6   3M6 N32N8	N8)	N=3N=O67N0ON)r.   r/   r0   r&   rg   r,   r+   rM  rM  1  s    E#r,   rM  c                     t         j                  j                  | |j                  dd            }t         j                  j	                  |      j                  dd      S )Nr   rf   )r   ro   r   r   normpath)rr  rs  r   s      r+   r   r   z  sC    
RD#./A77A&&tS11r,   )9
__future__r   r   argparser   rF   r   r   rU  rE   pyftpdlib.authorizersr   r   pyftpdlib.filesystemsr   r   pyftpdlib.handlersr	   pyftpdlib.ioloopr
   pyftpdlib.serversr   r&   r   r   authsrvr   r   utilr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   svchubr    xranger_  r"   r4   rz   r*  rI  rK  objectrM  r   rg   r,   r+   <module>r     s    7    	  
  G ? ) # ' (      $ E!/ !Oo Od}L }@
^
 ^
B	1j. F#6 F#R2[	s   6C C