
    (Gjt              	       l   U 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
Z
ddlZddlZddlZddlmZ  ej        e          ZdZde dZdZded	ed
efdZded	ed
efdZd
efdZdaedz  ez  ed<   dZ da!eed<   dZ"da#eed<   da$eed<   dDdZ% ej&                    Z'da(ej)        dz  ed<    e*            Z+e*e         ed<    ej&                    Z,deded
dfdZ-dDdZ.dZ/d
efdZ0d
efdZ1d
edz  fdZ2d
efdZ3dEd efd!Z4d" Z5d
efd#Z6d
edz  fd$Z7d
efd%Z8dFd'ed(ed)efd*Z9d+ed,ed-ed
edz  fd.Z:d/ed+ed0ed
efd1Z;d2e	j<        d3ed
e=edz  ef         fd4Z>d5d6d7ed
e=edz  ef         fd8Z?d9ed
efd:Z@d9ed
efd;ZAd5d6d7efd<ZBd5d6d7efd=ZCd>ZDd?ZEd@ed
efdAZFdBed
efdCZGdS )Gu  Tirith pre-exec security scanning wrapper.

Runs the tirith binary as a subprocess to scan commands for content-level
threats (homograph URLs, pipe-to-interpreter, terminal injection, etc.).

Exit code is the verdict source of truth:
  0 = allow, 1 = block, 2 = warn

JSON stdout enriches findings/summary but never overrides the verdict.
Operational failures (spawn error, timeout, unknown exit code) respect
the fail_open config setting. Programming errors propagate.

Auto-install: if tirith is not found on PATH or at the configured path,
it is automatically downloaded from GitHub releases to $HERMES_HOME/bin/tirith.
The download always verifies SHA-256 checksums.  When cosign is available on
PATH, provenance verification (GitHub Actions workflow signature) is also
performed.  If cosign is not installed, the download proceeds with SHA-256
verification only — still secure via HTTPS + checksum, just without supply
chain provenance proof.  Installation runs in a background thread so startup
never blocks.
    N)get_hermes_homezsheeki03/tirithz^https://github.com/z,/\.github/workflows/release\.yml@refs/tags/vz+https://token.actions.githubusercontent.comkeydefaultreturnc                 ^    t          j        |           }||S |                                dv S )N>   1yestrue)osgetenvlowerr   r   vals      ;/home/rurouni/.hermes/hermes-agent/tools/tirith_security.py	_env_boolr   3   s-    
)C..C
{99;;...    c                 v    t          j        |           }||S 	 t          |          S # t          $ r |cY S w xY w)N)r   r   int
ValueErrorr   s      r   _env_intr   :   sM    
)C..C
{3xx   s   ) 88c                     ddddd} 	 ddl m}  |                                di           pi }n# t          $ r i }Y nw xY wt	          d|                    d	| d	                             t          j        d
|                    d| d                             t          d|                    d| d                             t	          d|                    d| d                             dS )z@Load security settings from config.yaml, with env var overrides.Ttirith   )tirith_enabledtirith_pathtirith_timeouttirith_fail_openr   )load_configsecurityTIRITH_ENABLEDr   
TIRITH_BINr   TIRITH_TIMEOUTr   TIRITH_FAIL_OPENr   )hermes_cli.configr   get	Exceptionr   r   r   r   )defaultsr   cfgs      r   _load_security_configr)   D   s     	 H111111kmm
B//52    $$4cgg>NPXYiPj6k6kllysww}h}F]/^/^__"#3SWW=MxXhOi5j5jkk%&8#''BTV^_qVr:s:stt	  s   &0 ??_resolved_pathF _install_failure_reason   _crash_count_circuit_openc                      t           dz  a t           t          k    r$dat                              dt                      dS dS )zCIncrement the crash counter and open the circuit breaker if needed.   Tzbtirith circuit breaker opened after %d consecutive failures; disabling for the rest of the processN)r.   _CRASH_LIMITr/   loggerwarning r   r   _record_tirith_crashr6   u   sN     AL|##4	
 	
 	
 	
 	
 $#r   _install_thread_warned_messagesmessagec                     t           5  | t          v r	 ddd           dS t                              |            ddd           n# 1 swxY w Y   t          j        |g|R   dS )z``logger.warning`` but at-most-once per ``key`` for the process
    lifetime. Used to avoid drowning the log when a fail-open tirith
    misconfiguration fires on every command.N)_warned_lockr8   addr3   r4   )r   r9   argss      r   
