
    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dS )zSerg G. Brester (sebres)z"Copyright (c) 2014 Serg G. BresterGPL    N   )
JailThread)FailManagerEmpty   )	getLogger)MyTime)Utilsc                   `    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| _        d S )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__?   s    &&N&;;;$)_&&$$+""$, $.$,$,$)"$$+++    c                 ^    	 | 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   sB    2
+a.	 2 2 2	,q0	1	112s    ,c                 X    	 | j         |= d S # t          $ r t          d|z            w xY w)NzInvalid event index: %sr&   r(   s     r#   __delitem__zObserverThread.__delitem__Z   sC    1{1~~~	 1 1 1	+a/	0	001s    )c                 *    t          | j                  S N)iterr   r!   s    r#   __iter__zObserverThread.__iter__`   s    	dk		r$   c                 *    t          | j                  S r.   )lenr   r0   s    r#   __len__zObserverThread.__len__c   s    	T[		r$   c                     dS )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                             |d          }||                                 t          j        || j        |          }|| j         |<   |                                 dS )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   s_     ltT""!]88:::oi511!$,t'')))))r$   c                 L   t           j        h|rft          j        t          j        | j        t          j                    |z   t          j                    |z   |f          }|                                 dS t          j        || j	        |          }|                                 dS )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3T5G[]]Y	i 7? 1 77999	6oi511!'')))))r$   c                     t          j                    |k    st          j                    |k    r | j        dg|R   d S t          j        t
          j        | j        |||f          }|                                 d S )Nr   )	r	   rJ   rK   r   r?   r
   rH   rI   rA   )r!   	endMyTimeendTimerC   rD   s        r#   rI   zObserverThread._delayedEvent   sz    []]i49;;'#9#94>!e	6oe2D4Fw ! '')))))r$   c                 V    | j         s| j        }|r|                                 dS dS dS )z1Notify wakeup (sets /and resets/ notify event)
		N)r   r   set)r!   ns     r#   pulse_notifyzObserverThread.pulse_notify   sB     
 |1 EEGGGGG  r$   c                     | j         5  | j                            |           ddd           n# 1 swxY w Y   |                                  dS )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   /33c                 z    | j         5  | j                            |           ddd           dS # 1 swxY w Y   dS )z=Add a event to queue withouth notifying thread to wake up.
		N)r   r   rT   rU   s     r#   add_wnzObserverThread.add_wn   s       ;e                 s   044c                      ||  d S r.   r6   )r!   largss      r#   call_lambdazObserverThread.call_lambda   s    !T((((r$   c           
          t                               d           |                     d| j        d           | j        | j        | j        | j        | j        | j	        | j
        d d d	}	 |                     d           | j        rbd| _        | j        s	 d	}| j        5  t!          | j                  r| j                            d
          }d	d	d	           n# 1 swxY w Y   |n|d
         }t'          |d
                   s%|                    |          pt+          | |          } ||dd	           n4# t,          $ r'}t                               d|d           Y d	}~nd	}~ww xY w| j        | j        }|r?d| _        |                    | j                   |                                 | j        r;n&t9          j        t<          j                   | j         sn| j        bt                               dt!          | j                             d	| _        n4# t,          $ r'}t                               d|d           Y d	}~nd	}~ww xY w| j        5  g | _        d	d	d	           n# 1 swxY w Y   d| _        dS )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                      dS Nr6   r6   r6   r$   r#   <lambda>z$ObserverThread.run.<locals>.<lambda>   s     r$   c                      dS r`   r6   r6   r$   r#   ra   z$ObserverThread.run.<locals>.<lambda>   s    b r$   )	calldb_setr^   is_alive	is_activerA   stopnopshutdownre   FNr   r   %sTexc_infoz&Observer stopped, %s events remaining.z Observer stopped after error: %s)!logSysinforE   r   r[   rd   r^   isAliveisActiverA   rg   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HH [}J9
)y &,F88J	 "DIl ++b    
dk

  [__Q                              
Udbe__LVZZ%5%5%Lt9L9Ld
dBqrrFmmm + + +ll4Tl********+ l +$ 	A TYVVDNWWYYY  
Z5666L E 
 "H 
;;7T[9I9IJJJ4<<	 F F F	<<2A<EEEEEEEEF   4;              $)	s   )+H 	D7 /CD7 CD7  C!D7 &H 'AD7 6H 7
E(E#H #E((B4H 
I'I		II,,I03I0c                     dS )NTr6   r0   s    r#   ro   zObserverThread.isAlive   s    	r$   Nc                     | j         S r.   )rq   )r!   fromStrs     r#   rp   zObserverThread.isActive  s     
r$   c                     | j         5  | j        s't          t          |                                            d d d            d S # 1 swxY w Y   d S r.   )r   rq   r   r   rA   r    s    r#   rA   zObserverThread.start  s     ( (
+ (	.$%%'''( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   /AA	A	   Tc                    | j         r| j        rt                              d|           | j        5  |                     d           | j        }| j                                         d | _        d d d            n# 1 swxY w Y   |                     |          s|r*|                                 d| _         d| _	        d | _
        n|| _        |                     t          |d                    o| j         S dS )Nz-Observer stop ... try to end queue %s secondsri   FTg      ?)rq   r   rm   rn   r   rW   rP   
wait_emptyrx   r   r   	wait_idleminrz   )r!   wtime	forceQuitrQ   s       r#   rg   zObserverThread.stop  s/   	[ ?T\ ?	;;>FFF 	  KK
ALDL               ooe 	 GGIIIDKDLDIIDL
..UC
)
)
>$,.>>	s   =A::A>A>c                 t    | j         5  t          | j                  rdndcd d d            S # 1 swxY w Y   d S )NTF)r   r3   r   r0   s    r#   rz   zObserverThread.is_full#  s     . .dk""
-$$. . . . . . . . . . . . . . . . . .s   -11c                    t          j        t          j                   |t	          j                     |z   }| j        7|                     d           | j        r| j        r| 	                                 | j        r?|t	          j                     |k    rn%t          j        t          j                   | j        ?| 
                    d           | j         S )zWWait observer is running and returns if observer has no more events (queue is empty)
		Nrh   gMbP?)rJ   ry   r   rH   r	   r   rW   rz   r   rR   r   r!   r   r~   s      r#   r   zObserverThread.wait_empty(  s     *^2333{}}y 1	\;;u
l ty  5 1 1	:n3444 	 5
 ..\	r$   c                    t          j        t          j                   | j        rdS |t          j                     |z   }| j        s?|t          j                     |k    rn%t          j        t          j                   | j        ?| j        S )zJWait observer is running and returns if observer idle (observer sleeps)
		T)rJ   ry   r   rH   r   r	   r   s      r#   r   zObserverThread.wait_idle<  s     *^2333	Y 
${}}y 1I 5 1 1	:n3444 I 5 
r$   c                     | j         S r.   )r   r0   s    r#   pausedzObserverThread.pausedJ  s
    	r$   c                 V    | j         |k    rd S || _         |                                  d S r.   )r   rR   )r!   pauses     r#   r   zObserverThread.pausedN  s3    	\U	6$,r$   c                     dS )z/Status of observer to be implemented. [TODO]
		) r   r6   r0   s    r#   statuszObserverThread.statusW  s	     
r$   c                     || _         d S r.   )r   )r!   dbs     r#   rd   zObserverThread.db_seta  s    $)))r$   c                     t                               d           | j        | j                                         |                     d| j        d           d S )NzPurge database event occurredr]   r^   )rm   debugr   purgerE   r   r0   s    r#   r^   zObserverThread.db_purged  sP    ,,.///	Y9??z4#;ZHHHHHr$   c           
      `   |                                 r|                    d          sdS |                                }|                                }t                              d|j        |           d}d}d}	 |j        j        	                                }|j
        }	|	|	                    ||          D ];\  }}}
t          ||                                          }d|dk     r|ndz  dz  dz   } t          ||          }|+||k    r%t                              d|j        |||           dS |dk    rdS t                              d	|j        |t!          j        |          ||||k    rd
nd           |j        j                            ||dz
  d          }|                    |           ||k    r|j                            |           dS dS # t*          $ rM}t                              d|t                                          t0          j        k               Y d}~dS 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   Trj   rk   )ro   getBanTimeExtragetIDgetTimerm   r   r   filterfailManagergetMaxRetrydatabasegetBanmaxgetBanCountr   rn   r	   time2str
addFailuresetBanCount
performBanru   rv   getEffectiveLevelloggingDEBUG)r!   jailticketipunixTimebanCount
retryCount	timeOfBanmaxRetryr   lastBanTimer~   s               r#   failureFoundzObserverThread.failureFoundo  s\    
 
t33K@@ 
	6||~~"^^(,,0$)R@@@(*) Mk%113382n,.IIb$,?,?  ()[Hf002233Xhmm((<a?!CZ Z**JY!6!6\\L	2x, , ,VAoo
F	;;6	2
OHxh&&WWB1 1 1 '226:>4PP:	hHK2  
 M M M	<<a&":":"<"<gm"K<LLLLLLLLLMs'   <B4G 2G :BG 
H- AH((H-c                       e Zd Zd ZdS )ObserverThread.BanTimeIncrc                 "    || _         || _        d S 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                 t    |                                 } |d         |                     ||                    S )N	evformula)r   r   )r!   r   r   r   bes        r#   calcBanTimezObserverThread.calcBanTime  s7    "	K))'8<<	=	==r$   c                     |                                 r|j        s|S |                                }|                                }|}	 |dk    rd|                    dd          rM|j                            |||                    dd                    D ]\  }}}	||                                k    r|                    |dz              t          	                    d|||           |dk    r% |d         | 
                    ||                    }|                    |           |                                |k    rht                              d	|j        d
|d|dt          j        |          dt          j        |          dt          j        |                     nd|_         nY# t&          $ rL}
t                              d|
t                                          t,          j        k               Y d}
~
nd}
~
ww xY w|S )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 Trj   rk   N)ro   r   r   r   r=   r   r   r   rm   r   r   
setBanTimer   rn   r   r	   r   seconds2strrestoredru   rv   r   r   r   )r!   r   r   r   r   r   
orgBanTimer   r   r   r~   s              r#   incrBanTimezObserverThread.incrBanTime  s)    
 t} 
>"||~~"*Mkkbff[%00k 
]"d1N1NOO ()[ 	F&&((((!$$$\\6HiPPP1; 0 0( C CDDgw9$$kkktyyyRTRTRTV^V^V^y!!!!*%%%%v'9''B'B'BD E E E E fo
	 M M M	<<a&":":"<"<gm"K<LLLLLLLLM	.s   	E+F5 5
H?AHHc           
      l   |j         rdS 	 |}|                                }t                              d|j        ||           |dk    rL|                                8|                     |||          }|dk    s||k    r|                    |           |dk    rz|                                |z   }t          j
        |          t          j        |          f}|t          j                    k     r#t                              d|d                    dS nd}||k    rt          j        d|j        ||                                g|R   t                              d	d
|j        |||f           |                     t#          dt%          d||z
  d	z
                      | j        ||           |j        $|j         s|j                            ||           dS dS dS # t,          $ rM}t                              d|t                                          t2          j        k               Y d}~dS 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)r   z[%s] Observer: prolong %s in %sr   r   rj   rk   )r   r   rm   r   r   
getBanTimer   r   r   r	   r   r   rJ   noticer   logrK   r   r   
prolongBanr   addBanru   rv   r   r   r   )	r!   r   r   btimeoldbtimer   bendtimelogtimer~   s	            r#   banFoundzObserverThread.banFound  sS    _ 
	6 M82	<<149b%HHHrkkf''))1T5&11E{{eh&&urkk~~%'H!%((&/(*C*CDG&+--\\)71:666E   (Gx
M8$)				) ') ) ) ) JJq3TYUHDUVVVNN3r3q%("2Q"67788$/6SWXXX
mMv&&&&&   
 M M M	<<a&":":"<"<gm"K<LLLLLLLLLMs    DG CG 
H3&AH..H3c                    	 |                                 }|                                }t                              d|j        ||           |j                            |           dS # t          $ rM}t                              d|t          	                                t          j        k               Y d}~dS d}~ww xY w)r   z[%s] Observer: prolong %s, %srj   rk   N)r   r   rm   r   r   actions_prolongBanru   rv   r   r   r   )r!   r   r   r   r   r~   s         r#   r   zObserverThread.prolongBan  s    M52	<</BFFF<F#####	 M M M	<<a&":":"<"<gm"K<LLLLLLLLLMs   A$A( (
B?2A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   ro   rp   rA   rg   propertyrz   r   r   r   setterr   rd   r^   r   r   r   r   r   r   __classcell__)r"   s   @r#   r   r   (   s        (  6;    *2 2 21 1 1                      N N N`     ( ( ( ( (
   . . . (.   (      ( 	-  -   (  I I I/M /M /Md       
> > >' ' 'R(M (M (MTM M M M M M Mr$   r   c                       e Zd Zd ZdS )
_Observersc                     d | _         d S 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   rm   r   r   	Observersr6   r$   r#   <module>r      s^  0 (
4     " " " " " " ) ) ) ) ) ) 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 



                   
8		bM bM bM bM bMZ bM bM bMJ        JLL			r$   