
    =*fD                         S r SrSrSSKrSSKJr  SSKJr  SSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKrSSKrSS	KJr  SS
KJr  SSKJr  \" \5      r " S S\5      r " S S5      r\" 5       rg)zSerg G. Brester (sebres)z"Copyright (c) 2014 Serg G. BresterGPL    N   )
JailThread)FailManagerEmpty   )	getLogger)MyTime)Utilsc                   j  ^  \ rS rSrSr\R                  S-  rU 4S jrS rS r	S r
S rS	 rS
 rS rS rS rS rS rS rS rS rS rS'S jrU 4S jrS(S jr\S 5       rS'S jrS'S jr\S 5       r\R>                  S 5       r\S 5       r S r!S r"S r# " S  S!5      r$S" r%S# r&S$ r'S% r(S&r)U =r*$ ))ObserverThread(   a>  Handles 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.

   c                    > [         [        U ]  SS9  SU l        [        R
                  " 5       U l        / U l        [        R                  " 5       U l	        SU l
        0 U l        SU l        S U l        SU l        SU l        g )Nzf2b/observer)nameT<   Fi  )superr   __init__idle	threadingRLock_queue_lock_queueEvent_notify	sleeptime_timers_paused_ObserverThread__db"_ObserverThread__db_purge_intervaldaemonself	__class__s    :/usr/lib/python3/dist-packages/fail2ban/server/observer.pyr   ObserverThread.__init__?   sm    &N&;$)__&$$+"$, $.$,$,$)"$$+    c                 Z     U R                   U   $ ! [         a    [        SU-  5      ef = f)NzInvalid event index : %sr   KeyErrorr"   is     r$   __getitem__ObserverThread.__getitem__T   s5    2
++a.	 2	,q0	112s    *c                 X     U R                   U	 g ! [         a    [        SU-  5      ef = f)NzInvalid event index: %sr(   r*   s     r$   __delitem__ObserverThread.__delitem__Z   s2    1{{1~	 1	+a/	001s    )c                 ,    [        U R                  5      $ N)iterr   r"   s    r$   __iter__ObserverThread.__iter__`   s    	dkk	r&   c                 ,    [        U R                  5      $ r2   )lenr   r4   s    r$   __len__ObserverThread.__len__c   s    	T[[	r&   c                     g)NF )r"   others     r$   __eq__ObserverThread.__eq__f   s    	r&   c                     [        U 5      $ r2   )idr4   s    r$   __hash__ObserverThread.__hash__i   s    	D/r&   c                     U R                   R                  US5      nUb  UR                  5         [        R                  " X R
                  U5      nX@R                   U'   UR                  5         g)zAdd 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)r   getcancelr   Timeraddstart)r"   r   	starttimeeventts        r$   add_named_timerObserverThread.add_named_timerl   sQ     lltT"!]88:ooi51!,,t'')r&   c                 v   [         R                  bw  U(       ap  [        R                  " [        R
                  U R                  [         R                  " 5       U-   [        R                  " 5       U-   U45      nUR                  5         g[        R                  " XR                  U5      nUR                  5         g)zXAdd a timer event to queue will start (and wake) in 'starttime' seconds
                N)
r	   myTimer   rG   r
   DEFAULT_SLEEP_INTERVAL_delayedEventtimerI   rH   )r"   rJ   rK   rL   s       r$   	add_timerObserverThread.add_timery   sy     ]]9u33T5G5G[[]Y		i 7?1 779	ooi51!'')r&   c                    [         R                  " 5       U:  d  [        R                  " 5       U:  a  U R                  " S/UQ76   g [        R                  " [
        R                  U R                  XU45      nUR                  5         g )Nr   )	r	   rS   rT   r   rG   r
   rQ   rR   rI   )r"   	endMyTimeendTimerK   rL   s        r$   rR   ObserverThread._delayedEvent   sb    [[]i499;'#9>>!e	ooe22D4F4F! '')r&   c                 p    U R                   (       d%  U R                  nU(       a  UR                  5         ggg)z?Notify wakeup (sets /and resets/ notify event)
                N)r   r   set)r"   ns     r$   pulse_notifyObserverThread.pulse_notify   s*     
||1EEG  
r&   c                     U R                      U R                  R                  U5        SSS5        U R                  5         g! , (       d  f       N= f)zCAdd a event to queue and notify thread to wake up.
                N)r   r   appendr]   r"   rK   s     r$   rH   ObserverThread.add   s9     ;;e  s   A