_warn_oncer>      s     
 " """"" " " " " " " " 	S!!!" " " " " " " " " " " " " " " N7"T""""""s   AAA
A
c                  x    t           5  t                                           ddd           dS # 1 swxY w Y   dS )u   Clear the warn-once dedupe set. Called when tirith is freshly
    (re)installed so a subsequent failure surfaces again — e.g. user
    deletes the binary mid-session.
    N)r;   r8   clearr5   r   r   _reset_spawn_warning_staterA      s    
 
 ! !   ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   /33iQ c                  8    t          t                                S )zAReturn the Hermes home directory, respecting HERMES_HOME env var.)strr   r5   r   r   _get_hermes_homerD      s      !!!r   c                  Z    t           j                            t                      d          S )z3Return the path to the install-failure marker file.z.tirith-install-failed)r   pathjoinrD   r5   r   r   _failure_marker_pathrH      s     7<<(**,DEEEr   c                  f   	 t                      } t          j                            |           }t	          j                    |z
  t
          k    rdS t          | dd          5 }|                                                                cddd           S # 1 swxY w Y   dS # t          $ r Y dS w xY w)zRead the failure reason from the disk marker.

    Returns the reason string, or None if the marker doesn't exist or is
    older than _MARKER_TTL.
    Nrutf-8encoding)
rH   r   rF   getmtimetime_MARKER_TTLopenreadstripOSError)pmtimefs      r   _read_failure_reasonrX      s     ""  ##IKK%K//4!S7+++ 	$q6688>>##	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$   tts<   AB" B" "&BB" BB" BB" "
B0/B0c                  ~    t                      } | dS | dk    r$t          j        d          rt                       dS dS )zCheck if a recent install failure was persisted to disk.

    Returns False (allowing retry) when:
    - No marker exists
    - Marker is older than _MARKER_TTL (24h)
    - Marker reason is 'cosign_missing' and cosign is now on PATH
    NFcosign_missingcosignT)rX   shutilwhich_clear_install_failed)reasons    r   _is_install_failed_on_diskr`      sJ     "##F~u!!!fl8&<&<!u4r   r_   c                 ,   	 t                      }t          j        t          j                            |          d           t          |dd          5 }|                    |            ddd           dS # 1 swxY w Y   dS # t          $ r Y dS w xY w)a  Persist install failure to disk to avoid retry on next process.

    Args:
        reason: Short tag identifying the failure cause. Use "cosign_missing"
                when cosign is not on PATH so the marker can be auto-cleared
                once cosign becomes available.
    Texist_okwrK   rL   N)rH   r   makedirsrF   dirnamerQ   writerT   )r_   rU   rW   s      r   _mark_install_failedrh      s     ""
BGOOA&&6666!S7+++ 	qGGFOOO	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   s6   AB A8+B 8A<<B ?A< B 
BBc                      t                       	 t          j        t                                 dS # t          $ r Y dS w xY w)z3Remove the failure marker after successful install.N)rA   r   unlinkrH   rT   r5   r   r   r^   r^      sT    
    
	&(()))))   s    2 
A A c                      t           j                            t                      d          } t          j        | d           | S )z/Return $HERMES_HOME/bin, creating it if needed.binTrb   )r   rF   rG   rD   re   )ds    r   _hermes_bin_dirrn      s8    
%''//AKD!!!!Hr   c                      t          j                    } t          j                                                    }| dk    rd}n	| dv rd}ndS |dv rd}n	|dv rd	}ndS | d
| S )u  Return the Rust target triple for the current platform, or None.

    Windows is intentionally unsupported — tirith does not ship a Windows
    build. Callers should treat `None` as "this platform will never have
    tirith" and silently fall back to pattern-matching guards.
    Darwinzapple-darwin>   LinuxAndroidzunknown-linux-gnuN>   amd64x86_64rt   >   arm64aarch64rv   -)platformsystemmachiner   )ry   rz   platarchs       r   _detect_targetr}      s     _F  &&((G 	'	'	'"t%%%	(	(	(tTr   c                  "    t                      duS )u  True when tirith ships a prebuilt binary for this OS+arch.

    Used by callers (CLI banner, etc.) to distinguish "tirith failed to
    install" from "tirith was never going to install here" — the latter
    is silent because there is nothing the user can do about it.
    N)r}   r5   r   r   is_platform_supportedr     s     4''r   
   urldesttimeoutc                    t           j                            |           }t          j        d          }|r|                    dd|            t           j                            ||          5 }t          |d          5 }t          j	        ||           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )zDownload a URL to a local file.GITHUB_TOKENAuthorizationztoken )r   wbN)
urllibrequestRequestr   r   
add_headerurlopenrQ   r\   copyfileobj)r   r   r   reqtokenresprW   s          r   _download_filer     s<   
.
 
 
%
%CIn%%E :(8(8(8999			W		5	5 $tD$?O?O $ST4###$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s6   0B;B#B;#B'	'B;*B'	+B;;B?B?checksums_pathsig_path	cert_pathc                    t          j        d          }|st                              d           dS 	 t	          j        |dd|d|dt          dt          | gd	d	d
t          j                  }|j	        dk    rt                              d           d	S t          
                    d|j	        |j                                                   dS # t          t          j        f$ r&}t          
                    d|           Y d}~dS d}~ww xY w)uk  Verify cosign provenance signature on checksums.txt.

    Returns:
        True  — cosign verified successfully
        False — cosign found but verification failed
        None  — cosign not available (not on PATH, or execution failed)

    The caller treats both False and None as "abort auto-install" — only
    True allows the install to proceed.
    r[   zcosign not found on PATHNzverify-blobz--certificatez--signaturez--certificate-identity-regexpz--certificate-oidc-issuerT   capture_outputtextr   stdinr   z%cosign provenance verification passedz(cosign verification failed (exit %d): %sFzcosign execution failed: %s)r\   r]   r3   info
subprocessrun_COSIGN_IDENTITY_REGEXP_COSIGN_ISSUERDEVNULL
returncoder4   stderrrS   rT   TimeoutExpired)r   r   r   r[   resultexcs         r   _verify_cosignr   %  s)    \(##F .///t]iH,.E(.  $
 
 
 !!KK?@@@4NNE +V]-@-@-B-BD D D5Z./   4c:::ttttts   AC 8C D	#DD	archive_patharchive_namec                   	 d}t          |d          5 		D ]S}|                                                    dd          }t          |          dk    r|d         |k    r
|d         } nTddd           n# 1 swxY w Y   |st                              d|           d	S t          j                    }t          | d
          5 	t          	fdd          D ]}|	                    |           	 ddd           n# 1 swxY w Y   |
                                }||k    rt                              d||           d	S dS )z4Verify SHA-256 of the archive against checksums.txt.NrK   rL   z  r1      r   zNo checksum entry for %sFrbc                  .                          d          S )Ni    )rR   )rW   s   r   <lambda>z"_verify_checksum.<locals>.<lambda>^  s    !&&,, r   r   z&Checksum mismatch: expected %s, got %sT)rQ   rS   splitlenr3   r4   hashlibsha256iterupdate	hexdigest)
r   r   r   expectedlinepartsshachunkactualrW   s
            @r   _verify_checksumr   N  s   H	nw	/	/	/ 1 	 	DJJLL&&tQ//E5zzQ58|#;#; 8                1<@@@u
.

C	lD	!	! Q....44 	 	EJJu	               ]]__F?6RRRu4s$   AA88A<?A<,C>>DDtardest_dirc                 j   |                                  D ]}|j        dk    s|j                            d          rd|j        v r2|                                s |d|j                    dS |                     |          }| |d            dS t
          j                            |d          }	 t          |d	          5 }t          j
        ||           ddd           n# 1 swxY w Y   |                                 n# |                                 w xY w|d
fc S  |d           dS )z?Extract the tirith binary from a release archive into dest_dir.r   z/tirithz..z/tirith archive member is not a regular file: %s)Nbinary_not_regular_fileNz,tirith binary could not be read from archive)Nbinary_extract_failedr   r+   z"tirith binary not found in archive)Nbinary_not_in_archive)
getmembersnameendswithisfileextractfiler   rF   rG   rQ   r\   r   close)r   r   logmembersrc_file	dest_pathouts          r   _extract_tirith_binaryr   g  s   .."" ! !;(""fk&:&:9&E&E"v{""==?? 7Ev{SSS666v..HBCCC444Xx88I!)T** 6c&x5556 6 6 6 6 6 6 6 6 6 6 6 6 6 6         b=   # #& C,---((s0   5DC'D'C+	+D.C+	/DDTlog_failuresr   c                 "	   | rt           j        nt           j        }t                      }|s@t                               dt          j                    t          j                               dS d| d}dt           d}	 t          j
        d          }n$# t          $ r} |d	|           Y d
}~dS d
}~ww xY w	 t          j                            ||          }t          j                            |d          }t          j                            |d          }	t          j                            |d          }
t                               d|           	 t          | d| |           t          | d|           n:# t           $ r-} |d|           Y d
}~t#          j        |d           dS d
}~ww xY wd}t#          j        d          r	 t          | d|	           t          | d|
           t)          ||	|
          }|du rd}n|du r$ |d           	 t#          j        |d           dS t                               d           nL# t           $ r%}t                               d|           Y d
}~n"d
}~ww xY wt                               d           t+          |||          s	 t#          j        |d           dS t-          j        |d           5 }t1          |||          \  }}|&d
|fcd
d
d
           t#          j        |d           S 	 d
d
d
           n# 1 swxY w Y   t          j                            t3                      d!          }	 t#          j        ||           nu# t          $ rh 	 t#          j        ||           nN# t          $ rA 	 t          j        |           n# t          $ r Y nw xY wY Y t#          j        |d           d"S w xY wY nw xY wt          j        |t          j        |          j        t<          j         z  t<          j!        z  t<          j"        z             |rd#nd$}t                               d%||           |d&ft#          j        |d           S # t#          j        |d           w xY w)'a^  Download and install tirith to $HERMES_HOME/bin/tirith.

    Verifies provenance via cosign and SHA-256 checksum.
    Returns (installed_path, failure_reason).  On success failure_reason is "".
    failure_reason is a short tag used by the disk marker to decide if the
    failure is retryable (e.g. "cosign_missing" clears when cosign appears).
    z/tirith auto-install: unsupported platform %s/%s)Nunsupported_platformztirith-z.tar.gzzhttps://github.com/z/releases/latest/downloadztirith-install-)prefixz1tirith install failed: cannot create temp dir: %sN)Nno_spacezchecksums.txtzchecksums.txt.sigzchecksums.txt.pemu9   tirith not found — downloading latest release for %s.../z/checksums.txtztirith download failed: %sT)ignore_errors)Ndownload_failedFr[   z/checksums.txt.sigz/checksums.txt.pemz=tirith install aborted: cosign provenance verification failed)Ncosign_verification_failedz5cosign execution failed, proceeding with SHA-256 onlyz?cosign artifacts unavailable (%s), proceeding with SHA-256 onlyu{   cosign not on PATH — installing tirith with SHA-256 verification only (install cosign for full supply chain verification))Nchecksum_failedzr:gzr   )Ncross_device_copy_failedzcosign + SHA-256zSHA-256 onlyztirith installed to %s (%s)r+   )#r3   r4   debugr}   r   rx   ry   rz   _REPOtempfilemkdtemprT   r   rF   rG   r   r&   r\   rmtreer]   r   r   tarfilerQ   r   rn   movecopyrj   chmodstatst_modeS_IXUSRS_IXGRPS_IXOTH)r   r   targetr   base_urltmpdirr   r   r   r   r   cosign_verifiedcosign_resultr   srcr_   r   verifications                     r   _install_tirithr     s    )
:&..flCF ,E_&&(8(:(:	< 	< 	<++,V,,,LEUEEEH !):;;;      ?EEE K2w||FL99fo>>7<<(;<<GLL)<==	OQWXXX	+h7777FFFh666GGGG 	+ 	+ 	+C,c222****| 	fD111111A	+  <!! 	OY(>>>III(>>>	JJJ !/~x S S D((&*OO"e++ CWXXX=P 	fD111111I KK WXXXX  d d d]_bccccccccd  KK N O O O  nlKK 	+*< 	fD1111119 \,// 	$30fcBBKC{V|	$ 	$ 	$ 	$ 	$ 	$ 	$8 	fD111115 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$
 w||O--x88	8KT"""" 	8 	8 	88C&&&& 8 8 8IdOOOO   D77 	fD1111118 '&	8 	rwt}},t|;dlJT\YZZZ-<P)).14FFFRx 	fD11111fD11111s"  =B 
