
    GkcD                         d Z dZdZddlZddlmZ ddlmZ ddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZdd	lmZ dd
lmZ ddlmZ  ee      Z G d de      Z G d d      Z e       Zy)zSerg G. Brester (sebres)z"Copyright (c) 2014 Serg G. BresterGPL    N   )
JailThread)FailManagerEmpty   )	getLogger)MyTime)Utilsc                   V    e Zd ZdZej
                  dz  Z fdZd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd%dZ fdZd&dZed        Zd%dZd%dZed        Zej<                  d        Zed        Zd Z d Z!d Z" G d d       Z#d! Z$d" Z%d# Z&d$ Z' xZ(S )'ObserverThreada8  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                    t         t        |   d       d| _        t	        j
                         | _        g | _        t	        j                         | _	        d| _
        i | _        d| _        d | _        d| _        d| _        y )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   zObserverThread.__init__?   sm    &N&;$)__&$$+"$, $.$,$,$)"$$+    c                 X    	 | j                   |   S # t        $ r t        d|z        w xY w)NzInvalid event index : %sr   KeyErrorr!   is     r#   __getitem__zObserverThread.__getitem__T   s5    2
++a.	 2	,q0	112s    )c                 V    	 | j                   |= y # t        $ r t        d|z        w xY w)NzInvalid event index: %sr&   r(   s     r#   __delitem__zObserverThread.__delitem__Z   s2    1{{1~	 1	+a/	001s    (c                 ,    t        | j                        S N)iterr   r!   s    r#   __iter__zObserverThread.__iter__`   s    	dkk	r$   c                 ,    t        | j                        S r.   )lenr   r0   s    r#   __len__zObserverThread.__len__c   s    	T[[	r$   c                      y)NF )r!   others     r#   __eq__zObserverThread.__eq__f   s    	r$   c                     t        |       S r.   )idr0   s    r#   __hash__zObserverThread.__hash__i   s    	D/r$   c                     | j                   j                  |d      }||j                          t        j                  || j
                  |      }|| j                   |<   |j                          y)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_timerzObserverThread.add_named_timerl   sU     lltT"!]88:ooi51!$,,t'')r$   c                 d   t         j                  o|rmt        j                  t        j
                  | j                  t        j                         |z   t        j                         |z   |f      }|j                          yt        j                  || j                  |      }|j                          y)zJAdd a timer event to queue will start (and wake) in 'starttime' seconds
		N)
r	   myTimer   r?   r
   DEFAULT_SLEEP_INTERVAL_delayedEventtimerA   r@   )r!   rB   rC   rD   s       r#   	add_timerzObserverThread.add_timery   s{     ]]9u33T5G5G[[]Y		i 7?1 779	ooi51!'')r$   c                    t        j                         |k\  st        j                         |k\  r | j                  dg|  y t        j                  t
        j                  | j                  |||f      }|j                          y )Nr   )	r	   rJ   rK   r   r?   r
   rH   rI   rA   )r!   	endMyTimeendTimerC   rD   s        r#   rI   zObserverThread._delayedEvent   sf    [[]i499;'#94>>!e	ooe22D4F4Fw! '')r$   c                 \    | j                   s | j                  }|r|j                          yyy)z1Notify wakeup (sets /and resets/ notify event)
		N)r   r   set)r!   ns     r#   pulse_notifyzObserverThread.pulse_notify   s*     
