l#g% ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl ZddlZddlZddlmZddlmZmZddlmZmZddlmZmZmZddlmZddlm Z ddl!m"Z"m#Z#m$Z$m%Z%dd lm&Z&dd lm'Z'dd l(m)Z)dd l*m+Z+dd l,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4ddl5Z5ddl6Z6ddl7Z7ddl8m9Z9e4de/Z:ej;e<Z=dZ>dZ?da@dZAe)dZBdZCe)dZDe)dZEe)dZFGdde ZGejHddZIeddZJe=ddfd ZKGd!d"ZLdejMejMd#dfd$e3eNeOeOffd%ZPddd&d'ZQGd(d)ejRZSeSfd$eOfd*ZTeSfdd+ZUdd$eVfd-ZWd.ZXGd/d0ZYd1ZZGd2d3e[Z\d4Z]d5Z^ dd7Z_d,ddd,dd8d$e`fd9ZaejHdd:Zbdd$eVfd;ZcGd<d=Zdejed>fd?eVd@eNd$eVfdAZf dd?eVd@eNd$e3eVeNffdBZgdCZhdDZiddFZj ddHZkdIZlejHdJeNfdKZmejne5jodLd,MZpdNZqd?ejrdOeOd$dfdPZsdQZtd?ejrdReOd$e`fdSZudTZvGdUdVZwe?fdWZxdXZyedYeNfdZZzdd\eVd$e)fd]Z{d^eVd\eVd$e`fd_Z|d`Z}ddbedceNd$efddZ~deZGdfdgeZejHd6dhZdiZdd$e`fdjZGdkdlZeZdmZdnZGdodpejZdqZ ddrZdsZe[dfdtZefduZdvZdwZd#dxdyZedzd{Zd|Zd}Zd^e)d$eOfd~ZdeOd$e)fdZdZdZde/de.ffdZdZdZdZdZejHddZdLdde2eVfdZddddZddZGddZdZejHddZGdde[ZdZd$efdZe=jfdZdeNfdZde0e-e-fdeNfdZejHddZdS)N)Future) OrderedDictdeque) GeneratorIterable) ExitStackcontextmanagersuppress) timedelta)Enum)LOCK_EXLOCK_NBLOCK_UNflockwraps)islice)Path)NamedTemporaryFile)Any AwaitableCallableDict FrozenSetListTupleTypeVar)rmtreeF)bounduser_id)z User-AgentzAccept-LanguagezAccept-Encoding ConnectionDNTz.i360bakz/run/systemd/systemz/etc/cloudlinux-edition-soloz/var/run/imunify-antivirus.pidz/var/run/imunify360-agent.pidz/var/run/imunify360.pidceZdZdZdZdZdS)ScopezAV onlyz AV and IM360z IM360 onlyN)__name__ __module__ __qualname__AVAV_IM360IM360S/opt/imunify360/venv/lib/python3.11/site-packages/defence360agent/utils/__init__.pyr'r'As BH EEEr/r')maxsizecto2tot S)zReturn True if /run/systemd/system folder exists: [sd_booted] (https://www.freedesktop.org/software/systemd/man/sd_booted.html) )_SYSTEMD_BOOTED_DIRexistsis_dir is_symlinkr.r/r0is_systemd_bootr7GsC ""$$ 1  & & ( ( 1#..00 0r/c#K|s|sJtj}dVtj}|p|jd|||z dS)z :param str: action name to log :param logging.Logger: logger you want action name and timing to be logged with :param func: log function to use (`log` has preference over `logger_`) Nz%s took %.2f second(s))time monotonicdebug)actionlogger_logstartstops r0timeitrATsa c> N  E EEE >  DSGM3VTE\JJJJJr/cfd}|S)NcNtjfd}|S)NcKtpj5|i|d{VcdddS#1swxYwYdSN)r=r>rAr(argskwargsr<funr>r=s r0wrapperz+timefun..decorator..wrapperes.#,SIII 2 2 S$1&11111111 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s 8<< functoolsrrJrKr<r>r=s` r0 decoratorztimefun..decoratordsH    2 2 2 2 2 2 2   2r/r.r=r<r>rOs``` r0timefunrQcs0 r/c0eZdZdZeeddfdZdS)synczF the same timefun decorator variation but without async/await Ncfd}|S)z :param logging.Logger: logger you want action name and timing to be logged with :param str: action name to log cNtjfd}|S)Ncztpj5|i|cdddS#1swxYwYdSrErFrGs r0rKz0sync.timefun..decorator..wrapper}sF2clGMMM003///000000000000000000s 044rLrNs` r0rOzsync.timefun..decorator|sH _S ! ! 0 0 0 0 0 0 0" ! 0Nr/r.rPs``` r0rQz sync.timefunts0       r/)r(r)r*__doc__ staticmethodloggerrQr.r/r0rSrSosEt\r/rSFreturnc $K||tdtj}|r't|tsJ|g}t j}n*t|ttfsJt j }ttdtd|||||dd|d{V}| |d{V\} } |d{V} td |||| | | f| | | fS) zYAsynchronous command executor. Returns a tuple (exit_code, stdout_data, stderr_data).Nz/stdin and input arguments may not both be used.r)seconds) max_trieson_errorTstdinstdoutstderrstart_new_sessionz run(%s, stdin=%s, shell=%s) = %s) ValueError _subprocessPIPE isinstancestrasynciocreate_subprocess_shelllisttuplecreate_subprocess_execretry_onBlockingIOError await_for communicatewaitrYr;) commandrarbrcshellinputrIcreate_subprocessprocouterr exit_codes r0runr|s   NOO O  ;'3''''')#;'D%=11111#:1y/C/C/C             D%%e,,,,,,,,HCiikk!!!!!!I LL*  C  c3 r/)looptimeoutc|rtdD]b} tj}|sn7n#t$rYnwxYwtjtjc|tjt|tj r|ntj ||S)zjRun coroutine from a blocking code (outside the event loop). Coroutine will be wrapped in Task. Nr\r~) rangerjget_event_loop is_closed RuntimeErrorset_event_loopnew_event_looprun_until_completewait_forrhrTask)coror}r~_s r0run_corors  |q = =A -//~~''E       "7#9#;#; < < < <  " "tW^44 LDD',t:L:L     s? A  A ceZdZdZdS) CheckRunErrorcd}||j|j|jpd|jpdS)Nz[Command {cmd!r} returned non-zero code {returncode}, Stdout: {output}, Stderr: {error} )cmd returncodeoutputerror)formatrrrdecoderc)self_MESSAGEs r0__str__zCheckRunError.__str__s_ $  ;%%''/4+$$&&.$    r/N)r(r)r*rr.r/r0rrs#      r/rc`Kt|fi|d{V\}}}|dkr||||||S)zJ Asynchronous command executor. Returns output as bytestring. Nr)r|)rt raise_excrIrryrzs r0 check_runrsZ "%W!7!7!7!7777777JSQi GS#666 Jr/cKt|tjtjtjd{V\}}}|dkr |||dS)z Asynchronous command executor. Raises raise_exc if exit code is nonzero. Stdin, stdout and stderr of command are connected to /dev/null. )rarbrcNr)r|rfDEVNULL)rtrcoders r0check_exit_codersy !"" JD!Q qyyig&&&yr/TcK t|fi|d{V\}}}n,#t$rtd|YdSwxYw|r%|dkrtd|||dS |}n,#t $rtd|YdSwxYw|S)zGSafe run command. Returns stdout as string or empty string on errorNzCommand %s failed with OSErrorrz'Command %s failed with exit code %s: %sz#Command %s returned non-utf8 output)r|OSErrorrYwarningstriprUnicodeDecodeError)rtcheck_returncoderIrcryrzresults r0safe_runrs 33F33333333 C 7AAArrB!GG 5wC   r##%% .wrappers  %+--Kr/r.)rrKrs` @r0plainold_lazy_initrs.K Nr/ceZdZdZdZdZdS) PeriodicCheckz Invoke a callback with a certain period and return cached result in between. Raising an exception from the callback does not affect the next check schedule. c||_||_tj|z |_d|_t tj|_ dSr) _cb_coro_check_every_n_secondsr9r:_last_check_timestamp_last_check_resultrrjLock_lock)rcb_corocheck_every_n_secondss r0__init__zPeriodicCheck.__init__*sD &;#%)^%5%58M%M""&' 55 r/cK|4d{Vtj|jz }||jkrVt d|j|jtj|_|j|i|d{V|_|jcdddd{VS#1d{VswxYwYdS)Nz3Timeout %d seconds has expired, doing the check: %s) rr9r:rrrYr;rr)rrHrIdeltas r0__call__zPeriodicCheck.__call__3s\::<< + + + + + + + +N$$t'AAE333 I/M .2^-=-=*0= t0Nv0N0N*N*N*N*N*N*N'* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sBB33 B=B=N)r(r)r*rWrrr.r/r0rr!s<666 + + + + +r/rcfd}|S)Nc$t|Sr)r)rnsecs r0decoratezcache_result..decorateBsT4(((r/r.)rrs` r0 cache_resultrAs#))))) Or/ceZdZdZdS)RecurringCheckStopz: raised by coroutine to stop recurring_check loop Nr(r)r*rWr.r/r0rrHs Dr/rcK t|r!tj|di|d{Vntj|d{VdS#tj$rYdSwxYw)NFTr.)callablerjsleepCancelledError)period period_kwargss r0wait_for_periodrPs F   (- 7 7 7 788 8 8 8 8 8 8 8 8-'' ' ' ' ' ' ' 'u  !ttsA AA#"A#c8K|r|rt|fi|d{VndSNF)r)checkrrs r0should_stop_after_period_passedr[sG   of66 666666666 r/ c fd}|S)z run decorated corotine in a loop every :period: seconds. If more then consecutive_err_limit error occured, exit loop. :param period: :param consecutive_err_limit: :param check_period_first: default false :return: cFtfd}|S)NcKd} tfid{VrdS |i|d{Vd}n#tjtf$rYdSt$r}|dz }|kr t dYd}~dSt|tj r3t d|j |j |j |j nt dYd}~nd}~wwxYwt fid{VrdS)NrTrz-Error count exceeded limit,exiting check loopz+Failed to run %s (%s). stdout=%s, stderr=%szError executing %s)rrjrr ExceptionrY exceptionrhrfCalledProcessErrorrrrrc) rHrIconsecutive_err_cntexccheck_period_firstconsecutive_err_limitrJrrs r0wrappedz3recurring_check..decorator..wrappedps"#  8&2?E,#t.v.........*+,'') .0BCEE DDD'1,'*-BBB((K!#{'EFF D((IGNJJ (()=sCCC!D&9**F6CE? s"/C. C.%C).decoratorosI s! ! ! ! ! ! ! !  ! Fr/r.)rrrrrOs```` r0recurring_checkrcs7%%%%%%%%N r/)backupuidgidallow_empty_content permissionsc lt|tr|}tt5t |d5}|t|dz}dddn #1swxYwY||kr ddddS dddn #1swxYwY|s |st d||dS|rUt|ttj fr|} ntj |tz} tj|| |k t!jtj|j}n>#t$r1tjd} tj| d| z}YnwxYwtj|\} } t-| st d| t15} t3d | d | d zdd 5fd }| |||*|(tj||tj|tj dddn #1swxYwYtj!j"|| #dddn #1swxYwYdS)aAtomically rewrites *filename* with given *data*. If *filename*'s content is *data* already, do nothing. If both *uid* and *gid* are given then resulting file is chowned to given user id and group id. Skip rewrite with empty content if *allow_empty_content* is False. Chmod to given access *permissions* else preserve *filename* 's permissions. Return True if *filename* file was updated, False otherwise rbrNFzempty content: %r for file: %srizParent dir is missing: wbz .i360editr)modedirsuffixprefix bufferingdeletectt5tjjddddS#1swxYwYdSr)r FileNotFoundErrorosremovename)tfsr0cleanupzatomic_rewrite..cleanups/00''Ibg&&&''''''''''''''''''s=AAT)$rhriencoder ropenreadlenrYrrPathLikefspathBACKUP_EXTENSIONshutilcopystatS_IMODEst_modeumaskpathsplitrr4rrcallbackwriteflushchownfilenochmodfsyncrenamerpop_all)filenamedatarrrrrfile old_contentbackup_filename current_umaskdirpathbasenamestackrrs @r0atomic_rewriters ,${{}} # $ $ (D ! ! 3T))CIIM22K 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $     t 5tXFFFu / fsBK0 1 1 E$OO i114DDO Ho... 1,rwx'8'8'@AAKK  1 1 1HQKKM H] # # #=.0KKK  1  h//GX ==   ! !G E' E EFFF  c>     " ' ' ' ' ' NN7 # # # HHTNNN HHJJJ3?c3/// HRYY[[+ . . . HRYY[[ ! ! !- " " " " " " " " " " " " " " ". "'8$$$ 38 4s~B.&B6 B.B B. B B..B25B25+E!!8FFL)B=K$ L)$K( (L)+K( ,1L))L-0L-c tdS#t$rYdSwxYw)Nz/etc/system-release)r read_textrstriprr.r/r0os_release_and_versionrsP)**4466==??? tts25 AAc|p t}|r-tjd|}|r|dSntt d|z)z3Return os version, if can't get it raise ValueErrorz\s*(\d+\.\d+\S*)(\s|$)rz!Can't discover os version from %r)rresearchgroup cache_clearre)release_and_versionrvmatchs r0 os_versionr"st  8 6 8 8B - 3R88  ";;q>> ! " **,,, 82= > >>r/ceZdZdZedZedZedZdZe dZ e de e e ffdZe dee fd Ze de fd Ze de fd Ze d Ze d Ze dZe dZe dZe dZe dZe dZe dZdS) OsReleaseInfoz/etc/os-release)debian)rhelfedoracentos)unknownNct|j5}|D]U} |d\}}|d||<F#t $rYRwxYw dddn #1swxYwYd|vr,t |d|d<dSt |ddf|d<dS)N="ID_LIKEIDlinux)rETC_OS_RELEASErrrre frozensetget)clsdict_flinekvs r0dict_from_filezOsReleaseInfo.dict_from_files3 #$ % %   ;;==..s33DAq wws||E!HH!D                    (y)9)?)?)A)ABBE)    )%))D'*B*B)DEEE)   s5A;AAA; A+(A;*A++A;;A?A?rZc\|jt}tj|jr||ntj}|r|dr|d d}|dkr d|dvrd}||d<d |d|d|d|d <|d vr |j |d <n.|d vr |j |d <n|j|d <nd |d<|j|d <d |d <||_|jS)NrredzRed Hat Enterprise Linuxr&r.z {} {} ({})rr\ PRETTY_NAME) cloudlinuxr(r&r-)ubuntur%r))r4dictrrr4r0r9distrolinux_distributionlowerrrRHEL_FEDORA_CENTOSDEBIANUNKNOWN)r3r4dosids r0to_dictzOsReleaseInfo.to_dictsQ 9 $(FFEw~~c011 5""5))))-//515Q4::<<--//2Du}})Cqt)K)K%"&E$K+7+>+>!adAaD,,E-(???+.+Ai((!555+.:i((+.;i(("+E$K'*{E)$+4E-(CIyr/c6|dS)Nr-rHr3s r0id_likezOsReleaseInfo.id_like6s{{}}Y''r/c6|dS)Nr<rJrKs r0 pretty_namezOsReleaseInfo.pretty_name:s{{}}]++r/cR|ddS)zi :return: OS name, like centos, ubuntu, debian, cloudlinux, redhat in lower case r.r))rHr2rKs r0get_oszOsReleaseInfo.get_os>s" {{}}  y111r/c2|dkS)Nr&rPrKs r0is_rhelzOsReleaseInfo.is_rhelFszz||v%%r/c2|dkS)Nr(rRrKs r0 is_centoszOsReleaseInfo.is_centosJzz||x''r/c2|dkS)Nr>rRrKs r0 is_ubuntuzOsReleaseInfo.is_ubuntuNrVr/c.|dvS)N)r=cloudlinuxserverrRrKs r0 is_cloudlinuxzOsReleaseInfo.is_cloudlinuxRszz||AAAr/cJtjtSr)rrr4_CL_SOLO_EDITION_FILErKs r0is_cloudlinux_soloz OsReleaseInfo.is_cloudlinux_soloVsw~~3444r/c2|dkS)Nr%rRrKs r0 is_debianzOsReleaseInfo.is_debianZrVr/c2|dkS)NolrRrKs r0is_oracle_linuxzOsReleaseInfo.is_oracle_linux^szz||t##r/c2|dkS)N almalinuxrRrKs r0 is_almalinuxzOsReleaseInfo.is_almalinuxbszz||{**r/c2|dkS)NrockyrRrKs r0 is_rockylinuxzOsReleaseInfo.is_rockylinuxfszz||w&&r/)r(r)r*r0r1rDrCrEr4 classmethodr9rrirrHrrLrNrPrSrUrXr[r^r`rcrfrir.r/r0r$r$s&N Y{ # #F"#?@@i %%G E F F[ FS#X[<( #((([(,C,,,[,2s222[2&&[&(([((([(BB[B55[5(([($$[$++[+''['''r/r$r  chunksizec0t|||dS)zReturn hash of the file `filename`, reading it in chunks. * filename is a path to a file; * hash_func is a function that returns hash object (one of hashlib.md5 etc); * chunksize is a size of chunks to read, in bytes. r)file_hash_and_size)r  hash_funcrls r0 file_hashrpks h 9 = =a @@r/c|}d}t|d5} ||}|sn(|||t|z }@ dddn #1swxYwY||fS)aCalculate hash and size of the file `filename`, reading it in chunks. * filename is a path to a file; * hash_func is a function that returns hash object (one of hashlib.md5 etc); * chunksize is a size of chunks to read, in bytes. Return tuple(hash, file size).rrTN)rrupdater hexdigest)r rorlhash_sizer5chunks r0rnrnxs IKKE D h   FF9%%E  LL    CJJ D    ??  d ""sAA,,A03A0c|\}}||kr&tdjdit|S)z0Given login.defs line, return *varname*'s value.z"Expected {varname!r}, got {name!r}r.)rrervars)varname defs_linervalues r0_parse_name_valuer|sJ//##KD%$D=DNNtvvNNOOO Lr/cHtdkrt\a}tS)Nr%)_MIN_UID_get_max_min_uid)rs r0 get_min_uidrs2~~&(( ! Or//etc/login.defsc\d\}}ttjz}tt5|r&t drd\}}dddn #1swxYwY t|5}|D]f}|drttd|}|drttd|}g dddn #1swxYwYn#ttf$rYnwxYw||fS)zGet UID_MIN, UID_MAX from the login.defs file specified as *path*. On error, return default for the current OS values. )i`6)rNUID_MINUID_MAX) r$rLrCr rer" startswithrintr|r)ruid_minuid_maxr(rr6s r0rrs #GW  " " $ $}'G GF *  **  *jll--c22 *) GW***************  $ZZ F4 F F??9--F!"3It"D"DEEG??9--F!"3It"D"DEEG  F F F F F F F F F F F F F F F F Z       G sI)A55A9<A9DA*D; DD  DD DD'&D'zimunify360-captchazimunify360-webshieldclt\fdtjDS)z~ :param excludes: users to exclude in results :return: list: list of pwd.struct_passwd objects representing users cPg|]"}|jcxkrknn |jv |#Sr.pw_uidpw_name).0entryexcludesrrs r0 z(get_non_system_users..sS     el - - - -g - - - - -%-x2O2O 2O2O2Or/rpwdgetpwall)rrrs`@@r0get_non_system_usersrsR())GW      \^^   r/cdt\}fdtjDS)z; :return: list: list of str with system user names c4g|]}|jk |jSr.r)rrrs r0rz)get_system_user_names..s.   W 5L5L 5L5L5Lr/r)rrs @r0get_system_user_namesrsE"##JGQ    #&<>>   r/rc0t\}}||kSr)r)rrrs r0is_system_userrs'))GW =r/d)r1typedct|d5}|dd}|dkrF||dz |ddkr|d|||ds|dddddS#1swxYwYdS)Nzr+rr\r rseekrrendswithr r r5 last_char_poss r0append_with_newliners h   q! A   FF=1$ % % %vvayyD     }}T""  GGDMMM                  B"CCCr ct|d5}|dd}|dkrF||dz |ddkr|d|||ds|dddddS#1swxYwYdS)z>Append *data* to *filename* making sure there is at the end.zr+brr\r Nrrs r0append_with_newline_bytesrs h   !q! A   FF=1$ % % %vvayyE!!  }}U##  GGENNN                  rcd}t|d5}tfd|Dsd}dddn #1swxYwY|rt||S)zAdd *line* to *filename* if it is not present in the file Returns: True if the file was changed, False otherwise. Frc3HK|]}|kVdSrrr_liner6s r0 z&ensure_line_in_file..088U5;;==D(888888r/TN)ranyrr r6changedr5s ` r0ensure_line_in_filers G h  8888a88888 G,Hd+++ N>AAr6cd}t|d5}tfd|Dsd}dddn #1swxYwY|rt||S)zAdd *line* to *filename* if it is not present in the file. Returns: True if the file was changed, False otherwise. Frc3HK|]}|kVdSrrrs r0rz,ensure_line_in_file_bytes..rr/TN)rrrrs ` r0ensure_line_in_file_bytesrs G h  8888a88888 G2!(D111 Nrctj|}t|d5}t d|d5}|D]/}||kr||0tj|j|dddn #1swxYwYddddS#1swxYwYdS)NrwF)rrr) rrdirnamerrrrr r)r r6basedirsfrrs r0remove_line_from_filers;gooh''G h  %$6 ge%%%%   E{{}}$$ "'8$$$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%s6B4A B B4B B4#B $B44B8;B8c,eZdZdZdZefdZdZdZdS)FileLockz` Simple context manager to enable UNIX-specific file locking with flock system call rcZ||_d|_t|d|_||_dS)NFr)rlockedrrr~)rrr~s r0rzFileLock.__init__0s*  sOO  r/cKtj} t|jttzd|_|S#t tf$r}|jtj kr|j tj|z kr&t d|j Yd}~dStjdd{VYd}~nd}~wwxYw)NTz)Failed to lock file %s. Timeout exceeded.r)r9rrr rrrIOErrorerrnoEAGAINr~rYrrrjr)rr?exs r0 __aenter__zFileLock.__aenter__6s  ' 'di7!2333"  W% ' ' '8u|++\DIKK%$777NNCTYEEEEEmA&&&&&&&&&&&&&& ' 's*ACAC/CCcK|jrt|jtd|_|jdSr)rrrrclose)rexc_typeexc_valexc_tbs r0 __aexit__zFileLock.__aexit__NsC ; & $)W % % %  r/N)r(r)r*rW_TIMEOUTrrrr.r/r0rr(sZ H%- '''0r/rc |g}|fdt|Dtj}|d|dd|S#ttf$r%}t d|Yd}~nd}~wwxYwdS)Nc3DK|]\}}|v t|VdSr)ri)rfieldr{fieldss r0rz user_identity.._s?  u JJ  r/rutf8surrogateescapez9Generation of user identity hash failed, invalid data: %s) extendsorteditemshashlibsha1rrjoinrrsreUnicodeEncodeErrorrYr) attackers_ipsourceruid_datahash_alges ` r0 user_identityrXs  !>    &v||~~ 6 6      <>>))009JKKLLL!!### * +    G         4sB%B))C:CCc0tjdkS)Nr)rgetuidr.r/r0 is_root_userrss 9;;! r/maskc#Ktj|} dVtj|dS#tj|wxYwr)rr)r current_masks r0run_with_umaskrwsM8D>>L  s 2Arusernamec~t|tstd|ztj|vrtd t j|}n0#t$r#td|wxYwtj |j |}t|S)z Returns user's home dir if `relpath` is not specified. Otherwise, returns absolute path of `relpath` build from `username`'s home dir :raise ValueError: when user home dir is not exists z#Invalid type for %s, should be str!zInvalid usernamezUser {!r} doesn't exist) rhrirerseprgetpwnamKeyErrorrrrpw_dirr)rrelpathpwabs_paths r0get_abspath_from_user_dirrs h $ $K>IJJJ v+,,,E \( # # EEE299(CCDDDEw||BIw//H >>s A-Brcd} t|}t||d}n>#t$r1}tt |Yd}~nd}~wwxYw|S)NFT)rr relative_torerYrri)rrstatus user_homers r0does_path_belong_to_userrs F-h77  T y))) s1vv Ms38 A3'A..A3ctj|std|z tj|rg t jtj|jj S#t$r)ttj|jcYSwxYwtj |})NzPath %s should be absolute!) rrabspathrer4rgetpwuidrst_uidrrrirrs r0get_path_ownerrs 7??4 ?6=>>>% 7>>$   1 1|BGDMM$899AA 1 1 1274==/00000 1wt$$ %s/B0B65B6riterable chunk_sizec#Kt|}tt||}|r%|Vtt||}|#dSdS)a Generator that splits iterable on N-parts by chunk_size items in each chunk >>> list(split_for_chunk([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], chunk_size=2)) [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] :param iterable: :param int chunk_size: :return: generator: N)iterrlr)rripieces r0split_for_chunkr sp XA :&& ' 'E , VAz**++ ,,,,,r/ct|tr+td|DSt|trt d|DS|S)Nc3>K|]\}}|t|fVdSrfreeze)rkeyr{s r0rzfreeze..s1JJ*#u#ve}}-JJJJJJr/c34K|]}t|VdSrr )rr{s r0rzfreeze..s(22uVE]]222222r/)rhr?r1rrlrm)rFs r0r r sm!T3JJ JJJJJJ At  322222222 Hr/c&eZdZdZiZfdZxZS) Singletonzc Metaclass for creating only one instance of class, when providing the same arguments. c|t|t|f}|j|s(tt|j|i||j|<|j|Sr)r  _instancesr2superrr)r3rHrIr __class__s r0rzSingleton.__call__srF4LL&..1~!!#&& "@% 3"7"7"@###CN3 ~c""r/)r(r)r*rWrr __classcell__)rs@r0rrsI J#########r/rctjdd5}|cdddS#1swxYwYdS)z3 :return str: server's external IP address zhttps://api.ipify.orgr\rN)urllibrequesturlopenrr)rs r0get_external_iprs    7  C C!qvvxx  !!!!!!!!!!!!!!!!!!s&AAAc<d}|||}tj|st d|d|t |d5}|}dddn #1swxYwY|S)z Reads parameter of kernel module from /sys/module/{module_name}/parameters/{parameter} :return str: value of the parameter z(/sys/module/{mod}/parameters/{parameter})mod parameterzCannot find parameter z for module rN)rrrr4rerrr) module_namer _MOD_PAR_PATH param_filepr{s r0get_kernel_module_parameterr#s ?M%%+%KKJ 7>>* % % j8A ;; O    j#  !!  !!!!!!!!!!!!!!! Ls'BBBcd}|D][\}}t|tr%||vs|s|||<d}(t|||}?||vs|sJ|d||||<d}\|S)zPerforms deep update of dict dst with values from src. Does not overwrite subdicts in dst blindly with new dicts in src, but does a deep update of (sub)dict content recursivelyFTz already exists in )rrhr?dict_deep_update)dstsrcallow_overwriteupdatedr7r8s r0r%r%s G  1 a   ||1|A*3q6155  ---- /CFGG Nr/c8eZdZd dZdZdZdZdedefdZd S) TimedCacherct|tsJ||_||_t |_i|_dSr)rhr expirationr1rcache_locks)rr-r1s r0rzTimedCache.__init__s<*i00000$  ]]  r/ct}|jD]J}|j|\}}tj|z |jkr||f||<K||_dS)zClear cache from expired valuesN)rr.r9r- total_seconds)r tmp_cacherr{added_ats r0_collectzTimedCache._collectshMM : 1 1C"joOE8 h&$/*G*G*I*III!& # r/c:t|_i|_dSr)rr.r/rs r0rzTimedCache.cache_clears ]]  r/c|}|r3t|}|t|z }t|S)z Generate key from call arguments :param args: call positional args :param kwargs: call keyword args :return: )rrrmhash)rrHrIseedkws r0 _make_keyzTimedCache._make_keysB   ''B E"II DDzzr/funcrZctfd}tfd}tjr|n|}j|_|S)a  Use it to cache calls to decorated function @TimedCache(expiration=timedelta(minutes=10)) async def func(*args, **kwargs): pass :param func: decorated function :return: NOTE: is not thread safe. chK||}j|}|tjx}j|< tj|jd{VnP#tj $r=|j|urtjx}j|<n j|}YnwxYw   j |\}}ns#t$rftj jkrj d|i|d{V}|t!jfj |<YnwxYw|n#|wxYw|S)NTFlast)r;r/r2rjrracquirer-r1 TimeoutErrorr4r.rrr1popitemr9release)rHrIrlockrrr<rs r0 wrapper_asyncz*TimedCache.__call__..wrapper_async5s..v..C;??3''D|*1,..8t{3' 00!* (E(E(G(G+ 0 0 0 t{3///29,..@t{3//#{3/ 0  0  : $ 3IFAA:::4:$,66 ***666#'4#8#8#8888888F&,dikk&9DJsOOO :   MsEABA C&%C&+FDFA-F>FFFF/cZ||} j|\}}nm#t$r`t jjkrjd|i|}|tjfj|<YnwxYw|S)NFr?)r4r;r.rrr1rCr9)rHrIrrrr<rs r0 wrapper_syncz)TimedCache.__call__..wrapper_syncXs MMOOO..v..C 6 JsO  6 6 6tz??dl22J&&E&222t.v.."($)++"5 3  6 Ms>A'B('B()rrjiscoroutinefunctionr)rr<rFrHrKs`` r0rzTimedCache.__call__(s t       D t       *400 MM  #.r/N)r) r(r)r*rr4rr;r rr.r/r0r+r+s   CQC1CCCCCCr/r+cftjtjtjdS)z Send SIGUSR2 to os.getpid() to shutdown agent process by signal (implies exit code -12). Agent will do failover restart then thanks to systemd (or chkservd) if it needs. N)rkillgetpidsignalSIGUSR2r.r/r0fail_agent_servicerOqs$GBIKK(((((r/c K|dttj}t |d5}|t tjj ||dt d||tjj |fi|d{V}t |dzd5}| d|jt!j|jdddn #1swxYwYdddn #1swxYwY|S) z Runs command and log it's output to the log file :param cmd: :param log_file_mask: :return: str path of log file *rTr`z Popen(%r, %r)Nz.pidz{:d} {} )replacerirrLrrrr?rj subprocessrrYr;rkrrpidpsutilProcess create_timehex)r log_file_mask popen_kwargslive_log live_log_fprxpfs r0run_cmd_and_logr^|s$$S#bikk*:*:;;H h    (0"""&         _c<888'?           (V#S ) ) R HH##HfnTX66BBDDHHJJ                  & Os8BE A*D?3 E?E EE EEEceZdZdZdS)rc `|jdkr7|jr0|dd}|jr |j|d<|j| t j|dS#t$rt|j ddpt|j dd}t|j ddpt|j dd}t|j d dpt|j d d}|j }|r|j p|j }td ||j||YdSwxYw) NPENDINGz%Task was destroyed but it is pending!)taskmessagesource_tracebackr*r(gi_codecr_codegi_framecr_framez+!> Finalizer error in {}() {} at {} line {})_state_log_destroy_pending_source_traceback_loopcall_exception_handlerr__del__AttributeErrorgetattr_coro co_filenamef_linenoco_firstlinenoprintr)rcontextrrframer linenos r0rnz Task.__del__s{ ;) # #(A #BG% E.2.D*+ J - -g 6 6 6  N4    4:~t<< JAAD4:y$777 It<<DDJ D99W J>>E'H.F43FF =DD$+x       sACD-,D-N)r(r)r*rnr.r/r0rrs#r/rcfd}|S)zReturn async callback which waits for *seconds*. Usage: @retry_on(Error, on_error=await_for(seconds=PAUSE_INTERVAL), timeout=T) async def coro(): 'here's something that may raise Error.' c<Ktjd{VSr)rjr)rHr]s r0pausezawait_for..pauses)]7+++++++++r/r.)r]r{s` r0rqrqs#,,,,, Lr/cftgstdfd}|S)a5 Retry the function call on exception (or exceptions, if given in tuple) at most *max_tries*. Await *on_error* (if set) for each exception. If *timeout* is set, stop all attempts in *timeout* seconds. If *silent* is set to True - don't raise exceptions after max tries or timeout. zSet any of max_tries, timeoutctjfd}tjfd}tjr|S|S)NcNK rtj z} stjdnt d dzD]} rg|tjz }|dkr$t j|i||d{VcS s t jrdn|i|d{VcS}#t jt j f$r$r@}| kr srd|  ||d{VYd}~d}~wwxYwdS)Nrrr Timeout exceeded when calling %s0Max tries exceeded when calling %s with error %s) r9r: itertoolscountrrjrrBrr rHrIend_timerremaining_timerrr<r>r^r_silentr~s r0rFz2retry_on..decorator..wrapper_asyncs 6>++g5!- """1i!m,,# /# / /;)1DN4D4D)D)A--)0)9 $d 5f 5 5~***$$$$$$$*"&-&: :!$" # $F!"!"!"&*T4%:6%:%::::::::::,g.DE / / /I~~%! II!, $ #   +&hsA......... //# /# /s?C 4C D""6DD"c rtj z} stjdnt d dzD]} rH|tjz }|dkr |i|cS st rdn |i|cSX#$r:}| kr srd|  ||Yd}~d}~wwxYwdS)Nrrrr)r9r:rrrrBrrs r0rHz1retry_on..decorator..wrapper_sync sm 6>++g5!- """1i!m,, ) ) ) 5)1DN4D4D)D)A--#'4#8#8#8888#)"&2 2!$" # $F!"!"!" $tT4V44444 ) ) )I~~%! II!, $ #   + a((( )' ) )s%B.)BC 0CCrMrrjrI) r<rFrHrr>r^r_rr~s ` r0rOzretry_on..decorators   & /& /& /& /& /& /& /& /& /& /  & /P   " )" )" )" )" )" )" )" )" )" )  " )H  &t , ,   r/)rre)rr_r^r~rr>rOs`````` r0roross  7# $ $:8999R R R R R R R R R R h r/ctjfd}tjfd}tjr|n|S)zhIf func throws an exception it is catched, converted to a string and returned as a result of a call.crK |i|d{VS#t$r}t|cYd}~Sd}~wwxYwrrreprrHrIrr<s r0rFz,stub_unexpected_error..wrapper_async<sg t.v........ .   77NNNNNN s  6166cb |i|S#t$r}t|cYd}~Sd}~wwxYwrrrs r0rHz+stub_unexpected_error..wrapper_syncCsQ 4((( (   77NNNNNN s .)..r)r<rFrHs` r0stub_unexpected_errorr8s_T _T $7== O==<Or/c2 tjfd}|S)zkA decorator that logs uncaught exceptions ignoring them otherwise. CancelledError is not handled. Nctjfd}tjfd}tjr|S|S)Nc K |i|d{VS#tj$r$r'}dtdd|Yd}~dSd}~wwxYwNzIgnoring exception from %s: %sr*r)rjrrprHrIrrr log_handlers r0rFz>log_error_and_ignore..decorator..wrapper_asyncVs !T426222222222)       4D.&99 s AA  Ac t |i|S#$r'}dtdd|Yd}~dSd}~wwxYwr)rprs r0rHz=log_error_and_ignore..decorator..wrapper_synccs tT,V,,,    4D.&99 s 727r)rrFrHrrs` r0rOz'log_error_and_ignore..decoratorUs                          &t , ,   r/rYr)rrrOs`` r0log_error_and_ignorerMs: &       < r/cfd}|S)z'Abort the agent service on *exception*.cLtjfd}|S)NcK |i|d{VS#$r/}t|Yd}~dSd}~wwxYwrr)rHrIrabortrrs r0rKz2abort_agent_on..decorator..wrapperzs !T426222222222     ###  s A$AArL)rrKrrs` r0rOz!abort_agent_on..decoratorysC            r/r.)rrrOs`` r0abort_agent_onrvs*       r/cRtjdd|S)zPascalCase to snake_casez([a-z])([A-Z])z\1_\2)rsubrB)strings r0 snake_casers# 6"Hf 5 5 ; ; = ==r/)exec_expr_with_empty_iterc'K|s|rdg}nt|t}ddlm}|j5|D]}||g|REd{V ddddS#1swxYwYdS)a] Get iterator over results of sql expression expr. Given iterable will be split for chunks and we will return iterator containing results of all split queries. Useful for sql selects with in_() in order to avoid too many sql variables error. If exec_expr_with_empty_iter is True and iterable is None(empty) we will process expression once, passing here chunk=None expr(None, *args) :param expr: :param iterable: :param exec_expr_with_empty_iter: if iterable is None(empty) process given expression once, passing here chunk=None expr(None, *args) :return: Nrrinstance)r CHUNK_SIZE_SQL_QUERYdefence360agent.modelrdb transaction)exprrrrHchunksrrvs r0get_results_iterable_expressionrs& L1L 6JKKK......  " "** * *EtE)D))) ) ) ) ) ) ) ) ) *******************sA##A'*A'rcd}ddlm}|j5t ||D] }|||g|Rz }! dddn #1swxYwY|S)z Get number of results of sql expression expr. Given iterable will be split for chunks and we will return number of results of all split queries. Useful for sql delete with in_() in order to avoid too many sql variables error rrrN)rrrrr execute)rrrrHrrrvs r0execute_iterable_expressionrsG......  " "44$X*EEE 4 4E ttE)D)))1133 3GG 4444444444444444 Ns3A""A&)A&cXtj|dddzS)Nr\nr)rfsencoderRrs r0encode_filenamers% ;t||D%00 1 1E 99r/cbtj|ddddS)Nr%rr)rfsdecoderRrs r0decode_filenamers+ ;t  SbS ! ) )% 6 66r/cNtjtj|Sr)base64 b64encoderrrs r0base64_encode_filenamers  BK-- . ..r/b64namechttjtj|Sr)rrrr b64decode)rs r0base64_decode_filenamers%  F,W5566 7 77r/cV tj|}n#t$rd}YnwxYw|S)zS Like pwd.getpwnam(username) but returns None instead of raising KeyError. N)rrr)rrs r0rrsAh''  Ms  &&c>tt|||S)zH Put the specified `value` inside the [`low`, `high`] interval. )maxmin)r{lowhighs r0cliprs s5$ % %%r/r.crfd}||i|}|||S)z Use this function in plugin initialization instead of loop.create_task to be able to see the exceptions from the specified coroutine. c|sA|/d||ddSdSdS)Nz1Unhandled exception during plugin initialization!)rcrrb) cancelledrrm)rbr}s r0_log_exceptionz6create_task_and_log_exceptions.._log_exceptionsv~~ DNN$4$4$@  ' 'L!%!1!1        $@$@r/) create_taskadd_done_callback)r}rrHrIrnew_tasks` r0create_task_and_log_exceptionsrsY     d 5f 5 566H ~... Or/cfd}|S)a5 Create coroutine from regular function Useful to pass functions to APIs requiring coroutines Note: coroutine will still block event loop in main thread. For most blocking functions, run_in_executor should be considered instead :param function: :return: coroutine running function cK|i|Srr.)rHrIfunctions r0rzmake_coro..coro sx((((r/r.)rrs` r0 make_corors#))))) Kr/cK|tkr tj}n tj}|dt |ddx}rd|dnd||t jtd{VdS)Nz7Failed to copy data%s to modsec ruleset dir %r, try: %sr z ()r)COPY_TO_MODSEC_MAXTRIESrYrrrprjr_MODSEC_COPY_FAILURE_TIMEOUT)rrr>fns r0log_failed_to_copy_to_modsecrs ###lnCA$S*d;;;rD R "   -4 5 5555555555r/c tt5tstr/t dr ddddSdddn #1swxYwYdS)NrTF)r rer$rUr[r"rr.r/r0is_centos6_or_cloudlinux6r!s *    # # % % )6)D)D)F)F ll%%c**   5sABB B) err_buf_sizerc 4Kd}t|}tj|dtjjtjjd|d{V} tj||j||j23d{V}|WV 6 |d{V}|dkr%t||dd |dS#|d{V}|dkr%t||dd |wxYw)z Start *cmd*, yield its stdout line by line [b' '] If *cmd* return nonzero exit status, raise CheckRunError with the last *err_buf_size* lines from stderr. cJK|23d{V}||6dSr)append)pipebufr6s r0read_pipe_intoz1readlines_from_cmd_output..read_pipe_into5sL       $ JJt    $$s")maxlenT)rdrbrcNrr/) rrjrnrSrgrrcrbrsrr)rrrZrerr_bufrxr6rs r0readlines_from_cmd_outputr+s<(((G/ !&!&         D I NN4;@@AAA+       $JJJJJ&+ 99;;&&&&&& ?? Cchhw6G6GHH H ? 99;;&&&&&& ?? Cchhw6G6GHH H H H H Hs*C:BCADr\)r^delaycKtd|dzD]3}||d{V}|s!||krtj|d{V0|cSdS)z Retry *predicate_coro(*args)* until it becomes true, but no more than *max_tries* attempts. Sleep for *delay* seconds before the next *predicate_coro()* call. Return whether the predicate became true. rN)rrjr)predicate_coror^rrHattemptrs r0finally_happenedrMsIM**%~t,,,,,,, 'I---&& & & & & & & &  r/'cKt|dD]-\}}|WV||zdkrtjdd{V.dS)z6Yield to the event loop every *chunk_size* iterations.r)r?rN) enumeraterjr)rrritems r0 nice_iteratorr]soXQ///##4 Nq -"" " " " " " " "##r/ceZdZdZdZdZdS)LazyLocka Descriptor object to share async Lock between client objects. Used in order to achieve lazy evaluation of the lock and share state between it's clients. Using asyncio.Lock in client code directly: >>> class Foo: >>> lock = asyncio.Lock() leads to an unclear error ([Errno 9] Bad file descriptor), when trying to move this Lock during demonization process. cd|_dSr)rr6s r0rzLazyLock.__init__vs  r/cN|jstj|_|jSr)rrjr)rrowners r0__get__zLazyLock.__get__ys!z ( DJzr/N)r(r)r*rWrrr.r/r0rrgs<  r/rctj||x}r'|dSdS)Nr)rrrr)regexrms r0_get_system_package_versionrsA IeV $ $$q"wwqzz!!!""r/c~tstrddgdfSddgdfS)Nz dpkg-queryz-lz(?m)^ii\s+{}\s+(\S+).*rpmz-qz{}-([\d\.]*-\d*))r$rXr`r.r/r0_get_cmd_n_regexrsJ  4M$;$;$=$=4t$&?@@ 233r/ceZdZdZdS)FirewallDisabledExceptionz;Exception in case of using firewall api, when it's disabledNrr.r/r0rrsEEEEr/rc<tfd}|S)NcKtjdrtd|i|d{VS)Nz!/var/imunify360/firewall_disabledz"Not available in the current build)rrr4r)rHrIr<s r0rKz(check_disabled_firewall..wrappers\ 7>>= > > +4 T4*6*********r/r)r<rKs` r0check_disabled_firewallrs3 4[[++++[+ Nr/cKt\}t|t|zddd{Vfd|DS)a Retrieves the version of the specified system packages using a command and regex specific to the current system. Parameters: packages (Set[str]): A set of package names to retrieve version for. Returns: A dictionary mapping package names to their corresponding version strings, or None if the package is not installed or version information cannot be retrieved. F)r~rNcXi|]&}|t|'Sr.)rr)r package_namerversion_regexps r0 z(system_packages_info..sK     1  ! !, / /     r/)rsafe_run_with_timeoutrl)packagesrrrs @@r0system_packages_infor s+,,C( d8nnb5F     %    r/cK tjt|fi||d{VS#tj$r|d|YdSwxYw)Nrz#Command %s failed: Timeout occurredr)rjrrrB)rtr~r>rIs r0r r s% W ' ' ' '              17;;;rrs&+A  A nc#K|dkrtdt|}tt||x}r%|Vtt||x}#dSdS)Nrzn must be at least one)rerrlr)rritbatchs r0batchedrs  1uu1222 hBr1 && &% r1 && &%r/rFc#RKt|D]}fd|DVdS)Nc"i|] }|| Sr.r.)rr7rFs r0r z batched_dict..s&&&1q!A$&&&r/)r)rFrrs` r0 batched_dictrsKA''&&&&&&&&&&&''r/cn tjddgd}|d}|s?t drtjddgd}d|vrd}|S#t $r&}td |Yd}~d Sd}~wwxYw) Nhostnamez-fT)text)z.cloudwaysapps.comz.cloudwaysstagingapps.comz/usr/local/sbin/apminfo Cloudwaysz$Error while checking environment: %sF) rf check_outputrrrr4rrYr)r _is_cloudwaysrrs r0 is_cloudwaysrs+  T   %'' !)) ?   %&;!r:s7   ********////////::::::::::222222222222''''''                      GCx     8 $ $ d0116d344 "d#BCC$899D Q     K K K K4T    4        00 3u 0000f 0      K2    (5  5    .; ' ' ' ' ' ,   ++++++++@        :?3333v   OOO OOOOdQ ? ?C ? ? ? ?h'h'h'h'h'h'h'h'X%[4 A A A58 A A A A A #### 38_ ####26<     $)#         5 T         5 T    %%%--------`0E6D&3#$ % % % , ,h ,C ,) , , , ,    ########"R   !!! !"2eeeeeeeeP )))B7<B   $   ggggTPPP*$-$&&&&R%7&>>> 6;*****@';&:::777//%////8E8d8888&&&i(4      6 6 6Q %(III cIIIID=>Q      ####0""" Q44 4FFFFF FFF   D07=l     'DcN's'''' Q r/