B4B//B48BQ6 (E= <Q6 =
F4F/Q6 /F44Q6 &I 4'Q6 4Q6 
I>I94Q6 9I>>.Q6 Q6 L$4Q6 Q6 $L((Q6 +L(,/Q6 M2 1Q6 2
O$=NO$
ON32O3
O =O?O  OO$Q6 OO$!Q6 #O$$A;Q6 6Rconfigured_pathc                     | dk    S )zHReturn True if the user explicitly configured a non-default tirith path.r   r5   )r   s    r   _is_explicit_pathr     s    h&&r   c                    t           t           t          urt           S t          j                            |           }t          |           }t           t          u }|st                      st          a da|S |rt          j                            |          r#t          j	        |t          j
                  r|a |S t          j        |          }|r|a |S t                              d|            t          a da|S t          j        d          }|r|a dat                       |S t          j                            t#                      d          }t          j                            |          r3t          j	        |t          j
                  r|a dat                       |S |r6t          dk    r)t          j        d          rda dat                       d	}n|S t$          t$                                          r|S t)                      }|t+                      rt          a |a|S t-                      \  }}|r|a dat                       |S t          a |at/          |           |S )
u@  Resolve the tirith binary path, auto-installing if necessary.

    If the user explicitly set a path (anything other than the bare "tirith"
    default), that path is authoritative — we never fall through to
    auto-download a different binary.

    For the default "tirith":
    1. PATH lookup via shutil.which
    2. $HERMES_HOME/bin/tirith (previously auto-installed)
    3. Auto-install from GitHub releases → $HERMES_HOME/bin/tirith

    Failed installs are cached for the process lifetime (and persisted to
    disk for 24h) to avoid repeated network attempts.
    Nr   z6Configured tirith path %r not found; scanning disabledexplicit_path_missingr   r+   rZ   r[   F)r*   _INSTALL_FAILEDr   rF   