||1EEG  
r$   c                     | j                   5  | j                  j                  |       ddd       | j                          y# 1 sw Y   xY w)z5Add a event to queue and notify thread to wake up.
		N)r   r   appendrR   r!   rC   s     r#   r@   zObserverThread.add   s@      ;;e s   AAc                 |    | j                   5  | j                  j                  |       ddd       y# 1 sw Y   yxY w)z=Add a event to queue withouth notifying thread to wake up.
		N)r   r   rT   rU   s     r#   add_wnzObserverThread.add_wn   s4      ;;e  s   2;c                      ||  y r.   r6   )r!   largss      r#   call_lambdazObserverThread.call_lambda   s	    T(r$   c           
      N   t         j                  d       | j                  d| j                  d       | j                  | j
                  | j                  | j                  | j                  | j                  | j                  d d d	}	 | j                  d       | j                  r0d| _        | j                  s	 d	}| j                  5  t!        | j"                        r| j"                  j%                  d
      }d	d	d	       |nG|d
   }t'        |d
         s|j)                  |      xs t+        | |      } ||dd	   | j                  s| j0                  }|r?d| _        |j3                  | j4                         |j7                          | j                  r1t9        j:                  t<        j>                         | j@                  sn| j                  r0t         j                  dt!        | j"                               d	| _        | j                  5  g | _        d	d	d	       d| _        y# 1 sw Y   3xY w# t,        $ r#}t         j/                  d|d       Y d	}~ d	}~ww xY w# t,        $ r"}t         j/                  d|d       Y d	}~d	}~ww xY w# 1 sw Y   d| _        yxY w)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                       yNr6   r6   r6   r$   r#   <lambda>z$ObserverThread.run.<locals>.<lambda>       r$   c                       yr`   r6   r6   r$   r#   ra   z$ObserverThread.run.<locals>.<lambda>   rb   r$   )	calldb_setr^   is_alive	is_activerA   stopnopshutdownrf   FNr   r   %sTexc_infoz&Observer stopped, %s events remaining.z Observer stopped after error: %s)!logSysinforE   r   r[   re   r^   isAliveisActiverA   rh   r@   activer   r   r   r3   r   popcallabler=   getattr	Exceptionerrorr   waitr   clearrJ   sleepr   rH   is_full)r!   _ObserverThread__methevmetherQ   s         r#   runzObserverThread.run   s-    	++!"z4#;#;ZH [[}}JJ99
&,F88J	DIll+b  
dkk
[[__Q  
Udbe_VZZ%5%Lt9Ld
BqrFm ll$ 	ATYVVDNNWWY 
ZZ556LLE 
H 
;;7T[[9IJ4<  4;$)	O     +ll4Tl**+, 
 F	<<2A<EEF$)	s   1I& :H7 1H*9
H7 I& :H7 >I& B	I& 0I& J*H4/H7 7	I# II& I##I& &	J/JJJ$c                      y)NTr6   r0   s    r#   rp   zObserverThread.isAlive   s    	r$   c                     | j                   S r.   )rr   )r!   fromStrs     r#   rq   zObserverThread.isActive  s     
r$   c                     | j                   5  | j                  st        t        |           d d d        y # 1 sw Y   y xY wr.   )r   rr   r   r   rA   r    s    r#   rA   zObserverThread.start  s5     (
++	.$%'( ( (s   6?c                    | j                   r| j                  rt        j                  d|       | j                  5  | j                  d       | j                  }| j                  j                          d | _        d d d        | j                  |      s|r&j                          d| _         d| _	        d | _
        n| _        | j                  t        |d            xr | j                   S y# 1 sw Y   txY w)Nz-Observer stop ... try to end queue %s secondsrj   FTg      ?)rr   r   rn   ro   r   rW   rP   
wait_emptyry   r   r   	wait_idleminr{   )r!   wtime	forceQuitrQ   s       r#   rh   zObserverThread.stop  s    	[[T\\	;;>F 	 KK
ALLDL ooe	GGIDKDLDIDL
..UC
)
>$,,.>>	! s   ?C--C6c                 x    | j                   5  t        | j                        rdndcd d d        S # 1 sw Y   y xY w)NTF)r   r3   r   r0   s    r#   r{   zObserverThread.is_full#  s0     .dkk"$. . .s   09c                    t        j                  t        j                         |t	        j                          |z   }| j
                  9| j                  d       | j                  r| j                  r| j                          | j                  rJ|t	        j                          kD  rn0t        j                  t        j                         | j                  rJ| j                  d       | j                   S )zWWait observer is running and returns if observer has no more events (queue is empty)
		ri   gMbP?)rJ   rz   r   rH   r	   r   rW   r{   r   rR   r   r!   r   r   s      r#   r   zObserverThread.wait_empty(  s     **^223{{}y 1	\\;;u
lltyy 1	::n334 	
 ..\\	r$   c                 p   t        j                  t        j                         | j                  ry|t        j                          |z   }| j                  sV|$t        j                          kD  r	 | j                  S t        j                  t        j                         | j                  sV| j                  S )zJWait observer is running and returns if observer idle (observer sleeps)
		T)rJ   rz   r   rH   r   r	   r   s      r#   r   zObserverThread.wait_idle<  s     **^223	YY
{{}y 1II 1		 ::n334 II 
r$   c                     | j                   S r.   )r   r0   s    r#   pausedzObserverThread.pausedJ  s    	r$   c                 R    | j                   |k(  ry || _         | j                          y r.   )r   rR   )r!   pauses     r#   r   zObserverThread.pausedN  s$    	\\U	$,r$   c                      y)z/Status of observer to be implemented. [TODO]
		) r   r6   r0   s    r#   statuszObserverThread.statusW  s     
