
    Si                        U d 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
mZ dZdZh d	Zee   ed
<   dddddddddd	Zeeeef   eedz  ef   f   ed<   e G d d             Ze G d d             Zdedededededed ed!efd"Zd#ed!edz  fd$Zd#ed!ee   fd%Zd#ed!ee   fd&Zd'ee   d(ed!ee   fd)Zd*ed!ee   fd+Zd3d,ed-ed!efd.Z d4d/ed0ed!eedz  ef   fd1Z!d/ed!efd2Z"y)5u'  스킬 보안 스캔 모듈.

위협 패턴 스캔, 구조 검사, 보이지 않는 문자 탐지 및 설치 정책 판정.

Usage:
    from utils.skill_guard import scan_skill, should_allow_install
    result = scan_skill(Path("/path/to/skill"))
    allowed, msg = should_allow_install(result)
    N)	dataclassfield)datetimetimezone)Path)INVISIBLE_CHARSTHREAT_PATTERNSi   d   >
   .a.o.so.bin.dll.exe.lib.obj.pyc.pyo_BINARY_EXT)Tu   공식 스킬 - 안전)Tu   공식 스킬 - 주의 (경고))Nu3   공식 스킬 - 위험 패턴 발견, 확인 필요)Tu   커뮤니티 스킬 - 안전)Nu6   커뮤니티 스킬 - 주의 (사용자 확인 필요))Fu,   커뮤니티 스킬 - 위험 (설치 차단))Tu   에이전트 스킬 - 안전)Fu,   에이전트 스킬 - 주의 (설치 차단))Fu,   에이전트 스킬 - 위험 (설치 차단))	)officialsafe)r   caution)r   	dangerous)	communityr   )r   r   )r   r   )agent-createdr   )r   r   )r   r   _POLICYc                   T    e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   y)	SkillFinding
pattern_idseveritycategoryfilelinematchdescriptionN)__name__
__module____qualname__str__annotations__int     B/home/jay/workspace/.worktrees/task-2117-dev1/utils/skill_guard.pyr   r   "   s&    OMM
I
IJr-   r   c                   f    e Zd ZU eed<   eed<   eed<   eed<    ee      Zee   ed<   dZ	eed<   y	)
SkillScanResult
skill_namesourcetrust_levelverdict)default_factoryfindings 
scanned_atN)
r&   r'   r(   r)   r*   r   listr6   r   r8   r,   r-   r.   r0   r0   -   s5    OKL#(#>Hd< >Jr-   r0   pidsevcatfplnmtdescreturnc           	      $    t        | ||||||      S )N)r   )r:   r;   r<   r=   r>   r?   r@   s          r.   _mkfrC   7   s    S#r2r488r-   filepathc                     | j                         r!| j                         j                  t        kD  ry | j                  j                         t        v ry 	 | j                  dd      S # t        $ r Y y w xY w)Nutf-8replaceencodingerrors)	is_filestatst_size_MAX_FILE_BYTESsuffixlowerr   	read_textOSError)rD   s    r.   
_read_textrS   ;   si    !8!8?!J+-!!79!EE s   A( (	A43A4c                 V   t        |       }|g S g }t        |j                         d      D ]z  \  }}t        D ]l  \  }}}}}	t	        j
                  ||t        j                        }
|
s1|j                  t        |||t        |       ||
j                  d      dd |	              z | |S )u#   단일 파일 위협 패턴 스캔.N   r      )rS   	enumerate
splitlinesr	   research
IGNORECASEappendrC   r)   group)rD   contentoutnor#   patr:   r;   r<   r@   ms              r.   	scan_filerc   F   s    "G	 Cg002A6 D(7 	$Cc3		#tR]]3A

4S#s8}b!''!*TcBRTXYZ		 Jr-   c                 f   | j                         sg S 	 | j                  dd      }g }t        |j	                         d      D ]U  \  }}|D cg c]  }|t
        v s| }}|s!|j                  t        dddt        |       |t        |dd	       d
             W |S # t        $ r g cY S w xY wc c}w )u,   보이지 않는 유니코드 문자 탐지.rF   rG   rH   rU   z	INVIS-001highobfuscationN   u$   보이지 않는 유니코드 문자)