expanduserr   r   r,   r   accessX_OKr\   r]   r3   r4   r^   rG   rn   r7   is_aliverX   r`   r   rh   )	r   expandedexplicitinstall_failedfound
hermes_bindisk_reason	installedr_   s	            r   _resolve_tirith_pathr    sv   $ !nO&K&Kw!!/22H 11H#6N  133 ("8  7>>(## 		(BG(D(D 	%NOX&& 	"NLOQ`aaa("9
 L""E "$o//::J	w~~j!! bi
BG&D&D #"$
  "&6666<;Q;Q6!N&(#!###"NNO
 "'?'?'A'A"
 '((K#=#?#?("-'))Iv ""$ %N$   Or   c                 8   t           5  t          	 ddd           dS t          j        d          }|r|ada	 ddd           dS t
          j                            t                      d          }t
          j        	                    |          r1t          j
        |t
          j                  r|ada	 ddd           dS t          |           \  }}|r|adat                       nt          a|at          |           ddd           dS # 1 swxY w Y   dS )z6Background thread target: download and install tirith.Nr   r+   r   )_install_lockr*   r\   r]   r,   r   rF   rG   rn   r   r   r   r   r^   r   rh   )r   r   r   r   r_   s        r   _background_installr  X  s    
 ) )%) ) ) ) ) ) ) ) X&& 	"N&(#) ) ) ) ) ) ) ) W\\/"3"3X>>