r$   c                     || _         y r.   )r   )r!   dbs     r#   re   zObserverThread.db_seta  s	    $)r$   c                     t         j                  d       | j                  | j                  j                          | j	                  d| j
                  d       y )NzPurge database event occurredr]   r^   )rn   debugr   purgerE   r   r0   s    r#   r^   zObserverThread.db_purged  s?    ,,./	YY99??z4#;#;ZHr$   c           
         |j                         r|j                  d      sy|j                         }|j                         }t        j                  d|j                  |       d}d}d}	 |j                  j                  j                         }|j                  }	|	|	j                  ||      D ]3  \  }}}
t        ||j                               }d|dk  r|ndz  dz  dz   } n t        ||      }|)||k  r$t        j                  d|j                  |||       y|dk  ryt        j                  d	|j                  |t!        j"                  |      ||||k\  rd
nd       |j                  j                  j%                  ||dz
  d      }|j'                  |       ||k\  r|j                  j)                  |       yy# t*        $ rE}t        j-                  d|t        j/                         t0        j2                  k         Y d}~yd}~ww xY w)z} Notify 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   Trk   rl   )rp   getBanTimeExtragetIDgetTimern   r   r   filterfailManagergetMaxRetrydatabasegetBanmaxgetBanCountr   ro   r	   time2str
addFailuresetBanCount
performBanrv   rw   getEffectiveLevelloggingDEBUG)r!   jailticketipunixTimebanCount
retryCount	timeOfBanmaxRetryr   lastBanTimer   s               r#   failureFoundzObserverThread.failureFoundo  s    
t33K@	||~"^^(,,0$))R@(*) Mkk%%11382n,.IIb$,? ()[Hf0023Xhm(<a?!CZ  Z*JY!6\\L		2x,Ao
	;;6		2
OOHxh&WB1 ''226:>4P:	hHKK2  
 M	<<a&":":"<gmm"K<LLMs&   +B0F> F> "BF> >	H;HHc                       e Zd Zd Zy)ObserverThread.BanTimeIncrc                      || _         || _        y r.   )TimeCount)r!   banTimer   s      r#   r   z#ObserverThread.BanTimeIncr.__init__  s    494:r$   N__name__
