dZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z mZddlmZddlmZddlmZmZddlmZddlZdd lmZddlZddlZddlZdd lmZdd l m!Z!m"Z"dd l#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*ddl+m,Z,ddl-m.Z.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5ddl6m7Z7m8Z8m9Z9ddl:m;Z;mZ>m?Z?ddl@mAZAmBZBddlCmDZDmEZEmFZFmGZGddlHmIZIddlJmKZKddlLmMZMddlNmOZOmPZPddlQmRZRddlSmTZTmUZUmVZVddlWmXZXmYZYddlZZZdZ[ede'j\zZ]d Z^ej_e`ZaePeO!eajbZcGd"d#Zde d$Zeefhd%Zgd&Zhd=d(Zid=d)Zjd*Zkd+Zld,Zmd-Znd.Zod/Zpd0Zqd'ee5ererffd1Zsd2e5fd3Ztd4Zud5Zvd6erd'dfd7Zwd8Zxd9Zyd:Zzd;Z{d<Z|dS)>u  This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.  If not, see . Copyright © 2019 Cloud Linux Software Inc. This software is also available under ImunifyAV commercial license, see N)ThreadPoolExecutor)contextmanagersuppress)partial)Path)CalledProcessError check_output)Tuple) AlreadyLocked)files)health inactivity)ConfigsValidatorCoreMergerModel SimpleRpc) HookEvent) LicenseCLN) MessageSink MessageSource)g)IndependentAgentIDAPI)TheSink)instancesimplification tls_check)NonRootRpcServerNonRootRpcServerAV RpcServer RpcServerAV is_running)persistent_statesystemd_notifier)Taskcreate_task_and_log_exceptions is_root_useris_systemd_boot)shutdown_process_pools)is_db_corrupted)EXITCODE_GENERAL_ERROR)DAY rate_limit) flush_sentry)MalwareHitStatusMalwareScanResourceTypeVulnerabilityHitStatus) MalwareHitVulnerabilityHiti4z%s.is_corruptedzImunify360 database is corrupt. Application cannot run with corrupt database. Please, contact Imunify360 support team at https://cloudlinux.zendesk.com)periodceZdZdZdZdS) TaskFactoryc,t|_dSN)setpool)selfs @/opt/imunify360/venv/lib/python3.11/site-packages/imav/server.py__init__zTaskFactory.__init__gsEE ct||}|j|||jj|S)Nloop)r%r:addadd_done_callbackdiscard)r;rAcorotasks r<__call__zTaskFactory.__call__jsFDt$$$ d ty0111 r>N)__name__ __module__ __qualname__r=rGr>r<r6r6fs2r>r6c#K dVdS#t$r;}td||tj|Yd}~dSd}~wwxYw)z)Log *message* on any error & suppress it.Nzcaught error %r on %s) Exceptionloggererror sentry_sdkcapture_exception)messagees r<log_and_suppress_errorrTqsq(  ((( ,a999$Q'''''''''(s A0A  A>dnfrpmyumrpm2cpio#returnct tj}|dD]} |}n!#tjtjf$rY5wxYw|t vrztd||j  | t#tj $r*t d||j tYwxYwdS#tjtjf$rYdSt$r&}t d|Yd}~dSd}~wwxYw)zWait for child rpm/yum/dnf processes to finish before exiting. Exiting while a child package-manager process holds the Berkeley DB lock corrupts rpmdb (BDB1507). See DEF-39911. T recursivezAWaiting for child %s (pid=%d) to finish to avoid rpmdb corruptiontimeoutz'Child %s (pid=%d) did not finish in %dsz.Error waiting for package manager children: %sN)psutilProcesschildrenname NoSuchProcess AccessDenied_PACKAGE_MANAGER_PROCESS_NAMESrNinfopidwait_PACKAGE_MANAGER_WAIT_TIMEOUTTimeoutExpiredwarningrM)currentchildrcrSs r<"_wait_for_package_manager_childrenros L.""%%%55  E zz||(&*=>    555 0I  JJ'DJEEEE,NNA 5 6   *  &"5 6     LLLGKKKKKKKKKLsd+C*AC*A!C* A!!-C*B+*C*+6C$!C*#C$$C**D7 D7D22D7ctjdsdStjdtjD}fd|D}t dt|t||D].}t d|j|j |j / tj }| d}|rt d t||D]j} t d |j||J#tjtjf$rYgwxYwdSt d dS#t$$r&}t d |Yd}~dSd}~wwxYw) zLog debug information about threads and child processes at shutdown. This helps diagnose why the process might hang during shutdown. DEBUGNc:g|]}||SrK)is_alive.0ts r< z,_log_shutdown_debug_info..s%FFF1FQFFFr>c.g|]}|js|k|SrK)daemon)rurvcurrent_threads r<rwz,_log_shutdown_debug_info..s456.5H5H5H5H5Hr>z@Shutdown debug: %d threads alive (%d non-daemon, excluding main)z& Thread: name=%r, daemon=%s, ident=%sTr\z"Shutdown debug: %d child processesz+ Child process: pid=%d, name=%r, status=%sz"Shutdown debug: no child processesz'Could not enumerate child processes: %s)rget threadingrz enumeraterNrglenrcryidentr`rarbrhstatusrdrerMrl) alive_threadsnon_daemon_threadsrvcurrent_processrbrnrSrzs @r<_log_shutdown_debug_infors 5>>-//NFF 3 5 5FFFM  KKJ M     4 F H G     E .**"++d+;;  > KKAFAEFE;8F:E;;FF G &GG 2c||rdStd| tn#t$rYnwxYwt jddS)uDaemon thread that force-exits if shutdown exceeds *deadline* seconds. This is defense-in-depth: if the asyncio event loop or any shutdown phase hangs (e.g. a task survives CancelledError — see DEF-40570), the process is killed regardless. Nz9Shutdown watchdog: deadline of %ds exceeded, forcing exit)rirNrOr.rMos_exit)deadline stop_events r<_shutdown_watchdogrszx   LLC       HQKKKKKsA AAc Ktj}tjtt|fd}|t d5tj tj dddn #1swxYwYt dtjt d5tjd4d{Vdt"vrBt"jt"jd{Vdddd{Vn#1d{VswxYwYdddn #1swxYwYt+|d D]}t d 5tjd4d{Vt d |jj|jj|j|d{Vdddd{Vn#1d{VswxYwYdddn #1swxYwYt d 5t d tjd4d{V|d{Vdddd{Vn#1d{VswxYwYdddn #1swxYwYt d5tjd4d{Vt7jd{Vdddd{Vn#1d{VswxYwYdddn #1swxYwYt#jdx}Ct d5tj|dd{Vdddn #1swxYwYt d5|dddn #1swxYwYt?| t dtjdS)NT)targetargsryz)marking the start of the shutdown processzshutdown task starting, pid=%szclosing external sources sensor_serverc|jSr8)SHUTDOWN_PRIORITY)ps r<z _shutdown_task..s A4Gr>)keyzshutting down pluginz$Shutting down %s.%s (priority %d)...zdraining message queuezShutting down TheSink...zshutting down IAID APIweb_server_restart_taskzwaiting for web server restart<r^z stopping loopzshutdown task finished, pid=%s)!r|EventThreadr_SHUTDOWN_DEADLINEstartrTr sensor shutting_downtimerNrgrgetpidasyncior_rrclose wait_closedsorted __class__rIrHrshutdownrr{wait_forstopr.r9)rAthe_sink plugin_list stop_watchdogwatchdogplugin restart_tasks r<_shutdown_taskrsO%%M! - 0H  NN  K L L11 ##DIKK000111111111111111 KK0")++>>> : ; ;44?2&& 4 4 4 4 4 4 4 4!##%%'''o11333333333 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4444444444444444*G*GHHH ( ( #$: ; ; ( (r** ( ( ( ( ( ( ( ( :$/$-,  oo''''''''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 8 9 9&& .///?2&& & & & & & & & &##%% % % % % % % % & & & & & & & & & & & & & & & & & & & & & & & & & & &&&&&&&&&&&&&&&& 8 9 933?2&& 3 3 3 3 3 3 3 3'022 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 33333333333333337888 E #$D E E = ="<<<< < < < < < < < = = = = = = = = = = = = = = =  0 0 NNN KK0")++>>>>>s1BB BE5:A EE5 E" "E5%E" &E55E9<E9#H>>AH!H>! H+ +H>.H+ /H>>I I 5KJ;)K; K KK KKK2M L9'M9 M MM MMMN//N36N3 O**O.1O.ctd|tj}tj||_d|_tj|_ trd|_ nd|_ tj j|_ |nC#t"$r6tdt'jt*YnwxYwt-jtj jdS)NzRun as daemon [pidfile = %s]FTz*PID file already locked by another process)rNrgry DaemonContextpidfile PIDLockFile prevent_corer FILE_UMASKumaskr(detach_processdefence360agent internalsget_fdsfiles_preserveopenr rOsysexitr+gccollect reconfigure) pidfilepathdcs r< _daemonizer&s  KK. <<<    B++K88BJBOBH!! '18@@BBB)  ))) ABBB '((((()JLLL$0022222s1C=DDc<Ktjd{VdS)zPerform update files on start.N)r !update_all_no_fail_if_files_existrKr>r<_initial_files_updater?s-  1 3 3333333333r>cj|tj|tjdSr8)run_until_completerrun_in_executorrresetr@s r<_tls_check_resetrDs6&tY_==r>c fd|DS)Nc4g|]}t||SrK) isinstance)rurpclasss r<rwz$plugin_instances..Ps( 5 5 5!z!V44 5A 5 5 5r>rK)objsrs `r<plugin_instancesrOs 5 5 5 5t 5 5 55r>cd|D}t|t}|D]E}td||||Ft ||}t|t}|D]F}td|||||G| |||fS)Nc"g|] }| SrKrK)ru plugin_classs r<rwz"_start_plugins..TsAAA,||~~AAAr>zCreating sink %rzCreating source %r) rrrNrgr create_sinkrr create_sourcer)rAplugin_classespluginssinkssrsourcess r<_start_pluginsrSsAA.AAAG Wk 2 2E 55 &***  d 3 34444ud##Hw 66G AA (!,,, h ? ?@@@@ NN UG ##r>rctdtjrtt f}nt tf}|D]+}|| ||,dS)NzStarting RpcServers...) rNrgrSOCKET_ACTIVATIONr!rr rrcreate)rAr rpc_serversrpcs r< _start_rpcrhsv KK()))"4"$67  "23 <<  4 : :;;;;<c tddgt|zdditj}n_#t$r}t |j}Yd}~n.s# 0 0 0$4 0CII 0 0 0r>)r listrenvironrbytesoutputFileNotFoundErrorrNrlIOErrorstripsplitr9)r outrSlinespidss r<_get_pids_openrrs  UOd5kk )-<<    AHoo ?@@@   IIKK  e $ $E 0 0% 0 0 0D D ??s 14 BA)B BBcFtrtj}|dkrtj|}t tjtj }g}|D]} tj|}n#tj $rY)wxYw| }|r|}nd}| ||dt|zf t|5} | } dddn #1swxYwYn#t t"f$rd} YnwxYwt%dt&jd|d|dt|d|d | d t+jt.t1t2j rt6s9t:t>t6 nt:!t>t+jt.dStEtF5t6$ddddS#1swxYwYdS) NrNonezparent process = %sz Instance of z% is already running. Parent process "z " with pid "z". Sockets are in use by z. z file contents z pid)db_path)%r"rgetppidr`rarcrr SOCKET_PATHNON_ROOT_SOCKET_PATHrdparentappendstrrreadOSErrorrthrottled_log_errorrSVC_NAMErrr+r*rr_DB_IS_CORRUPTED_FLAGexistsrNrO_DB_IS_CORRUPTED_MSGtouchrlrrunlink) rppidrpids_used_socketprocess_used_socketrh_pr _local_parent _parent_namefile written_pids r<_check_able_to_startrs||--z|| 199^D))..00F-%y'E   #% '   .--CC+H #  *#0#5#5#7#7LL#)L#** -L0A0AA #']].d"&))++K...............W% # # #"  #   MMMFFDD+,,,,GGKK     H+ , , ,uz*** +$++-- 1 LL- . . . ! ' ' ) ) ) ) NN/ 0 0 0 '((((( ' ( ( + + ! ( ( * * * + + + + + + + + + + + + + + + + + +sZ;BB"!B"E D>2 E >EE EE E E /JJJrc ts3tdtjt t }tjj |j |j stj drHtjj|j ptj dtjt"t%|j|jr7t+|jt-jt,jjt4jt;jt=jst4j tCj"}tj#}|$tKtMd|r|dznd|'tQ tS|tTj+,tZj.t_|taj1|2| tfthfD] }| n]#tjj6$rK}t7dtq|tjt Yd}~nd}~wwxYw|2tsj:std  |2twnP#trj<$r>}t7d |tjt Yd}~nd}~wwxYwtzj>?tjAt||\}}} t||td tjEtjGd } t||jI|  tjKn2#t$r%}t7d|Yd}~nd}~wwxYwt|tt|||| z|PtdtdtdtCjR|D} | rtdt| | D]} | Ttt5|2tCjV| ddddn #1swxYwYt|dd} | r1td| Xd dtdttdtt|[tddS#tdtdtCjR|D} | rtdt| | D]} | Ttt5|2tCjV| ddddn #1swxYwYt|dd} | r1td| Xd dtdttdtt|[tdwxYw)zCommon function for agent service startup. plugin_classes is a list of classes implementing message processing plugins. init_actions is a coroutine that will be called prior to starting RPC and message processing.z5Imunify agent could be started by the root user only!IMUNIFY360_LOGGING_CONFIG_FILE ) max_workersz0Failed to stop pending cleanup/patch. Reason: %sNz=Essential files are missing. Performing initial files update.z*Failed to perform initial files update: %szMessage Bus startedF)versionresidentz!Failed to remove unused locks: %sz loop stoppedzStarting executor cleanupc:g|]}||SrK)donerts r<rwzstart..$s%FFFQVVXXF1FFFr>zCancelling %d pending tasksg@r^_default_executorz Shutting down ThreadPoolExecutorT)ricancel_futuresz"Shutting down ProcessPoolExecutorszExecutor cleanup completezEvent loop closed)\r'rNrgrrr+ parse_clirr setLogLevelverbose log_configrrr{update_logging_config_from_filesetrecursionlimit_MAX_RECURSION_DEPTHrrryrr$notify AgentState DAEMONIZEDr rstartingrr is_registered unregisteredrget_event_loop cpu_countset_default_executorrminset_task_factoryr6rrdbinitrrvalidate_configs_on_startrupdate_merged_configr_stop_pending_cleanup_stop_pending_patchrPeeweeExceptionrOreprr essential_files_existr UpdateErrorrtrack set_timeoutrINACTIVITY_TIMEOUTrrr AgentStartedrVERSIONr&process_messager#remove_unused_locksrM_setup_signal_handlersrr run_foreverr all_tasksr~cancelrrigetattrrr)ror)r init_actionsrrA_cpu_stop_outdatedrSrrr agent_startedpendingrFexecutors r<rrsa >>) KLLL '((( ;;D$00>>>  "*..)IJJ !(HH O Orz~~.NOO   .///&&& {H4<    0 ; FGGG M49;;'''  # % %% ""$$$  ! # #D <>>D s24/FtaxxQ'G'GHHH +--(((`) $$$!$'''#%%%  /// -#8:M"N ! !     !- - - - LLBDGG    H+ , , , , , , , , -&&u'B'D'DEE 1 KKO    1''(=(?(?@@@@$ 1 1 1 I1MMM/00000000 1 $$Y%ABBB#1$#G#G %4""" )***!.L5    ' (*M    A  0 2 2 2 2 A A A LL > >  8999     /000 """ +,,,  '(((((M  /000 """GFg/55FFF  L KK5s7|| D D D   )$$ L L'' Wc(J(J(JKKK L L L L L L L L L L L L L L L4!4d;;  ? KK: ; ; ;   5  > > >  8999     /000 """ +,,,  '((((s3A7[+K[L!AL[L!!A[%!N[O4O [OB [5R [ R8R3.[3R88A[.*W$$W(+W(Ba1*^ a1^ a1^ Ca1cj tjdS#t$r}ddlm}t jt|}|||t t|tj tYd}~dSd}~wwxYw)Nr) execute_hooks)rO)rvalidate_config_layersrMdefence360agent.hooks.executerOrAgentMisconfigr9rrNrlrrrr+)rArSrOagent_misconfigs r<r4r4Is)/11111 )))??????#2aAAA  o > >???s1vv '((((((((( )s B2BB--B2cdfd}tjtjtjtjfD]}|||||dS)NFcs/dtd|t|dStd|dS)NTz Caught %sz9Caught %s. Shutdown task is already running, please wait.)rNrgr&)rAsigcalled shutdowntasks r< _sighandlerz+_setup_signal_handlers.._sighandlerXs] F KK S ) ) )3D,GGFFF KKK     r>)signalSIGINTSIGTERMSIGUSR1SIGUSR2add_signal_handler)rArXrYrVrWs ` @r<rCrCUsp F       v~v~v~N== [$<<<<==r>c<tjd}|ddddd|d d d |d dd|dd|tjddS)NzRun imunify agent) descriptionz-vr"countrzLevel of logging. Each value corresponds to:1 - console only log level,2 - previous plus add network log,3 - all previous plus add process message log,4 - all previous plus add debug log)destactiondefaulthelpz--daemon store_truez run as daemon)rdrfz --pidfilez/var/run/imunify360.pidzuse with --daemon)rerfz --log-configzlogging config filename)rfr)argparseArgumentParser add_argument parse_argsrargv)parsers r<r r is  $1D E E EF   2      ctjtjtjktjtjj k}tj |tj dS)zP Get back to FOUND all malware hits which have stuck in CLEANUP_STARTED N) r2selectwhererr/CLEANUP_STARTED resource_typer0FILEvalue set_statusFOUNDhitss r<r6r6sb     $ $-== $;$@$FF  D$ 0 677777r>ctjtjtjk}tj|tjdS)zZ Get back to VULNERABLE all vulnerabilities which have stuck in PATCH_IN_PROGRESS N)r3rorprr1PATCH_IN_PROGRESSru VULNERABLErws r<r7r7sP  " $ $ * *#9#KK  D&<&GHHHHHr>)rZN)}__doc__rhrrloggingrrZrr|rconcurrent.futuresr contextlibrr functoolsrpathlibr subprocessrr typingr rylockfiler daemon.pidfiler` defence360agent.internals.loggerrr defence360agent.apir r defence360agent.contracts.configrrrrr%defence360agent.contracts.hook_eventsr!defence360agent.contracts.licenser!defence360agent.contracts.pluginsrr&defence360agent.internals.global_scoperdefence360agent.internals.iaidr"defence360agent.internals.the_sinkrdefence360agent.modelrrrdefence360agent.simple_rpcrrr r!r"defence360agent.subsysr#r$defence360agent.utilsr%r&r'r("defence360agent.utils.safe_fileopsr)defence360agent.utils.check_dbr*defence360agent.utils.clir+defence360agent.utils.commonr,r-defence360agent.sentryr.imav.malwarelib.configr/r0r1imav.malwarelib.modelr2r3rPr&rrr getLoggerrHrNrOrr6rT frozensetrfrjrorrrrrrrrrrrrrrr4rCr r6r7rKr>r<rs*   111111////////77777777 """""" ''''!!!!!!22222222<;;;;;888888HHHHHHHH444444@@@@@@666666EEEEEEEEEEFEEEEEEE FEEEEE::::::<<<<<<88888888////// ?>>>>>>>.;<<%  8 $ $,jj,,,V\::((("++L+L+L!M!M " L L L LF0E0E0E0Ef(7?7?7?t3332444 666$E'42E,F$$$$*