7>>*%% 	")J*H*H 	'N&(#!) ) ) ) ) ) ) )$ ,FFF	6 	)&N&(#!####,N&,# (((5) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )s$   	DDA/DA DDDc                 6   t                      }|d         sdS t          Wt          t          urIt          }t          j                            |          r!t          j        |t          j                  r|S dS t                      st          ada	dS |d         }t          |          }t          j                            |          }|rgt          j                            |          r#t          j        |t          j                  r|a|S t          j        |          }|r|a|S t          ada	dS t          j        d          }|r|ada	t                       |S t          j                            t!                      d          }t          j                            |          r3t          j        |t          j                  r|ada	t                       |S t          t          u r4t          dk    r't          j        d	          rdada	t                       ndS t#                      }|t%                      rt          a|a	dS t&          t&                                          s7t+          j        t.          d
| id          at&                                           dS )a  Ensure tirith is available, downloading in background if needed.

    Quick PATH/local checks are synchronous; network download runs in a
    daemon thread so startup never blocks. Safe to call multiple times.
    Returns the resolved path immediately if available, or None.
    r   Nr   r   r   r   r+   rZ   r[   r   T)r   kwargsdaemon)r)   r*   r   r   rF   r   r   r   r   r,   r   r   r\   r]   r^   rG   rn   rX   r`   r7   r   	threadingThreadr  start)	r   r(   rF   r   r   r   r   r   r   s	            r   ensure_installedr  x  s     
!
!C  t !nO&K&K7>>$ 	BIdBG$<$< 	Kt
 !"" ("8t-(O 11Hw!!/22H  
7>>(## 		(BG(D(D 	%NOX&& 	"NL("9t L""E "$o//::J	w~~j!! bi
BG&D&D #"$ (("&6666<;Q;Q6!N&(#!####4
 '((K#=#?#?("-t o&>&>&@&@#*&"L1
 
 

 	4r   2   i  commandc           
      |   t                      }|d         sdg ddS t          rdg ddS t                      sdg ddS t          |d                   }|d         }|d         }|t	          d
d           |rdg ddS dg ddS 	 t          j        |dddddd| gdd|t
          j                  }n# t          $ rk}dt          |          j
         dt          |dd           }t	          |d|           t                       |rdg d| dcY d	}~S dg d| dcY d	}~S d	}~wt
          j        $ r9 t	          d| d|           t                       |rdg d| d dcY S dg d!dcY S w xY w|j        }|d"k    rd}	d"anQ|d#k    rd}	nH|d$k    rd%}	n?t                               d&|           t                       |r
dg d'| d(dS dg d'| d)dS g }
d}	 |j                                        rt)          j        |j                  ni }|                    d*g           }|d	t.                   }
|                    d+d          pdd	t0                   }nG# t(          j        t4          f$ r. t                               d,           |	dk    rd-}n|	d%k    rd.}Y nw xY w|	d%k    r|
rd/ |
D             }|sd}	g }
d}|	|
|dS )0a@  Run tirith security scan on a command.

    Exit code determines action (0=allow, 1=block, 2=warn). JSON enriches
    findings/summary. Spawn failures and timeouts respect fail_open config.
    Programming errors propagate.

    Returns:
        {"action": "allow"|"warn"|"block", "findings": [...], "summary": str}
    r   allowr+   )actionfindingssummaryz!tirith disabled (circuit breaker)r   r   r   Ntirith_path_nonez/tirith path resolved to None; scanning disabledztirith path unavailableblockz%tirith path unavailable (fail-closed)checkz--jsonz--non-interactivez--shellposixz--Tr   ztirith_spawn_failed::errnoztirith spawn failed: %sztirith unavailable: z#tirith spawn failed (fail-closed): ztirith_timeout:ztirith timed out after %dsztirith timed out (zs)ztirith timed out (fail-closed)r   r1   r   warnz'tirith returned unexpected exit code %dztirith exit code z (fail-open)z (fail-closed)r  r  z.tirith JSON parse failed, using exit code onlyz-security issue detected (details unavailable)z/security warning detected (details unavailable)c                 0    g | ]}t          |          |S r5   )_is_app_tld_finding).0rW   s     r   
<listcomp>z*check_command_security.<locals>.<listcomp>P  s&    NNN!7J17M7MNANNNr   )r)   r/   r   r  r>   r   r   r   rT   type__name__getattrr6   r   r   r.   r3   r4   stdoutrS   jsonloadsr%   _MAX_FINDINGS_MAX_SUMMARY_LENJSONDecodeErrorAttributeErrorr   )r  r(   r   r   	fail_openr   r   	spawn_key	exit_coder  r  r  dataraw_findingsnon_suppressibles                  r   check_command_securityr.    sN     
!
!C  B!rbAAA  c!r>abbb
 !"" B!rbAAA&s='9::K"#G&'I=	
 	
 	
  	]%2B[\\\!r>efff`'8-@w0$
 
 
  k k k \499+=[[WVX@Y@Y[[	97=== 	`%2B^Y\B^B^________!r>idg>i>ijjjjjjjj$ 	` 	` 	`'g''(	
 	
 	

 	 	d%2BbW^BbBbBbccccc!r>^_____	` !IA~~	a	a 	@)LLL 	o%2BmV_BmBmBmnnn!r>kR[>k>k>klll HGH,2M,?,?,A,AItz&-(((rxx
B///88Ir**0b2C3C2CD .1 H H HEFFFWEGGvGGH HNNxNNN 	FHG(wGGGsL   +B0 0
E+:AD E+D E+ A E+"E+*E+A>I AJJfindingc                     t          | t                    sdS |                     d          dk    rdS dD ]?}|                     |          }|&dt          |                                          v r dS @dS )zReturn True if this finding is a lookalike_tld warning for the .app TLD only.

    Checks the rule_id and inspects common value/detail field names that
    Tirith may use to carry the TLD string.
    Frule_idlookalike_tld)valuetlddetaildescriptionr9   Nz.appT)
isinstancedictr%   rC   r   )r/  fieldr   s      r   r  r  Y  s     gt$$ u{{900uE  kk%  ?vS)9)999445r   )r   N)r+   )r   )H__doc__r   r"  loggingr   rx   r\   r   r   r   r   r  rO   urllib.requestr   hermes_constantsr   	getLoggerr  r3   r   r   r   rC   boolr   r   r   r8  r)   r*   __annotations__r   r,   r2   r.   r/   r6   Lockr  r7   r	  setr8   r;   r>   rA   rP   rD   rH   rX   r`   rh   r^   rn   r}   r   r   r   r   TarFiletupler   r   r   r  r  r  r$  r%  r.  r  r5   r   r   <module>rE     sg    ,    				                   , , , , , ,		8	$	$ gfff >/3 / /$ / / / /#      t    8 %)d
T! ( ( (!  ! ! ! c   t   

 

 

 

 	  +/!D( / / / !SUU #c( " " "y~#C ## # # # # #! ! ! ! "# " " " "
Fc F F F F
cDj    "D    "     "	 	 	    d
    8(t ( ( ( ($ $ $3 $ $ $ $ $&3 &# &# &$QU+ & & & &R3  3 SW    2) )3 )cTXjZ]oH^ ) ) ) )4 -1 c2 c2 c2T c2U3:s?5K c2 c2 c2 c2L's 't ' ' ' '
i# i# i i i iX 15 ) ) ) ) ) ) )@ .2 W W Wd W W W W|  |HC |HD |H |H |H |H~ $      r   