Ac                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)zJAdd a event to queue without notifying thread to wake up.
                N)r   r   r`   ra   s     r$   add_wnObserverThread.add_wn   s+     ;;e s	   2
A c                     U" U6   g r2   r<   )r"   largss      r$   call_lambdaObserverThread.call_lambda   s	    T(r&   c           
         [         R                  S5        U R                  SU R                  S5        U R                  U R
                  U R                  U R                  U R                  U R                  U R                  S S S.	n U R                  S5        U R                  (       Gac  SU l        U R                  (       d   S	nU R                     [!        U R"                  5      (       a  U R"                  R%                  S
5      nS	S	S	5        Uc  OVUS
   n['        US
   5      (       d#  UR)                  U5      =(       d    [+        X5      nU" USS	 6   U R                  (       d  M  U R0                  nU(       aG  SU l        UR3                  U R4                  5        UR7                  5         U R                  (       a  GM*  O6[8        R:                  " [<        R>                  5        U R@                  (       d  OU R                  (       a  GMc  [         R                  S[!        U R"                  5      5        S	U l        U R                     / U l        S	S	S	5        SU l        g! , (       d  f       GNa= f! [,         a   n[         R/                  SUSS9   S	nAGNBS	nAff = f! [,         a  n[         R/                  SUSS9   S	nANS	nAff = f! , (       d  f       N= f)zMain loop for Threading.

This function is the main loop of the thread.

Returns
-------
bool
        True when the thread exits nicely.
zObserver start...DB_PURGEdb_purgec                      gNr<   r<   r<   r&   r$   <lambda>$ObserverThread.run.<locals>.<lambda>   s    r&   c                      gro   r<   r<   r&   r$   rp   rq      s    br&   )	calldb_setrm   is_alive	is_activerI   stopnopshutdownru   FNr   r   %sTexc_infoz&Observer stopped, %s events remaining.z Observer stopped after error: %s)!logSysinforM   r   ri   rt   rm   isAliveisActiverI   rw   rH   activer   r   r   r8   r   popcallablerE   getattr	Exceptionerrorr   waitr   clearrS   sleepr   rQ   is_full)r"   _ObserverThread__methevmether\   s         r$   runObserverThread.run   s"    	++!"z4#;#;ZH [[}}JJ99
&,F88J	DIll+b
dkk

[[__Q  
Udbe__VZZ%5%L9Ld
BqrFm lll$ 	ATYVVDNNWWY 	 
ZZ556LLE 
H 
;;7T[[9IJ4< 4; $)	O   +ll4Tl*+, 
 F	<<2A<EF s   ;J! I4 6I"I4 J! AI4 J! *B!J! 0J! 
K"
I1,I4 4
J>JJ! JJ! !
K
+KK

Kc                     g)NTr<   r4   s    r$   r   ObserverThread.isAlive   s    	r&   c                     U R                   $ r2   )r   )r"   fromStrs     r$   r   ObserverThread.isActive  s     
r&   c                    > U R                      U R                  (       d  [        [        U ]  5         S S S 5        g ! , (       d  f       g = fr2   )r   r   r   r   rI   r!   s    r$   rI   ObserverThread.start  s,    
++	.$%' s	   $;
A	c                 6   U R                   (       a  U R                  (       a  [        R                  SU5        U R                     U R                  S5        U R                  nU R                  R                  5         S U l        S S S 5        U R                  U5      (       d  U(       a&  WR                  5         SU l         SU l	        S U l
        OWU l        U R                  [        US5      5      =(       a    U R                  (       + $ g! , (       d  f       N= f)Nz-Observer stop ... try to end queue %s secondsry   FTg      ?)r   r   r}   r~   r   rd   r[   
wait_emptyr   r   r   	wait_idleminr   )r"   wtime	forceQuitr\   s       r$   rw   ObserverThread.stop  s    	[[T\\	;;>F 	KK
ALLDL 	 ooe	GGIDKDLDIDL
..UC
)
>$,,.>>	! 	s   ?D


Dc                     U R                      [        U R                  5      (       a  SOSsS S S 5        $ ! , (       d  f       g = f)NTF)r   r8   r   r4   s    r$   r   ObserverThread.is_full#  s*    dkk""$ s	   5
Ac                 .   [         R                  " [        R                  5        Ub  [        R                   " 5       U-   nU R
                  bC  U R                  S5        U R                  (       a!  U R                  (       a  U R                  5         U R                  (       aT  Ub  [        R                   " 5       W:  a  O7[         R                  " [        R                  5        U R                  (       a  MT  U R                  S5        U R                  (       + $ )zeWait observer is running and returns if observer has no more events (queue is empty)
                rx   gMbP?)rS   r   r   rQ   r	   r   rd   r   r   r]   r   r"   r   r   s      r$   r   ObserverThread.wait_empty(  s     **^223{{}y 1	\\;;u
lltyy 1	::n334 	
 ..\\	r&   c                    [         R                  " [        R                  5        U R                  (       a  gUb  [
        R                   " 5       U-   nU R                  (       d`  Ub&  [
        R                   " 5       W:  a   U R                  $ [         R                  " [        R                  5        U R                  (       d  M`  U R                  $ )zXWait observer is running and returns if observer idle (observer sleeps)
                T)rS   r   r   rQ   r   r	   r   s      r$   r   ObserverThread.wait_idle<  s     **^223	YY
{{}y 1II 1		 ::n334 III 
r&   c                     U R                   $ r2   )r   r4   s    r$   pausedObserverThread.pausedJ  s    	r&   c                 R    U R                   U:X  a  g Xl         U R                  5         g r2   )r   r]   )r"   pauses     r$   r   r   N  s"    	\\U	,r&   c                     g)z=Status of observer to be implemented. [TODO]
                ) r   r<   r4   s    r$   statusObserverThread.statusW  s     
r&   c                     Xl         g r2   )r   )r"   dbs     r$   rt   ObserverThread.db_seta  s    )r&   c                     [         R                  S5        U R                  b  U R                  R                  5         U R	                  SU R
                  S5        g )NzPurge database event occurredrl   rm   )r}   debugr   purgerM   r   r4   s    r$   rm   ObserverThread.db_purged  s?    ,,./	YY99??z4#;#;ZHr&   c           
      ,   UR                  5       (       a  UR                  S5      (       d  gUR                  5       nUR                  5       n[        R                  SUR                  U5        SnSnSn UR                  R                  R                  5       nUR                  n	U	b}  U	R                  X15       H2  u  pWn
[        XRR                  5       5      nSUS:  a  UOS-  S-  S-   n  O   [        Xh5      nUb(  XG::  a#  [        R                  SUR                  X4U5        gUS::  a  g[        R                  S	UR                  U[         R"                  " U5      XVXh:  a  S
OS5        UR                  R                  R%                  X&S-
  S5      nUR'                  U5        Xh:  a  UR                  R)                  U5        gg! [*         aB  n[        R-                  SU[        R/                  5       [0        R2                  :*  S9   SnAgSnAff = f)zxNotify observer a failure for ip was found

Observer will check ip was known (bad) and possibly increase an retry count
	incrementNz[%s] Observer: failure found %sr   r      r   z8[%s] Ignore failure %s before last ban %s < %s, restoredz%[%s] Found %s, bad - %s, %s # -> %s%sz, Banr   Trz   r{   )r   getBanTimeExtragetIDgetTimer}   r   r   filterfailManagergetMaxRetrydatabasegetBanmaxgetBanCountr   r~   r	   time2str
addFailuresetBanCount
performBanr   r   getEffectiveLevelloggingDEBUG)r"   jailticketipunixTimebanCount
retryCount	timeOfBanmaxRetryr   lastBanTimer   s               r$   failureFoundObserverThread.failureFoundo  s    
t33K@@	||~"^^(,,0$))R@(*) Mkk%%11382n,.IIb,?([H0023Xhm(<a?!CZ  -@ Z*J!6\\L		2,Ao
	;;6		2
OOHx&WB1 ''226>4P:	hKK2  
 M	<<a&":":"<gmm"K<LMs&   5B/G %G ,BG 
H8HHc                       \ rS rSrS rSrg)ObserverThread.BanTimeIncri  c                     Xl         X l        g r2   )TimeCount)r"   banTimer   s      r$   r   #ObserverThread.BanTimeIncr.__init__  s    9:r&   )r   r   N__name__
__module____qualname____firstlineno__r   __static_attributes__r<   r&   r$   BanTimeIncrr     s    r&   r   c                 V    UR                  5       nUS   " U R                  X#5      5      $ )N	evformula)r   r   )r"   r   r   r   bes        r$   calcBanTimeObserverThread.calcBanTime  s*    "	K))'<	==r&   c                    UR                  5       (       a  UR                  (       d  U$ UR                  5       nUR                  5       nUn US:  GaL  UR	                  SS5      (       Ga4  UR                  R                  XQUR	                  SS5      S9 GH  u  pxn	XsR                  5       :  a  UR                  US-   5        [        R                  SXWU5        US:  a  US   " U R                  X'5      5      nUR                  U5        UR                  5       U:  at  [        R                  S	UR                  < S
U< SU< S[        R                   " U5      < S[        R"                  " U5      < S[        R"                  " U5      < 35        OSUl          U$    U$ ! [&         aC  n
[        R)                  SU
[        R+                  5       [,        R.                  :*  S9   Sn
A
U$ Sn
A
ff = f)zqCheck for IP address to increment ban time (if was already banned).

Returns
-------
float
        new ban time.
r   r   Foveralljails)r   r   z"IP %s was already banned: %s #, %sr   [z] IP z	 is bad: z # last z - incr z to Trz   r{   N)r   r   r   r   rE   r   r   r   r}   r   r   
setBanTimer   r~   r   r	   r   seconds2strrestoredr   r   r   r   r   )r"   r   r   r   r   r   
orgBanTimer   r   r   r   s              r$   incrBanTimeObserverThread.incrBanTime  s    
t}}
>"||~"*Mkbff[%00 
]]"1NO 	)[ 	&&((!$\\6iP1; 0 0 CDgw9$kktyyRTV^y!*%v'9'9''BD E fo
 
.) P( 
. 
 M	<<a&":":"<gmm"K<L	.Ms   EF! F! !
G.+8G))G.c           
      D   UR                   (       a  g UnUR                  5       n[        R                  SUR                  XS5        US:w  a?  UR                  5       c.  U R                  X#U5      nUS:X  d  X4:  a  UR                  U5        US:w  as  UR                  5       U-   n[        R                  " U5      [        R                  " U5      4nU[        R                  " 5       :  a  [        R                  SUS   5        gOSnX4:w  a  [        R                  " SUR                  XQR                  5       /UQ76   [        R                  S	S
UR                  XSU45        U R!                  [#        S[%        SX4-
  S	-
  5      5      U R&                  X5        UR(                  b.  UR                   (       d  UR(                  R+                  X!5        ggg! [,         aB  n[        R/                  SU[        R1                  5       [2        R4                  :*  S9   SnAgSnAff = f)Notify observer a ban occurred 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
Nz[%s] Observer: ban found %s, %szIgnore old bantime %sr   F)	permanentinfinitez$[%s] Increase Ban %s (%d # %s -> %s)   z[%s] Observer: prolong %s in %sr   r   rz   r{   )r   r   r}   r   r   
getBanTimer   r   r   r	   r   r   rS   noticer   logrT   r   r   
prolongBanr   addBanr   r   r   r   r   )	r"   r   r   btimeoldbtimer   bendtimelogtimer   s	            r$   banFoundObserverThread.banFound  s    __	 M82	<<1499bHrkf'')1T&1E{e&urk~~%'H!!%(&//(*CDG&++-\\)71:6   (G
MM8$))			) ') JJq3TYYHDUVNN3r3q%"2Q"678$//6X
mmMM& )8 
 M	<<a&":":"<gmm"K<LMs   C/G CG 
H8HHc                 \    UR                  5       nUR                  5       n[        R                  SUR                  XC5        UR
                  R                  U5        g! [         aB  n[        R                  SU[        R                  5       [        R                  :*  S9   SnAgSnAff = f)r   z[%s] Observer: prolong %s, %srz   r{   N)r   r   r}   r   r   actions_prolongBanr   r   r   r   r   )r"   r   r   r   r   r   s         r$   r   ObserverThread.prolongBan  s~    M52	<</BF<<F#	 M	<<a&":":"<gmm"K<LMs   AA 
B+)8B&&B+)__db__db_purge_intervalr   r   r   r   r   r   r    r   r   r2   )r   T)+r   r   r   r   __doc__r
   rQ   r   r,   r/   r5   r9   r>   rB   rM   rT   rR   r]   rH   rd   ri   r   r   r   rI   rw   propertyr   r   r   r   setterr   rt   rm   r   r   r   r   r   r   r   __classcell__)r#   s   @r$   r   r   (   s   (  66;*21N`(
. . .(   	--   I/Md 
>'R(MTM Mr&   r   c                       \ rS rSrS rSrg)
_Observersi  c                     S U l         g r2   Mainr4   s    r$   r   _Observers.__init__  s	    $)r&   r  Nr   r<   r&   r$   r  r    s    r&   r  )
__author____copyright____license__r   
jailthreadr   failmanagerr   osr   rS   datetimemathjsonrandomsyshelpersr   mytimer	   utilsr
   r   r}   r   r  	Observersr<   r&   r$   <module>r!     sg   0 (
4  " ) 6 6 6 6 
    
8	bMZ bMJ  L	r&   