ó Üœ^c@sdZdZdZddlZddlmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZdd lmZdd lmZdd lmZeeƒZd efd „ƒYZdfd„ƒYZeƒZdS(sSerg G. Brester (sebres)s"Copyright (c) 2014 Serg G. BrestertGPLiÿÿÿÿNi(t JailThread(tFailManagerEmptyi(t getLogger(tMyTime(tUtilstObserverThreadcBsreZdZejdZd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zd„Zd„Zd„Zd„Zd$d„Zd„Zd„Zed„ƒZd$d„Zd$d„Zed„ƒZejd„ƒZed„ƒZd„Z d„Z!d„Z"dd%d„ƒYZ#d „Z$d!„Z%d"„Z&d#„Z'RS(&s8Handles observing a database, managing bad ips and ban increment. Parameters ---------- Attributes ---------- daemon ident name status active : bool Control the state of the thread. idle : bool Control the idle state of the thread. sleeptime : int The time the thread sleeps for in the loop. i cCsƒtt|ƒjddƒt|_tjƒ|_g|_tj ƒ|_ d|_ i|_ t |_d|_d|_t|_dS(Ntnames f2b/observeri<i(tsuperRt__init__tTruetidlet threadingtRLockt _queue_lockt_queuetEventt_notifyt sleeptimet_timerstFalset_pausedtNonet_ObserverThread__dbt"_ObserverThread__db_purge_intervaltdaemon(tself((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR ?s       cCs7y|j|SWn!tk r2td|ƒ‚nXdS(NsInvalid event index : %s(RtKeyError(Rti((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt __getitem__Ts cCs6y|jt=Wn!tk r1tdtƒ‚nXdS(NsInvalid event index: %s(RRR(RR((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt __delitem__Zs cCs t|jƒS(N(titerR(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt__iter__`scCs t|jƒS(N(tlenR(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt__len__cscCstS(N(R(Rtother((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt__eq__fscCs t|ƒS(N(tid(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt__hash__iscGsa|jj|dƒ}|dk r.|jƒntj||j|ƒ}||j|<|jƒdS(sÅAdd a named timer event to queue will start (and wake) in 'starttime' seconds Previous timer event with same name will be canceled and trigger self into queue after new 'starttime' value N(RtgetRtcancelR tTimertaddtstart(RRt starttimeteventtt((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytadd_named_timerls    cGstjdk r[|r[tjtj|jtjƒ|tjƒ||fƒ}|j ƒdStj||j |ƒ}|j ƒdS(sJAdd a timer event to queue will start (and wake) in 'starttime' seconds N( RtmyTimeRR R)RtDEFAULT_SLEEP_INTERVALt _delayedEventttimeR+R*(RR,R-R.((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt add_timerys& cCsjtjƒ|ks$tjƒ|kr8|jd|ŒdStjtj|j|||fƒ}|jƒdS(Ni( RR3R4R R)RR1R2R+(Rt endMyTimetendTimeR-R.((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR2ˆs $cCs'|j r#|jr#|jjƒndS(s1Notify wakeup (sets /and resets/ notify event) N(RRtset(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt pulse_notify’scGs.|j|jj|ƒWdQX|jƒdS(s5Add a event to queue and notify thread to wake up. N(RRtappendR8(RR-((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR*™s cGs$|j|jj|ƒWdQXdS(s=Add a event to queue withouth notifying thread to wake up. N(RRR9(RR-((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytadd_wn¡s cGs||ŒdS(N((Rtltargs((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt call_lambda¨scCsLtjdƒ|jd|jdƒi |jd6|jd6|jd6|jd6|jd6|j d6|j d 6d „d 6d „d 6}yw|j dƒxJ|j rßt |_xÐ|jszy—d}|j)t|jƒrë|jjdƒ}nWdQX|dkrPn|d}t|dƒs<|j|ƒp6t||ƒ}n||dŒWq«tk rv}tjd|dtƒq«Xq«W|j}|r¿t|_|j|jƒ|jƒ|jrÜq–qÜq–tj t!j"ƒ|j#s–Pq–q–Wtjdt|jƒƒWn)tk r%}tjd|dtƒnX|jg|_WdQXt|_tS(sŽMain loop for Threading. This function is the main loop of the thread. Returns ------- bool True when the thread exits nicely. sObserver start...tDB_PURGEtdb_purgetcalltdb_settis_alivet is_activeR+tstopcSsdS(N(((((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytÄstnopcSsdS(N(((((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyREÅstshutdowniNis%stexc_infos&Observer stopped, %s events remaining.s Observer stopped after error: %s($tlogSystinfoR/RR=RAR?tisAlivetisActiveR+RDR*tactiveRR RRRR!RtpoptcallableR'tgetattrt ExceptionterrorR RtwaitRtclearR3tsleepRR1tis_full(Rt_ObserverThread__methtevtmethtetn((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytrun«s^                 !        cCstS(N(R (R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRKúscCs|jS(N(RM(RtfromStr((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRLþscCs3|j$|js)tt|ƒjƒnWdQXdS(N(RRMRRR+(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR+s  cCs˜|jr”|jr”d}tjd|ƒ|j1|jdƒ|j}|jjƒd|_WdQX|j|ƒ|j ƒt |_|j dƒndS(Nis-Observer stop ... try to end queue %s secondsRGgà?( RMRRIRJRR:R7Rt wait_emptyRTRt wait_idle(RtwtimeR[((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRD s       cCs+|jt|jƒrtStSWdQXdS(N(RR!RR R(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRVs cCsÄtjtjƒ|dk r/tjƒ|}n|jdk rm|jdƒ|jrm|j rm|j ƒqmnx?|jr®|dk r›tjƒ|kr›PntjtjƒqpW|j dƒ|j S(sWWait observer is running and returns if observer has no more events (queue is empty) RFgü©ñÒMbP?N( R3RURR1RRRR:RVR R8R_(RRRZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR^!s    cCs…tjtjƒ|jrtS|dk r<tjƒ|}nx?|js}|dk rjtjƒ|krjPntjtjƒq?W|jS(sJWait observer is running and returns if observer idle (observer sleeps) N(R3RURR1R R RR(RRRZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR_5s   cCs|jS(N(R(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytpausedCscCs*|j|krdS||_|jƒdS(N(RR8(Rtpause((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRaGs cCsdS(s/Status of observer to be implemented. [TODO] t(RcRc((R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytstatusPscCs ||_dS(N(R(Rtdb((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRAZscCsFtjdƒ|jdk r,|jjƒn|jd|jdƒdS(NsPurge database event occurredR>R?(RItdebugRRtpurgeR/R(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR?]s c CsE|jƒ s|jdƒ r!dS|jƒ}|jƒ}tjd|j|ƒd}d}d}y¥|jƒ} |j } | dk r/x]| j ||ƒD]I\}}} t ||j ƒƒ}d|dkrÑ|nd>dd}Pq˜Wt || ƒ}|dk r/||kr/tjd|j|||ƒdSn|dkr?dStjd |j|tj|ƒ|||| krud nd ƒ|j||dtƒ}|j|ƒ|| kry-x&trÙ|j|ƒ}|j|ƒq´WWqtk r|jtjƒƒqXnWn8tk r@} tjd | d tjƒtjkƒnXdS(s} Notify observer a failure for ip was found Observer will check ip was known (bad) and possibly increase an retry count t incrementNs[%s] Observer: failure found %siiiis8[%s] Ignore failure %s before last ban %s < %s, restoreds%[%s] Found %s, bad - %s, %s # -> %s%ss, BanRcs%sRH(RKtgetBanTimeExtratgetIPtgetTimeRIRfRRt getMaxRetrytdatabasetgetBantmaxt getBanCounttminRJRttime2strt addFailureR t setBanCountttoBant putFailTicketRtcleanupR3RQRRtgetEffectiveLeveltloggingtDEBUG( Rt failManagertjailttickettiptunixTimetbanCountt retryCountt timeOfBantmaxRetryRet lastBanTimeRZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt failureFoundhsJ     "$      t BanTimeIncrcBseZd„ZRS(cCs||_||_dS(N(tTimetCount(RtbanTimeR€((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR ¡s (t__name__t __module__R (((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR† scCs&|jƒ}|d|j||ƒƒS(Nt evformula(RiR†(RR|R‰R€tbe((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt calcBanTime¥s c Cs¾|jƒ s|j r|S|jƒ}|jƒ}|}yF|dkr~|jdtƒr~x!|jj||d|jdtƒƒD]õ\}}} ||jƒkr·|j|dƒnt j d|||ƒ|dkrø|d|j ||ƒƒ}n|j |ƒ|j ƒ|krmt jd|j||tj|ƒtjdt|ƒƒtjdt|ƒƒfƒn t|_Pq‚WnWn8tk r¹} t jd | d t jƒtjkƒnX|S( stCheck for IP address to increment ban time (if was already banned). Returns ------- float new ban time. iRht overalljailsis"IP %s was already banned: %s #, %sRŒs/[%s] IP %s is bad: %s # last %s - incr %s to %stsecondss%sRH(RKRmRiRjR'RRnRpRtRIRfR†t setBanTimeRkRJRRRrtdatetimet timedeltatintR trestoredRQRRRxRyRz( RR|R‰R}RR~t orgBanTimeR€R‚R„RZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyt incrBanTime©s0   4   5  )c Cs|jr dSy¸|}|jƒ}tjd|j||ƒ|dkr™|jƒdkr™|j|||ƒ}|dks†||kr™|j|ƒq™n|dkr |j ƒ|}t j dt |ƒƒt j|ƒf}|t jƒkrtjd|dƒtSnd}||kr•tjd |j||jƒ|Œtjd d |j|||fƒ|jtd td ||d ƒƒ|j||ƒn|jdk rÄ|j rÄ|jj||ƒnWn8tk rÿ}tjd|dtjƒtjkƒnXdS(sÀ Notify observer a ban occured for ip Observer will check ip was known (bad) and possibly increase/prolong a ban time Secondary we will actualize the bans and bips (bad ip) in database Ns[%s] Observer: ban found %s, %siÿÿÿÿRsIgnore old bantime %sit permanenttinfinites$[%s] Increase Ban %s (%d # %s -> %s)is[%s] Observer: prolong %s in %si is%sRH(R˜R™(R•RjRIRfRt getBanTimeRR—R‘RkR’R“R”RRrR3RtnoticeRptlogR4RqRot prolongBanRmtaddBanRQRRRxRyRz( RR}R|tbtimetoldbtimeR~tbendtimetlogtimeRZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pytbanFoundÒs6    "6cCs„yE|jƒ}|jƒ}tjd|j||ƒ|jj|ƒWn8tk r}tjd|dtj ƒt j kƒnXdS(sÀ Notify observer a ban occured for ip Observer will check ip was known (bad) and possibly increase/prolong a ban time Secondary we will actualize the bans and bips (bad ip) in database s[%s] Observer: prolong %s, %ss%sRHN( RšRjRIRfRtactionst _prolongBanRQRRRxRyRz(RR}R|RŸR~RZ((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyRýs  N(((RŠR‹t__doc__RR1R RRR R"R$R&R/R4R2R8R*R:R=R\RKRRLR+RDtpropertyRVR^R_RatsetterRdRAR?R…R†RŽR—R£R(((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR(sF              O         8  ) +t _ObserverscBseZd„ZRS(cCs d|_dS(N(RtMain(R((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR s(RŠR‹R (((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyR© s(t __author__t __copyright__t __license__R t jailthreadRt failmanagerRtosRyR3R’tmathtjsontrandomtsysthelpersRtmytimeRtutilsRRŠRIRR©t Observers(((s</usr/lib/python2.7/site-packages/fail2ban/server/observer.pyts T  ÿæ