PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/local/cpanel/scripts
Viewing File: /usr/local/cpanel/scripts/manage_greylisting
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - scripts/manage_greylisting Copyright 2022 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited package scripts::manage_greylisting; use strict; use Try::Tiny; use Getopt::Long (); use Cpanel::JSON (); use Cpanel::ForkAsync (); use Cpanel::SafeDir::MK (); use Cpanel::IP::GreyList (); use Cpanel::LoadModule (); use Cpanel::GreyList::DB (); use Cpanel::GreyList::Client (); use Cpanel::GreyList::Config (); use Cpanel::GreyList::CommonMailProviders (); exit run(@ARGV) unless caller(); sub run { my @cmdline_args = @_; return usage(1) if !@cmdline_args; unless ( $> == 0 && $< == 0 ) { return usage( 1, "[!] This program can only be run by root!\n" ); } my $opts = {}; Getopt::Long::GetOptionsFromArray( \@cmdline_args, 'init|initialize' => \$opts->{'initialize'}, 'reset' => \$opts->{'reset'}, 'help|h' => \$opts->{'help'}, 'trust|t=s@' => \$opts->{'trust_common'}, 'import|import_trusted_hosts=s' => \$opts->{'import_trusted_hosts'}, 'export|export_trusted_hosts' => \$opts->{'export_trusted_hosts'}, 'export_to=s' => \$opts->{'export_to'}, 'update_common_mail_providers' => \$opts->{'update_common_mail_providers'}, 'force' => \$opts->{'force'}, ); return usage(0) if $opts->{'help'}; my $conf_dir = Cpanel::GreyList::Config::get_conf_dir(); if ( !-d $conf_dir ) { require File::Path; File::Path::make_path($conf_dir); } my ( $opts_passed, $exit_code ); if ( $opts->{'initialize'} || $opts->{'reset'} ) { $exit_code += initialize_db( $opts->{'reset'} ); $opts->{'update_common_mail_providers'} = 1; $opts_passed++; } if ( $opts->{'import_trusted_hosts'} ) { _ensure_db_is_initialized(); return import_trusted_hosts( $opts->{'import_trusted_hosts'} ); } if ( $opts->{'export_trusted_hosts'} ) { _ensure_db_is_initialized(); return export_trusted_hosts( $opts->{'export_to'} ); } if ( $opts->{'update_common_mail_providers'} ) { _ensure_db_is_initialized(); $exit_code += update_common_mail_providers( $opts->{'force'} ); $opts_passed++; } if ( ref $opts->{'trust_common'} eq 'ARRAY' && scalar @{ $opts->{'trust_common'} } ) { _ensure_db_is_initialized(); $exit_code += trust_common_email_service( $opts->{'trust_common'} ); $opts_passed++; } return ( $exit_code ? 1 : 0 ) if $opts_passed; return usage(1); } sub initialize_db { my $force = shift; my $action = "Initializing"; my $saved_trusted_hosts; if ($force) { $action = "Resetting"; $saved_trusted_hosts = _save_trusted_hosts(); } print "[*] $action database for the cPanel Greylist service.\n"; Cpanel::SafeDir::MK::safemkdir( Cpanel::GreyList::Config::get_conf_dir() ) if !-d Cpanel::GreyList::Config::get_conf_dir(); my $success = 0; try { my $db_obj = Cpanel::GreyList::DB->new( Cpanel::GreyList::Config::get_sqlite_db() ); $success = $db_obj->initialize_db($force); } catch { print "[!] $action database failed: $_\n"; }; return 1 if !$success; print "[+] $action database successfully completed.\n"; _restore_trusted_hosts($saved_trusted_hosts) if $saved_trusted_hosts; if ( Cpanel::GreyList::Config::is_enabled() ) { Cpanel::LoadModule::load_perl_module('Cpanel::ServerTasks'); print "[*] Restarting cPGreyListd service …"; Cpanel::ServerTasks::queue_task( ['CpServicesTasks'], "restartsrv cpgreylistd" ); print " Done.\n"; } return; } sub trust_common_email_service { my $trust_email_services = shift; print "[*] Updating Trusted Hosts List …\n"; my $client = Cpanel::GreyList::Client->new(); $client->{'disabled'} = 0; my $providers_in_db = Cpanel::GreyList::Client->new()->get_common_mail_providers(); foreach my $common_service ( @{$trust_email_services} ) { if ( not exists $providers_in_db->{$common_service} ) { print "\t[!] Skipping '$common_service'. This email service is not registered, and cannot be trusted via this script. Add the IP address ranges for this email service manually via the WHM interface.\n"; next; } try { if ( my $ips_trusted = $client->trust_entries_for_common_mail_provider($common_service) ) { print "\t[+] $ips_trusted IP(s)for '$common_service'\n"; } } catch { print "\t[!] Failed to trust IP(s) for '$common_service': $_\n"; }; } print "[+] Updated Trusted Hosts List.\n"; return; } sub update_common_mail_providers { my $force = shift; if ( !Cpanel::GreyList::Config::is_enabled() && !$force ) { print "[!] Greylisting is disabled. Skipping common mail providers update.\n"; return; } print "[*] Updating Common Mail Providers List …\n"; my $return_code = try { my $json_data = Cpanel::GreyList::CommonMailProviders::fetch_latest_data(); my $json_create_time = delete $json_data->{'create_time'}; my $config = Cpanel::GreyList::Config::load_common_mail_providers_config( { map { $_ => 1 } keys %{$json_data} } ); my $client = Cpanel::GreyList::Client->new(); $client->{'disabled'} = 0; my $providers_in_db = $client->get_common_mail_providers(); my $renamed = 0; foreach my $new_key ( sort keys %{$json_data} ) { # Do not rename an existing provider if the new provider already exists in the DB. next if exists $providers_in_db->{$new_key}; next unless my $old_keys_ar = $json_data->{$new_key}->{'renamed_from'}; # Only rename the first existing provider match if there are multiple. next unless my $old_key = ( grep { exists $providers_in_db->{$_} } @{$old_keys_ar} )[0]; print "[*] Renaming '$old_key' to '$new_key' …\n"; $client->rename_mail_provider( $old_key, $new_key ); $config->{$new_key} = delete $config->{$old_key} // 1; $renamed = 1; print "[+] Renamed '$old_key' to '$new_key'.\n"; } if ($renamed) { $providers_in_db = $client->get_common_mail_providers(); Cpanel::GreyList::Config::save_common_mail_providers_config( { map { $_ => 1 } keys %{$config} }, $config ); } # Remove any/all providers that were removed from the list my @providers_to_remove = grep { not exists $json_data->{$_} } keys %{$providers_in_db}; foreach my $provider (@providers_to_remove) { print "[*] Removing '$provider' …\n"; my $ips_for_provider = $client->list_entries_for_common_mail_provider($provider); $client->remove_mail_provider($provider); send_removal_notification( $providers_in_db->{$provider}->{'display_name'}, [ map { $_->{'host_ip'} } @{$ips_for_provider} ] ); print "[+] Removed '$provider'\n"; } foreach my $provider ( keys %{$json_data} ) { my $newly_added = 0; if ( !exists $providers_in_db->{$provider} ) { $client->add_mail_provider( $provider, $json_data->{$provider}->{'display_name'}, $json_create_time ); $newly_added = 1; } else { # If an existing provider's display_name has changed, then update it. my $latest_display_name = $json_data->{$provider}->{'display_name'}; my $existing_display_name = $providers_in_db->{$provider}->{'display_name'}; if ( $existing_display_name ne $latest_display_name ) { print "[*] Changing name of '$provider' from '$existing_display_name' to '$latest_display_name' …\n"; $client->update_display_name_for_mail_provider( $provider, $latest_display_name ); print "[+] Changed name of '$provider' from '$existing_display_name' to '$latest_display_name'.\n"; } } # If the provider is not marked for autoupdating, then skip it. if ( exists $config->{$provider} && !$config->{$provider} ) { print "[*] Skipping $provider per configuration …\n"; next; } if ( !$force && ( $providers_in_db->{$provider}->{'last_updated'} || 0 ) >= $json_create_time ) { print "[*] No update necessary for '$provider'.\n"; next; } print "[*] Updating $provider …\n"; $client->delete_entries_for_common_mail_provider($provider); $client->add_entries_for_common_mail_provider( $provider, $json_data->{$provider}->{'ips'} ); $client->bump_last_updated_for_mail_provider( $provider, $json_create_time ); if ( $providers_in_db->{$provider}->{'is_trusted'} || ( $newly_added && $config->{'autotrust_new_common_mail_providers'} ) ) { print "[*] Marking $provider as a trusted Mail Provider …\n"; $client->trust_entries_for_common_mail_provider($provider); } } Cpanel::ForkAsync::do_in_child( sub { Cpanel::IP::GreyList::update_common_mail_providers_or_log(); # Its ok if this fails, it just means they will get a 20s connect delay if enabled. } ); print "[+] Updated Common Mail Providers list.\n"; return 0; ## no critic (TryTiny::ProhibitExitingSubroutine) } catch { print "[!] Failed to update Common Mail Providers list: $_\n"; return 1; }; return $return_code; } sub import_trusted_hosts { my $input_file = shift; if ( !Cpanel::GreyList::Config::is_enabled() ) { print "[!] Greylisting is disabled\n"; return; } my $input_file_fh; if ( !open( $input_file_fh, '<', $input_file ) ) { print "[!] Failed to read '$input_file': $!\n"; return 1; } my ( $json, $error ); try { $json = Cpanel::JSON::LoadFile( $input_file_fh, $input_file ); } catch { $error = $_; }; if ( !$json || ref $json ne 'HASH' ) { print "[!] Failed to read '$input_file': Invalid JSON data.\n"; print "[!] Error: $error\n" if $error; return 1; } print "[*] Importing cPGreylist Trusted Hosts:\n\n"; my $client = Cpanel::GreyList::Client->new(); foreach my $trusted_host ( keys %{$json} ) { try { $client->create_trusted_host( $trusted_host, $json->{$trusted_host} ); print "[+] Added '$trusted_host' to Trusted Hosts List.\n"; } catch { print "[!] Failed to add '$trusted_host' to the Trusted Hosts List: $_\n"; }; } return 0; } sub export_trusted_hosts { my $output_file = shift; if ( !Cpanel::GreyList::Config::is_enabled() ) { print "[!] Greylisting is disabled\n"; return; } print STDERR "[*] Exporting cPGreylist Trusted Hosts:\n\n"; my $output_fh; if ($output_file) { if ( !open( $output_fh, '>', $output_file ) ) { print "[!] Failed to open '$output_file' for writing: $!\n"; return 1; } print STDERR "[*] Saving to '$output_file'\n"; } my $error; try { my $client = Cpanel::GreyList::Client->new(); my $output = {}; foreach my $trusted_host ( @{ $client->read_trusted_hosts() } ) { $output->{ $trusted_host->{'host_ip'} } = $trusted_host->{'comment'}; } print { $output_fh ? $output_fh : \*STDOUT } Cpanel::JSON::pretty_dump($output); } catch { print "[!] Failed to export Trusted Hosts: $_\n"; $error++; }; return 1 if $error; return 0; } sub _ensure_db_is_initialized { if ( !-s Cpanel::GreyList::Config::get_sqlite_db() ) { print "[!] SQLite Database for the cPanel Greylist service is not initialized...\n"; initialize_db(); } return 1; } sub _save_trusted_hosts { my $saved_trusted_hosts = []; return if !Cpanel::GreyList::Config::is_enabled(); print "[*] Saving current Trusted Hosts List …\n"; my $success = 0; try { my $client = Cpanel::GreyList::Client->new(); $saved_trusted_hosts = $client->read_trusted_hosts(); die "Failed to read Trusted Hosts List\n" if !( $saved_trusted_hosts && 'ARRAY' eq ref $saved_trusted_hosts ); $success = 1; } catch { print "[!] Failed to save current Trusted Hosts List: $_\n"; }; return if !$success; print "[+] Saved " . scalar @{$saved_trusted_hosts} . " entries from the Trusted Host List.\n"; return $saved_trusted_hosts; } sub _restore_trusted_hosts { my $saved_trusted_hosts = shift; print "[*] Restoring saved Trusted Hosts List …\n"; my $success = 0; try { my $client = Cpanel::GreyList::Client->new(); foreach my $entry ( @{$saved_trusted_hosts} ) { $client->create_trusted_host( $entry->{'host_ip'}, $entry->{'comment'} ); } $success = 1; } catch { print "[!] Failed to restore Trusted Hosts List: $_\n"; }; return if !$success; print "[+] Restored " . scalar @{$saved_trusted_hosts} . " entries to the Trusted Host List.\n"; return $saved_trusted_hosts; } sub usage { my ( $retval, $msg ) = @_; my $fh = $retval ? \*STDERR : \*STDOUT; if ( !defined $msg ) { $msg = <<USAGE; $0 Utility to manage the cPanel Greylist service. Available options: --init => Initialize the SQLite DB with the basic data structure as needed. --reset => Forceably reset the DB. Note: This will attempt to preserve the Trusted Hosts List, if the greylisting service is enabled on the server. --trust => Trust the IPs for the common email services specified. Specify this switch more than once to trust multiple services at the same time. The following common services are recognized by this script: COMMON_EMAIL_SERVICES --import => [/path/to/json/file] Imports the Trusted Hosts contained in the specified JSON file: $0 --import import.json --export => Export the current Trusted Hosts List. To export the list to a file, specify the 'export_to' switch: $0 --export --export_to export.json Or redirect stdout: $0 --export > export.json --update_common_mail_providers => Update the Common Mail Provider data in the database. Fetches the latest data from a cPanel update mirror, and updates the database based on current Common Mail Provider configuration. You can specify '--force', in order to forceably update the IP data in the database. The SQLite file is located at: ${ \Cpanel::GreyList::Config::get_sqlite_db() }. USAGE my $providers_in_db = Cpanel::GreyList::Client->new()->get_common_mail_providers(); my $common_email_services_str = join( "\n", map { "\t\t\t$_" } ( sort keys %{$providers_in_db} ) ); $msg =~ s/COMMON_EMAIL_SERVICES/$common_email_services_str/; } print {$fh} $msg; return $retval; } sub send_removal_notification { my ( $provider, $ips_ar ) = @_; require Cpanel::Notify; Cpanel::Notify::notification_class( 'class' => 'Greylist::CommonProviderRemoval', 'application' => 'Greylist::CommonProviderRemoval', 'constructor_args' => [ 'origin' => 'manage_greylisting', 'provider_removed' => $provider, 'provider_ips' => $ips_ar, ] ); return; }