rK   rQ   rR   rW   rX   r   r\   rC   r)   repr)rD   r^   r_   r`   r#   cfounds          r.   check_invisible_charsrk   U   s    	$$gi$H !Cg002A6 D 9qA$899JJHr4PUVXWXPY?  ]C J  	 :s   B B.B.B+*B+	all_itemsbasec                    g }| D ]p  }|j                         s	 |j                         }t        |      j                  |      s2|j	                  t        dddt        |      dt        |      d             r |S # t        $ r Y w xY w)Nz
STRUCT-003critical	structurer   u   심링크 탈출)
is_symlinkresolver)   
startswithr\   rC   rR   )rl   rm   r_   itemtargets        r.   _check_symlinksrv   i   s     C  	\\^Fv;))$/

4j+s4yRSUXY_U`btuv J  		s   AA::	BB	skill_dirc                    | j                         sg S t        | j                  d            }t        d |D              }g }|t        kD  r4|j                  t        dddt        |       dd| dt         d	             |j                  t        |t        | j                                            |D ]  }|j                         r|j                         s%|j                         j                  t        kD  sG|j                  t        d
ddt        |      dd|j                         j                   d              |S )u,   파일 수, 크기, 심링크 탈출 검사.*c              3   B   K   | ]  }|j                         sd   yw)rU   N)rK   .0fs     r.   	<genexpr>z"check_structure.<locals>.<genexpr>|   s     11QYY[Q1s   z
STRUCT-001mediumrp   r   zcount=u   파일 수 초과 (최대 u   개)z
STRUCT-002zsize=u   파일 크기 초과)is_dirr9   rglobsum_MAX_FILE_COUNTr\   rC   r)   extendrv   rr   rq   rK   rL   rM   rN   )rw   rl   fcr_   rt   s        r.   check_structurer   w   s   	Y__S)*I	1	1	1B C	O

I,_,=TB
	
 JJy#i.?.?.A*BCD  T\\^		8K8Ko8]JJ\8[#d)Q%PTPYPYP[PcPcOdHeg}~
 Jr-   
skill_pathr2   c           
         g }| j                         r| j                  }|j                  t        |              | j	                  d      D ]X  }|j                         s|j                         r%|j                  t        |             |j                  t        |             Z n@| j                  }|j                  t        |              |j                  t        |              t        d |D              }t        d |D              }|rdn|s|rdnd}t        |||||t        j                  t        j                        j!                               S )u0   스킬 디렉터리/파일 전체 보안 스캔.ry   c              3   :   K   | ]  }|j                   d k(    yw)ro   Nr    r{   s     r.   r~   zscan_skill.<locals>.<genexpr>   s     91::+9   c              3   :   K   | ]  }|j                   d k(    yw)re   Nr   r{   s     r.   r~   zscan_skill.<locals>.<genexpr>   s     5A1::'5r   r   r   r   )r   namer   r   r   rK   rq   rc   rk   stemanyr0   r   nowr   utc	isoformat)r   r2   fdsr   r=   has_crithas_highr4   s           r.   
scan_skillr      s    C

?:./""3' 	6Bzz|BMMO

9R=)

045	6
 

9Z()

(459S99H555H%k(cIPVG4#x||HLL?Y?c?c?effr-   resultforcec                     |rdd| j                    dfS t        j                  | j                  | j                  fdd| j                   df      S )uB   설치 정책 판정. True=allow, False=block, None=확인 필요.Tz[force] u    강제 허용Nu   알 수 없는 소스())r1   r   getr2   r4   )r   r   s     r.   should_allow_installr      sV    x 1 12.AAA;;v~~6AWX^XeXeWffg?h8ijjr-   c                 b   dd| j                    d| j                   d| j                   d| j                  j                          dd| j                   dt        | j                         d	g}| j                  r|j                  d
       | j                  D ]u  }|j                  d|j                  j                          d|j                   dt        |j                        j                   d|j                   d|j                   
       w |j                  d       dj                  |      S )u   보고서 문자열 생성.z<============================================================z[SKILL GUARD] u
     소스: u
     판정: z (r   u
     스캔: u
     발견: u   건z<------------------------------------------------------------z  [z] z @ :z | 
)r1   r2   r4   upperr8   lenr6   r\   r    r   r   r"   r   r#   r%   join)r   linesfnds      r.   format_scan_reportr      s    	
**+,
V]]O:fnn-=R@T@T@V?WWXY
V&&'z#foo2F1GsK	E X?? 	CLLcll((*+2cnn-=SchhATAT@UUVWZW_W_V``cdgdsdsctu	 
LL99Ur-   )r   )F)#__doc__rY   dataclassesr   r   r   r   pathlibr   utils.skill_guard_patternsr   r	   rN   r   r   setr)   r*   r   dicttupleboolr   r0   r+   rC   rS   r9   rc   rk   rv   r   r   r   r   r,   r-   r.   <module>r      s   
 ( '  G"cSX c:F\A^ WE"Y$[
;eCHouTD[#%566	7 
      9c 9 9# 93 9C 9S 9 9P\ 9 #*  l!3 D T,-? (tDz  l9K t \(: 8g4 g g g(k k k%PTW[P[]`P`Ja k 3 r-   