__module____qualname__r   r6   r$   r#   BanTimeIncrr     s    r$   r   c                 X    |j                         } |d   | j                  ||            S )N	evformula)r   r   )r!   r   r   r   bes        r#   calcBanTimezObserverThread.calcBanTime  s.    "	K))'8<	==r$   c                    |j                         r|j                  s|S |j                         }|j                         }|}	 |dkD  rA|j	                  dd      r.|j                  j                  |||j	                  dd            D ]  \  }}}	||j                         k\  r|j                  |dz          t        j                  d|||       |dkD  r |d   | j                  ||            }|j                  |       |j                         |kD  rkt        j                  d	|j                  d
|d|dt        j                   |      dt        j"                  |      dt        j"                  |             nd|_         |S  |S # t&        $ rF}
t        j)                  d|
t        j+                         t,        j.                  k         Y d}
~
|S d}
~
ww xY w)ztCheck 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 Trk   rl   N)rp   r   r   r   r=   r   r   r   rn   r   r   
setBanTimer   ro   r   r	   r   seconds2strrestoredrv   rw   r   r   r   )r!   r   r   r   r   r   
orgBanTimer   r   r   r   s              r#   incrBanTimezObserverThread.incrBanTime  s    
t}}
>"||~"*Mkbff[%0 
]]"d1NO()[ 	F&&((!$\\6HiP1; 0 0( CDgw9$kktyyRTV^y!*%v'9'9''BD E fo
 
.+* 
. 
 M	<<a&":":"<gmm"K<LL	.Ms   EF F 	G;GGc           
      ,   |j                   ry	 |}|j                         }t        j                  d|j                  ||       |dk7  r>|j                         .| j                  |||      }|dk(  s||kD  r|j                  |       |dk7  rn|j                         |z   }t        j                  |      t        j                  |      f}|t        j                         k  rt        j                  d|d          yd}||k7  rt        j                  d|j                  ||j                         g|  t        j                  d	d
|j                  |||f       | j!                  t#        dt%        d||z
  d	z
              | j&                  ||       |j(                  *|j                   s|j(                  j+                  ||       yyy# t,        $ rE}t        j/                  d|t        j1                         t2        j4                  k         Y d}~yd}~ww xY w) 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
		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   rk   rl   )r   r   rn   r   r   
getBanTimer   r   r   r	   r   r   rJ   noticer   logrK   r   r   
prolongBanr   addBanrv   rw   r   r   r   )	r!   r   r   btimeoldbtimer   bendtimelogtimer   s	            r#   banFoundzObserverThread.banFound  s    __	 M82	<<1499b%Hrkf'')1T5&1E{eh&urk~~%'H!!%(&//(*CDG&++-\\)71:6'Gx
MM8$))			) ') JJq3TYYUHDUVNN3r3q%("2Q"678$//6SWX
mmMMv& )8 
 M	<<a&":":"<gmm"K<LLMs   C)G 9C	G 	H;HHc                 b   	 |j                         }|j                         }t        j                  d|j                  ||       |j
                  j                  |       y# t        $ rE}t        j                  d|t        j                         t        j                  k         Y d}~yd}~ww xY w)r   z[%s] Observer: prolong %s, %srk   rl   N)r   r   rn   r   r   actions_prolongBanrv   rw   r   r   r   )r!   r   r   r   r   r   s         r#   r   zObserverThread.prolongBan  s    M52	<</BF<<F#	 M	<<a&":":"<gmm"K<LLMs   AA   	B.);B))B.r.   )r   T))r   r   r   __doc__r
   rH   r   r*   r,   r1   r4   r8   r;   rE   rK   rI   rR   r@   rW   r[   r   rp   rq   rA   rh   propertyr{   r   r   r   setterr   re   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r$   r   c                       e Zd Zd Zy)
_Observersc                     d | _         y r.   )Mainr0   s    r#   r   z_Observers.__init__  s	    $)r$   Nr   r6   r$   r#   r   r     s    r$   r   )
__author____copyright____license__r   
jailthreadr   failmanagerr   osr   rJ   datetimemathjsonrandomsyshelpersr   mytimer	   utilsr
   r   rn   r   r   	Observersr6   r$   r#   <module>r      sg   0 (
4  " ) 6 6 6 6 
    
8	bMZ bMJ  L	r$   