
    R7_iZ                     P    S r SSKrSSKrSSKJrJrJrJr  SSKJ	r	   " S S5      r
g)u1   
沙箱配置

定义工具执行的安全限制
    N)ListSetOptionalTuple)Pathc                      \ rS rSrSr1 Skr1 Skr1 Skr/ SQr         S)S\	\
   S	\	\
   S
\\
   S\\
   S\	\
   S\S\S\S\4S jjr\S*S\\   S\4S jj5       r\S*S\	\
   S\\   S\	\
   4S jj5       rS*S\\   S\\   4S jjrS\
S\4S jrS\
S\4S jrS\
S\
S\	\
   4S jrS \
S\
S\4S! jrS*S\
S\\
   S\4S" jjrS\
S\4S# jr\S+S$\
S%\
S\\   SS 4S& jj5       r\S*S%\
S\\   SS 4S' jj5       rS(r g),SandboxConfig   u3   沙箱配置类

定义工具执行的安全边界
>C   [cdcplsmvpsrmshsstrwcawkcatcutenvgitnpmpippwdsedtarteetopzipbashcurldatediffechofindgrepgzipheadkilllesslsofmorenodeopenperlpip3rubysorttailtesttrueuniqwgetchmodfalsemkdirpatchpkillsleeptouchunzipwhichxargsdockergunzipprintfpythonnetstatpython3timeoutwhereisdocker-compose>   gor   cshphpzshr#   fishjavar0   r2   r4   rustcnodejsrH   python2rJ   >   suinitmkfssudochownfdiskpasswdrebootserviceshutdown	systemctldd if=> /dev/rm -rf /	kill -9 1	rm -rf /*chmod 777 /)zrm\s+-rf\s+/zrm\s+-rf\s+\*zsudo\s+zchmod\s+777\s+/Nallowed_directoriesallowed_write_directoriesallowed_commandsblocked_commandsknowledge_executable_dirsmax_file_sizemax_output_sizecommand_timeoutdocker_timeoutc
                     U=(       d    / U l         Ub  UOU R                   U l        U=(       d    U R                  R                  5       U l        U=(       d
    [        5       U l        U=(       d    / U l        X`l        Xpl	        Xl
        Xl        g)u  初始化沙箱配置

Args:
    allowed_directories: 允许读取/访问的目录列表（用于读取、列表等操作）
    allowed_write_directories: 允许写入的目录列表（用于写入操作，如果为None则使用allowed_directories）
    allowed_commands: 允许执行的命令集合
    blocked_commands: 显式禁止的命令集合
    knowledge_executable_dirs: 知识库可执行目录范围（相对 data/）
    max_file_size: 最大文件大小（字节）
    max_output_size: 最大输出大小（字节）
    command_timeout: 普通命令超时时间（秒）
    docker_timeout: Docker 命令超时时间（秒）
N)rh   ri   DEFAULT_ALLOWED_COMMANDScopyrj   setrk   rl   rm   rn   ro   rp   )
selfrh   ri   rj   rk   rl   rm   rn   ro   rp   s
             </Users/yu22x/Desktop/ge/ctf/app/services/ai/tools/sandbox.py__init__SandboxConfig.__init__^   s    2 $7#<" F_Fk)Bqu  rJ  rJ& 0 XD4Q4Q4V4V4X 0 9CE)B)Hb&*..,    defaultreturnc                      SSK Jn  UR                  SU =(       d    0 5      =(       d    U =(       d    0 $ ! [         a    U =(       d    0 s $ f = f)u$   从系统配置中加载沙箱策略r   )SystemConfigai_sandbox_policy)app.models.database.configr}   
get_config	Exception)rz   r}   s     rv   load_policySandboxConfig.load_policy   sG    	!?**+>2NaSZS`^`a 	!=b 	!s   25 AApathsbase_dirc                    / nU =(       d    /  Hh  n [        U5      nUR                  5       (       d  U(       a  X-  R                  5       nOUR                  5       nUR                  [	        U5      5        Mj     U$ ! [
         a     M{  f = f)u$   将相对路径解析为绝对路径)r   is_absoluteresolveappendstrr   )r   r   resolvedppath_objs        rv   _resolve_pathsSandboxConfig._resolve_paths   s     "A7++--( ( 3<<>H'//1HH.    s   A$A<<
B
	B
policyc                    U(       d  gUR                  S5      n[        U[        5      (       a]  U Vs/ s H  oD(       d  M  UR                  5       PM     nnSU;   a	  S1U l        O&[        U R                  5      [        U5      -  U l        UR                  S5      n[        U[        5      (       a7  [        U Vs/ s H  oD(       d  M  UR                  5       PM     sn5      U l        UR                  S5      n[        U[        5      (       aQ  U(       aJ  U R                  Xr5      n[        [        R                  U R                  =(       d    / U-   5      5      U l
        UR                  S5      n	[        U	[        5      (       aQ  U	(       aJ  U R                  X5      n[        [        R                  U R                  =(       d    / U-   5      5      U l        [        UR                  SU R                  5      =(       d    U R                  5      U l        [        UR                  SU R                  5      =(       d    U R                  5      U l        [        UR                  S	U R                  5      =(       d    U R                  5      U l        [        UR                  S
U R                   5      =(       d    U R                   5      U l        gs  snf s  snf )u!   应用策略到当前沙箱实例Nrj   *rk   allowed_read_dirsallowed_write_dirsrm   rn   ro   rp   )get
isinstanceliststriprj   rt   rk   r   dictfromkeysrh   ri   intrm   rn   ro   rp   )
ru   r   r   policy_allowedcmdcleanedpolicy_blocked	read_dirsextra
write_dirss
             rv   apply_policySandboxConfig.apply_policy   s     $67nd++.<Dns{syy{nGDg~),%(+D,A,A(BS\(Q%  $67nd++$'(VRU(V$WD! JJ23	i&&9''	<E'+DMM4;S;S;YWY]b:b,c'dD$ZZ 45
j$''J''
=E-1$--A_A_Aecein@n2o-pD* !OT=O=O!P!fTXTfTfg"6::.?AUAU#V#nZ^ZnZno"6::.?AUAU#V#nZ^ZnZno!&**-=t?R?R"S"jW[WjWjk7 E )Ws   
KK;
K	Kpathc                    U R                   (       d  g [        U5      R                  5       nU R                    H.  n[        U5      R                  5       n UR                  U5          g   g! [         a     M@  f = f! [
         a     gf = f)u   检查路径是否在允许的目录内（用于读取、列表等操作）

Args:
    path: 要检查的路径
    
Returns:
    是否允许
TF)rh   r   r   relative_to
ValueErrorr   ru   r   abs_pathallowed_dirallowed_abss        rv   is_path_allowedSandboxConfig.is_path_allowed   s     ''	Dz))+H#77";/779((5  8  " 
  		<   AA= A,'A= )A= ,
A:6A= 9A::A= =
B
	B
c                    U R                   (       d  g [        U5      R                  5       nU R                    H.  n[        U5      R                  5       n UR                  U5          g   g! [         a     M@  f = f! [
         a     gf = f)u   检查路径是否在允许写入的目录内（用于写入操作）

Args:
    path: 要检查的路径
    
Returns:
    是否允许写入
TF)ri   r   r   r   r   r   r   s        rv   is_write_path_allowed#SandboxConfig.is_write_path_allowed   s     --	Dz))+H#==";/779((5  >  " 
  		r   commandworking_dirc                    / nUR                  5       R                  5       nU(       d  U$ [        U5      S:  a  US   nUS   nSU;   a  [        R                  R                  U5      OUnXpR                  ;   aC  SU;   d,  UR                  S5      (       d  UR                  S5      (       a  UR                  U5        US   nSU;   d,  UR                  S5      (       d  UR                  S5      (       a  UR                  U5        U$ )u  从命令中提取所有可能的可执行文件路径

处理多种情况：
- python3 data/scripts/choice.py → ['data/scripts/choice.py']
- ./data/utils/tool → ['data/utils/tool']
- bash data/scripts/helper.sh arg1 → ['data/scripts/helper.sh']
- node data/scripts/process.js → ['data/scripts/process.js']
- ./data/scripts/executable → ['data/scripts/executable']

Args:
    command: 命令字符串
    working_dir: 工作目录（用于解析相对路径）
    
Returns:
    可执行文件路径列表
   r      /./../)	r   splitlenosr   basenameKNOWN_INTERPRETERS
startswithr   )ru   r   r   r   partsfirstsecondfirst_basenames           rv   _extract_executable_paths'SandboxConfig._extract_executable_paths   s    " %%'L u:?!HE1XF 9<uRWW--e4%N!8!88&=F$5$5d$;$;v?P?PQV?W?WLL( a%<5++D11U5E5Ee5L5LLLry   executable_pathc                     [         R                  R                  U5      (       a  [        U5      R	                  5       nO[        U5      U-  R	                  5       n[        U5      R	                  5       n UR                  U5      n[        U5      R                  S5      nSU;   a  g[        U SS5      nUc"  U R                  5       nUR                  S/ 5      nU(       d  g[        U5      n	U Ha  n
U
R                  5       R                  S5      n
U
(       d  M+  U
S:X  d  U
S:X  a
  SU	;  a    gMA  U	R                  U
S-   5      (       d  X:X  d  Ma    g   g! [         a     gf = f! [         a     gf = f)	u;  检查可执行文件路径是否在允许的目录内

检查可执行文件是否在配置的允许目录范围内，防止路径遍历攻击。

Args:
    executable_path: 可执行文件路径（相对或绝对）
    working_dir: 工作目录（用于解析相对路径）
    
Returns:
    是否允许执行
Fr   ..rl   NT. )r   r   isabsr   r   r   r   r   r   getattrr   r   r   r   r   )ru   r   r   r   working_pathrel_path
path_partsallowed_dirsr   path_strr   s              rv   is_data_executable_path_allowed-SandboxConfig.is_data_executable_path_allowed+  so   5	ww}}_--088: -?HHJ  ,446L#//= X,,S1Jz! #4)DdKL#))+%zz*ErJ   8}H+)//177<" #%):(*# &&{S'899X=T  ,  M  P  		sU   A3E% 6E  E% (9E% "AE% .E% E% E% 
E"E% !E""E% %
E21E2c                 P	   SU R                   ;   nU R                  (       a`  UR                  5       R                  5       nU(       a"  [        R
                  R                  US   5      OSnXPR                  ;   a  SSU S34$ U R                   H6  n[        R                  " Xa[        R                  5      (       d  M/  SSU 34s  $    U R                   H  nXq;   d  M
  SSU 34s  $    U(       a  UR                  5       R                  5       nUS	S
  H  n	U	R                  5       n	U	R                  S5      (       a  M+  [        R
                  R                  U	5      (       aQ  U R                  U	5      (       d9  SSU	 SU R                  (       a  SR!                  U R                  5      OS S34s  $ M  SU	;   d  M  SSU	 S34s  $    Sn
U(       a  U R#                  X5      nU H  nU R%                  X5      (       a  Sn
M  U(       a;  SU;   d,  UR                  S5      (       d  UR                  S5      (       a	  SSU 34s  $ U(       d  Mh  SU;   d.  UR                  S5      (       d  UR                  S5      (       d  M  SSU 34s  $    / SQnU/nU H0  n/ nU H#  nUR'                  UR                  U5      5        M%     UnM2     U GH  nUR                  5       nU(       d  M  SU;   Ga  UR)                  S5      nUS
U nU(       a  [        R*                  " SU5      (       a  UUS	-   S
 n[        R,                  " S U5      nU[        R,                  " S!U5      -  nU H  nUR                  5       R                  5       nU(       d  M*  US   nSU;   a  [        R
                  R                  U5      nUU R                  ;   a  SS"U S#34s  s  $ U(       a  My  UU R                   ;  d  M  SS"U S$34s  s  $    GM4  UR                  5       nU(       d  GMN  US   nU
(       a  UR                  S5      (       a	  SU;   a  GMy  SU;   a  [        R
                  R                  U5      nXPR                  ;   a
  SSU S34s  $ U(       a  GM  XPR                   ;  d  GM  SSU S$34s  $    g%)&u   检查命令是否允许执行

Args:
    command: 要检查的命令
    working_dir: 工作目录（可选，用于验证 data/ 目录内的可执行文件）
    
Returns:
    (是否允许, 原因)
r   r   r   Fu   命令 'u   ' 被沙箱策略禁止u   命令包含禁止的模式: u   命令包含禁止的操作: r   N-u   命令参数中的路径 'u+   ' 不在允许范围内（只允许访问: z, u	   无限制u   ）r   u!   命令参数包含路径遍历: ''Tzdata/z./data/z../data/uK   可执行文件路径不在允许的 data/ 目录内或包含路径遍历: r   r   r   u6   可执行文件路径不在允许的 data/ 目录内: )z&&z||;|=z^[a-zA-Z_][a-zA-Z0-9_]*$z\$\(([^)]+)\)z	`([^`]+)`u   命令替换中的命令 'u   ' 被禁止u   ' 不在允许列表中)Tr   )rj   rk   r   r   r   r   r   FORBIDDEN_PATTERNSresearch
IGNORECASEFORBIDDEN_COMMANDSr   r   r   rh   joinr   r   extendr(   matchfindall)ru   r   r   	allow_allmainmain_cmdpattern	forbiddenr   parthas_data_executableexecutable_paths	exec_pathcompound_separatorscommands_to_checksepnew_commandsr   
single_cmdeq_posvar_part
value_partsubst_matches	subst_cmdsubst_partssub_main_cmds                             rv   is_command_allowed SandboxConfig.is_command_allowedn  s    4000	   ==?((*D48rww''Q0bH000
2IJJJ ..Gyy2==99 =gYGGG /
 00I# =i[III 1
 MMO))+Eab	zz|??3''77==&&//55$(B4&Hs  \`  \t  \ttxt}t}  C  W  W  uX  zE  tF  FI  'J   J  J 6 T\ $EdV1"MMM " $#==gS-	77	OO*.'Gy$8I<P<PQZ<[<[_h_s_st~__ $opyoz"{{{YC9$4	8L8LT8R8RV_VjVjkpVqVq !$Z[dZe"fff ." 5$I&CL(##CIIcN3 ) ,	 ' ,J#))+J j #-%gv.)Dh O O!+FQJK!8J$&JJ/?$LM!RZZj%IIM%2	&/oo&7&=&=&?&;+6q>L"l2/1ww/?/?/M+t/D/DD',0J<.Xc.d'd d#,9TEZEZ1Z',0J<.Xo.p'p p &3 $$&EQxH #x':':4'@'@WPXEX h77++H5 000
2IJJJ91F1F!F
2IJJJe ,h ry   c                 Z    SUR                  5       ;   a  U R                  $ U R                  $ )uh   获取命令的超时时间

Args:
    command: 命令字符串
    
Returns:
    超时时间（秒）
rE   )lowerrp   ro   )ru   r   s     rv   get_timeoutSandboxConfig.get_timeout  s*     w}}&&&&###ry   output_base_dircategory_idc                    [        [        5      R                  R                  R                  R                  R                  nUS-  n[        U5      S/nS/nU(       a  UR	                  [        U5      5        O(U(       a!  XR-  S-  nUR	                  [        U5      5        U " UUSSS9n	U	R                  U=(       d    U R                  5       US9  U	$ )u,   创建用于 CTF 题目生成的沙箱配置ge10/tmpoutput,  X  rh   ri   ro   rp   r   )r   __file__parentr   r   r   r   )
clsr   r   r   project_rootge10_dirr   r   category_output_dirsandboxs
             rv   create_for_ctf_generation'SandboxConfig.create_for_ctf_generation   s     H~,,33::AAHH&( M
 %X%%c/&:;"*"88"C%%c*=&>? 1&8	
 	V8s'8<Pry   c                 4   [        [        5      R                  R                  R                  R                  R                  nUS-  nXA-  S-  n[        U5      S/n[        U5      S/nU " UUSSS9nUR	                  U=(       d    U R                  5       US9  U$ )u7   创建用于知识库管理/命令执行的沙箱配置r  datar  r  r  r  r  )r   r	  r
  r   r   r   )	r  r   r   r  r  data_dirr   r   r  s	            rv   create_for_knowledge_base'SandboxConfig.create_for_knowledge_base!  s     H~,,33::AAHH&()F2 ]F3!(mV4 1&8	
 	V8s'8<Pry   )	rj   rh   ri   rk   ro   rp   rl   rm   rn   )	NNNNNi   i@  r  r  )N)NNN)!__name__
__module____qualname____firstlineno____doc__rr   r   r   r   r   r   r   r   rw   staticmethodr   r   r   r   r   r   boolr   r   r   r   tupler   r   classmethodr  r  __static_attributes__ ry   rv   r	   r	      s<    D* *./3%)%)/3-#"!"-!#Y"- $(9"- c(	"-
 c("- $(9"- "- "- "- "-H !Xd^ !t ! ! d3i 8D> TRUY  #l8D> #lXd^ #lJC D ># $ >* *3 *4PS9 *XAs AQT AY] AFB# BHSM BUZ BH$3 $3 $  QT emnres   @O  @ C $ [j  ry   r	   )r  r   r   typingr   r   r   r   pathlibr   r	   r!  ry   rv   <module>r$     s'    
 	 - - d dry   