
    ogf                     *   d Z dZd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mZmZmZmZ ddlmZ ddlmZ dd	lmZmZmZ dd
lmZ ddlmZmZmZ ddl m!Z!mZ" ddl#m$Z$ ddl%m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z-m.Z.m/Z/m0Z0m1Z1m2Z3m4Z4m5Z5 ddl6m7Z7  e7e8      Z,dZ9dZ: e e!jv                               Z<e	jz                  j}                  e	jz                  j~                        Z?e	jz                  j}                  e	jz                  j                        Z@e?dz
  e_?        e,xe_,        xe_,        e_,        e%j                  ZBe%j                  ZDd ZEeExe_F        xe_F        xe_F        e$_F        d ZGe%j                  ZHd ZIe@fdZJ G d dej                        ZK G d dej                        ZLeKZMeLZNg aOd ZPePe_Q        dxe_R        e_R        e+j                  ZTd  ZUd! ZV	 	 	 d.d"ZWd# ZXd$ ZYd% ZZd& Z[i fd'Z\ G d( d)e+      Z] G d* d+e]      Z^ G d, d-e]      Z_y)/zSerg BresterzICopyright (c) 2014- Serg G. Brester (sebres), 2008- Fail2Ban ContributorsGPL    N)joinisdirisfileexistsdirnamewraps)Thread   )fail2banclientfail2banserverfail2bancmdline)Fail2banCmdLine)exec_command_lineCSocket
VisualWait)Fail2banServerr   )protocol)server)MyTime)Utils   )	LogCaptureTestCaselogSyswith_tmpdirshutilloggingSTOCK
CONFIG_DIRTEST_NOWtearDownMyTime)	getLoggerzfail2ban-clientzfail2ban-serverc                  4    t         j                  | d          y Nr   )r   infoargss    G/usr/lib/python3/dist-packages/fail2ban/tests/fail2banclienttestcase.py_test_outputr*   J   s    T!W    c                     t         j                  d|        t        j                  t        j                         | dz  z          y )Nz===>>> time shift + %s min<   )r   debugr   setTimetime)shifts    r)   _time_shiftr2   Q   s,    *E2b()r+   c                      t         j                  Jt         j                  j                  t               t         j                  j	                  t        dz         yy)z$Helper to wait observer becomes idleN   )	ObserversMain
wait_emptyMID_WAITTIME	wait_idle r+   r)   _observer_wait_idler;   Y   s:    NN..L)..<!+, r+   c                      t         j                  7t         j                  j                   fd}|t         j                  _        yy)zOHelper to block observer before increase bantime until some condition gets trueNc                      t         j                  _        t        j	                  d       t        j                         t        j	                  d        | i | y )Nz4  [Observer::banFound] *** observer blocked for testz.  [Observer::banFound] +++ observer runs again)r5   r6   banFoundr   r.   r   wait_for)r(   kwargs_obs_banFoundcondtimeouts     r)   	_banFoundz0_observer_wait_before_incrban.<locals>._banFoundd   sD    *9>>	<<FG>>$ 	<<@A$!&!r+   )r5   r6   r>   )rB   rC   rD   rA   s   `` @r)   _observer_wait_before_incrbanrE   _   s4    NN..))-" &).. r+   c                       e Zd ZdZy)ExitExceptionzException upon a normal exitN__name__
__module____qualname____doc__r:   r+   r)   rG   rG   t       #r+   rG   c                       e Zd ZdZy)FailExitExceptionzException upon abnormal exitNrH   r:   r+   r)   rO   rO   y   rM   r+   rO   c                  L    t        t              rt        j                  d      S y)Nr   exit)lenINTERACTpopr'   s    r)   _test_input_commandrU      s    M	a	r+   Fc                     t        | |      }|j                  dj                  |      |rdndz          |j                          y )N
 )openwriter   close)fnmodelinesfs       r)   _write_filer`      s4    	"d^5	54b	12r+   c                     d }	 t        |       }|j                         ||j                          S S # ||j                          w w xY wN)rY   readr[   )r\   r_   s     r)   
_read_filerd      sE    	
2h!	
]779 Q]779 s	   2 Ac                 f   t        | d      }|dk(  rt        | d      }d}	|rt        rd }
t        j                  t        ||
       |J dt        |      z         |d}t        j                  d	      }t        j                  t        |d
      d      D ]1  }|j                  d      }|j                  |      rd}t        |       3 t        j                  d      }t        j                  t        |d      d      D ]1  }|j                  d      }|j                  |      rd}t        |       3 |rdnd}	nft        j                  |       t        t        |d
      dddd|j!                  dd      z   ddt        | d      z   dt        | d      z   dd|z   dd d       |	r"t        t        ||	      dgd!dd"d#| z   df|z     |rt        t        |d$      dg|  t"        j$                  j&                  t(        j*                  k  r]t-        t        |d
             t-        t        |d             |rt-        t        |d$             |	r|	dk7  rt-        t        ||	             |rXt        rR|D ]M  }t        j.                  t        j0                  j3                  t        t        |            t        ||             O |r|D ]  }t        |d%| iz  d        d&\  }}t"        j$                  j&                  t(        j4                  k  rat7        t"        j$                  j&                        }t"        j$                  j8                  d'kD  r!d(d)t"        j$                  j8                  z  z   f}|d*|fz   }d+|d,t        | d      d-t        | d      d.|f|z   d/dd0t7        t:        j<                        fz   S )1Nconfigautozf2b-db.sqlite3	jail.confc           	      X    |D cg c]  }t        t        | |            s| c}S c c}w )z?Filters list of 'files' to contain only directories (under dir))r   pjoin)dirfilesr_   s      r)   ig_dirsz_start_params.<locals>.ig_dirs   s#    
4uU3]31
44
4s   '')ignorez?We are about to overload use_stock_cfg from the one provided %s)action.dzfilter.dz^dbfile\s*=zfail2ban.confT)inplacerW   zdbfile = :memory:z^backend\s*=backend = pollingz
jail.localrX   w[Definition]zloglevel = INFOzlogtarget = %z%%zsyslogsocket = autoz	socket = f2b.sockz
pidfile = f2b.pidz	dbfile = zdbmaxmatches = 100zdbpurgeage = 1d
[INCLUDES]	[DEFAULT]ztmp = zfail2ban.localtmp)r:   INFOr   -vz
--loglevel-c-sz-p--logtargetz--syslogsocketz	--timeout)rj   r   r   copytreeSTOCK_CONF_DIRreprrecompile	fileinputinputrstripmatchprintosmkdirr`   replaceunittestF2B	log_levelr   DEBUG	_out_filesymlinkpathabspathrz   str	verbosityr   MAX_WAITTIME)ry   	use_stockuse_stock_cfg	logtargetdb	f2b_localjailscreate_before_startcfgj_confrm   rlinenvvvllevs                   r)   _start_paramsr      sw    S(&LS"#"
%5 	//.#g6		 [DtMGZZ[	,DMjj !ooeC94H d
++d
4ggdmD;	 	jj!!ooeC5tD d
++d
4ggdmD;	 !<b& ((3-eC)3I%%c400sJ''%Y'' eC # "(S."  eC)*C<)<LLW]]*E#'(E#{#$U3()*+%U3  e Ha::bggooeNA67sAGH &aqE3<%& dLLW\\)	X\\##	$$\\a
HLL***
*	,3|T""T5j)4sI1F	#	$'7s?//0'	 r+   c                 V    	 | | j                  d      dz      dk(  S # t        $ r Y yw xY w)Nr   r   	INHERITEDF)index
ValueErrorstartparamss    r)   _inherited_logr      s9    	[&&}5a7	8K	GG 	s    	((c                     d }	 t        |       }t        j                  d|      j                         }t	        |      S # t
        $ r }t        j                  |       Y d }~|S d }~ww xY w)Nz\S+)rd   r   r   groupint	Exceptionr   r.   )pidfilepides      r)   _get_pid_from_filer      sZ    7#
##%#	S/ ,,q//s   9> 	A'A""A'c                     t         j                  d| t        |       f       t        |       r%| }t        |d      } t	        |       st        |d      } t
        j                  j                  t        j                  k  r:t        d      }t	        |      rt        |       nt         j                  dd|       t	        |       st         j                  d       yt         j                  d	|        t        |       y
	 t         j                  d       dk  st        j                         k(  rt        dd| d      t!        j"                        syt        j$                  t&        j(                         t!        j*                  fdd      s$t        j$                  t&        j,                         t         j                  d       t!        j"                         S # t.        $ r}t         j1                  |       Y d }~yd }~ww xY w)Nzcleanup: %rrv   zfail2ban.pidf2b.logr4   zno logfile %rzcleanup: no pidfile for %rTzcleanup pidfile: %rFzcleanup pid: %rr   zpid z of z is invalidc                  0    t        j                          S rb   )r   
pid_exists)r   s   r)   <lambda>z_kill_srv.<locals>.<lambda>+  s    E$4$4S$9 9 r+   r   cleanup: kill ready)r   r.   r   rj   r   r   r   r   r   r   r   logr   r   getpidr   r   r   killsignalSIGTERMr?   SIGKILLr   	exception)r   piddirlogfiler   r   s       @r)   	_kill_srvr   	  s   mguW~67	'N&&)$'	6>*7 LLW]]*&)$'G_W	::a'*w,,+V4	#W-'"K	,, #&AX		#	g>	??			#	
''#v~~	91	=773,,$%c"	"" 1s    ?AG% BG% %	H.HHc                 .     t                fd       }|S )zHelper to decorate tests which receive in the last argument tmpdir to pass to kill_srv

	To be used in tandem with @with_tmpdir
	c                 X    |d   }	  | g| t        |       S # t        |       w xY w)N)r   )selfr(   r   r_   s      r)   wrapperzwith_kill_srv.<locals>.wrapper:  s-    H'
D.4.W9Ws    )r	   )r_   r   s   ` r)   with_kill_srvr   5  s"    
 (  	r+   c                       fd}|S )z}Helper to decorate tests uses foreground server (as thread), started directly in test-cases

	To be used only in subclasses
	c                 D     t         t                fd              }|S )Nc                    	 d }t               	 t        fddi	t        d j                  	f      }d|_        |j                          t        t        ff 	fd	}| _        t        j                  fdt                j                  j                  dd               j                  d		       t        j                   d
        j#                           
 	g|i ||rWt        j                   d        j#                           j                          j                  dd       r|j%                          t'                S # t(        $ rD}t+        d|z          j-                         }|rt+        d|z          j#                           d }~ww xY w# |rWt        j                   d        j#                           j                          j                  dd       r|j%                          t'                w xY w)Nr   r   _TestCaseWorkernametargetr(   Tc                    t                j                  dd       sFt        j                  j	                  t        d            st        j                  fdt               j                  dd       sjj                  | d       t        j                  fdt               j                  j                  dd              j                  dddt        	       d
 _        y )Nendrv   c                  ,     j                  dd       d uS Nr   getphases   r)   r   zywith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapper.<locals>._stopAndWaitForServerEnd.<locals>.<lambda>_      UYYud34? r+   stopc                  ,     j                  dd       d uS r   r   r   s   r)   r   zywith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapper.<locals>._stopAndWaitForServerEnd.<locals>.<lambda>d  r   r+   Shutdown successfulzExiting Fail2banTallwaitc                       y rb   r:   )r(   r@   s     r)   r   zywith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapper.<locals>._stopAndWaitForServerEnd.<locals>.<lambda>h      r+   )r"   r   r   r   r   rj   r   r?   r8   execCmdr   
assertTrueassertLoggedstopAndWaitForServerEnd)coder   r   r   ry   s    r)   _stopAndWaitForServerEndzgwith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapper.<locals>._stopAndWaitForServerEnd[  s    IIeT"277>>%Y:O+Pnn?NIIeT"
ll4f-nn?N
ooeiit,-
-/AtR^_$@T!r+   c                  ,     j                  dd       d uS )Nstartr   r   s   r)   r   zWwith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapper.<locals>.<lambda>k  s    599Wd34? r+   r   )r   r   z=== within server: begin ===z=== within server: end.  ===r   z=== Catch an exception: %sz#=== Error of server, log: ===
%s===)dictr   r   _testStartForegrounddaemonr   SUCCESSFAILEDr   r   r?   r   r   r   _wait_for_srv	DefLogSysr&   pruneLogr   r"   r   r   getLog)r   ry   r(   r@   thr   r   r   r   r   r_   
startextras   ``      @@r)   r   zEwith_foreground_server_thread.<locals>._deco_wrapper.<locals>.wrapperI  s    	2656I{IjIK	
%%U
#
B
 BIHHJ (/&7 A A $<D 	NN?NOOEIIgt,-sDkGNN12MMOT35d5f5 
^^23	]]_	!!# 			%ggi#  
	'!+-
++-C

2S8:	]]_	
 
^^23	]]_	!!# 			%ggis%   C E 	F$ ?FF$$F' 'A%H)r   r
   )r_   r   r   s   ` r)   _deco_wrapperz4with_foreground_server_thread.<locals>._deco_wrapperH  s)    89  9t 
.r+   r:   )r   r   s   ` r)   with_foreground_server_threadr   C  s    
=| 	r+   c                       e Zd Zej                  Zd Zd Zd Ze	dd       Z
ddZd Zd Zd	 Z ed
di      d        Zeed               Zy)Fail2banClientServerBasec                      y rb   r:   )r   r(   r@   s      r)   _setLogLevelz%Fail2banClientServerBase._setLogLevel  s    r+   c                     t        j                  |        dt        _        t        j
                  t        _        t        | j                        t        _
        y)zCall before every test case.r   N)r   setUpr   DEF_LOGTARGETr   levelDEF_LOGLEVELstaticmethod
_test_exitr   _exitr   s    r)   r   zFail2banClientServerBase.setUp  s5    4 $&!&&t7/r+   c                     | j                   t        _        t        t        _        t        t        _        t        j                  |        t                y)zCall after every test case.N)
_orig_exitr   r  SRV_DEF_LOGTARGETr   r   SRV_DEF_LOGLEVELr  r   tearDownr"   r  s    r)   r
  z!Fail2banClientServerBase.tearDown  s2    ///*&(&d#r+   c                 4    | dk(  r
t               t               r%   )rG   rO   )r   s    r)   r  z#Fail2banClientServerBase._test_exit  s    	QY			r+   Nc                     si 	 t        |d      t        j                  fdt              }|rj	                  d      rt        d|      |r1t        j                   fdt              }|st        dd|      y y #  t        |      r,t        d j                         z          j                          t        |d	      }t        |      rt        |        t        |      st        j                  d
|        xY w)Nru   c                  @     j                  d      xs t              S r   )r   r   )r   socks   r)   r   z8Fail2banClientServerBase._wait_for_srv.<locals>.<lambda>  s    		% 0 @F4L r+   r   z7Unexpected: Socket file does not exists.
Start failed: c                  (    d j                         v S )NServer ready)r   r  s   r)   r   z8Fail2banClientServerBase._wait_for_srv.<locals>.<lambda>  s    4;;=!@ r+   z.Unexpected: Server ready was not found, phase z.
Start failed: z,=== Error by wait fot server, log: ===
%s===r   z*No log file %s to examine details of error)rj   r   r?   r   r   r   r   r   r   r   r   r   r   r.   )r   ry   readyr   r   retr   r  s   `   `  @r)   r   z&Fail2banClientServerBase._wait_for_srv  s    		
Z
 4	@,	O3
5!
  
..@,
OC	   		[!	:T[[]JLMMO	sI	3SkcN 	 ;'
LL=sCs   A=B A>Dc                 j    | j                  || j                  d   | j                  dd  |z   |z          y )Nr   r   )assertRaisesr   )r   exitTyper   r(   s       r)   r   z Fail2banClientServerBase.execCmd  s9    Hd44Q712,t36r+   c                     ||j                  d      dz      }t        |      }	 |j                  |      |j                          S # |j                          w xY w)Nr~   r   )r   r   sendr[   )r   r   r(   r  ss        r)   execCmdDirectz&Fail2banClientServerBase.execCmdDirect  sH    	[&&t,Q.	/$dm!
&&,7791779s   A Ac                     t         j                  d       d|d<   	 | j                  t        d|z   d       d|d<   d|d<   t         j                  d       y # d|d<   d|d<   t         j                  d       w xY w)Nzstart of test workerTr   z-fFr   zend of test worker)r   r.   r   r   )r   ry   r   r   s       r)   r   z-Fail2banClientServerBase._testStartForeground  sv    ,,%&%.&<<;.8 5>5<	<<$% 5>5<	<<$%s   A !A7r   )z[Thread]zstacksize = 128r   c                    | j                          | j                  t        |dd       | j                  d       | j                  t        |d       | j                  t        |d       | j                  t        |dd       y )Nr   threadz{'stacksize': 128}ping~~unknown~cmd~failed~~echo	TEST-ECHO)r   r   r   r   r   r   ry   r   s      r)   testStartForegroundz,Fail2banClientServerBase.testStartForeground  sa     --/,,wUH5(),,wV,,,v{$<=,,wV[9r+   c                 2    t         j                  st        j                  d      t	        |d      }t        j                  |      }|j
                  j                         }|j                  d       |j                          t        ||d      }ddi} fd}t        d	|||f
      }|j                          	  j                  t        d|z   d       d|d<   |j                           j                  ddd       y # d|d<   |j                          w xY w)NzSkip test because no databaseztmp.dbz#UPDATE fail2banDb SET version = 555r   )r   r   r   Tc                 h    t        j                  fdt              sj                  | d       y y )Nc                       d    S )Nr   r:   r   s   r)   r   z[Fail2banClientServerBase.testStartFailsInForeground.<locals>._stopTimeout.<locals>.<lambda>  s    U6]!2 r+   r   )r   r?   r   r  )r   r   r   s    `r)   _stopTimeoutzIFail2banClientServerBase.testStartFailsInForeground.<locals>._stopTimeout  s(    
..2L
A{F+ Br+   r   r   r  r   Fz/Attempt to travel to future version of databaseExit with code 255r   )r   
Fail2BanDbr   SkipTestrj   _dbcursorexecutescriptr[   r   r   r   r   r   r   r   )	r   ry   dbnamer   curr   r   r(  r   s	   `        r)   testStartFailsInForegroundz3Fail2banClientServerBase.testStartFailsInForeground  s    
					:	;;X& "
#9:))+cfD+4.%, 
	e"
 ((*<<+-w75=779ET  # 5=779s   ;C? ?D)r   )TNN)rI   rJ   rK   r   r  r  r   r   r
  r  r  r   r   r  r   r   r$  r   r   r2  r:   r+   r)   r   r     s    ##8  	<6
&  K 9 , 
:
: #  #r+   r   c                       e Zd ZeefZd Zd Zed        Z	ee
d               Zee
d               Zee
d               Zed        Zd Zy	)
Fail2banClientTestc                     | j                  t        t        t        t                           | j                  t        t        t        t
                           y rb   )r   r   rj   BINCLIENTSERVERr  s    r)   testConsistencyz"Fail2banClientTest.testConsistency  s2    //&sF+,-//&sF+,-r+   c                    | j                  t        dd       | j                  dt        z          | j                  d       | j	                          | j                  t        dd       | j                  t        j                                | j	                          | j                  t        ddd       | j                  dt
        j                  z          | j	                          | j                  t        dd	d
       | j                  d       y )Nr:   -hUsage: Report bugs to z-Vz-vqz	--versionz
Fail2Ban vz	--str2sec1d12h30m131400)r   r   r   r7  r   r   normVersionversionr  s    r)   testClientUsagez"Fail2banClientTest.testClientUsage  s    ,,wD!I&'%&--/,,wD!O//12--/,,wE;/L?#:#::;--/,,wK4Hr+   c                     t        |d      }| j                  t        |d       | j                  d       | j                  d       | j	                          | j                  t        |d       | j                  d       y )NTz-vvdzLoading filesz['set', 'logtarget',z--dp)r   r   r   r   r   r#  s      r)   testClientDumpz!Fail2banClientTest.testClientDump(  se     c4(+,,wV,O$*+--/,,wV,*+r+   c                 R   t        |d      }| j                  t        d|z   d       | j                  |d|       | j	                  d       | j	                  d       	 | j                  t        |dd       | j                  t
        |d	       | j                          | j                  t
        d|z   d       | j	                  d
       | j                          | j                  t        |d       | j	                  d       | j	                  d       | j                          | j                  t
        |d       | j	                  d       | j	                  d       y # | j                          | j                  t        |d       | j	                  d       | j	                  d       w xY w)NTz-br   r   r  Exit with code 0r!  r"  r   zServer already runningr   r   zFailed to access socket pathzIs fail2ban running?)r   r   r   r   r   r   r   r#  s      r)   testClientStartBackgroundInsidez2Fail2banClientTest.testClientStartBackgroundInside4  sU    c4(+,,w+-w7S$K8N#&')<<fk:<<%=>==?<<+-w7-.==?<<f-*+'(--/,,v{F+23*+ ==?<<f-*+'(s   A*E AF&c                 .	   t        |t        |d            }t        j                  j                  r| j                  t        |dz          nt        j                  t        t        t              f}t        j                  d|       ||z   dz   }t        j                  |t        dd      }| j!                  t#        |      xr |d	          | j%                  |d|
       | j'                  d       | j)                          	 | j                  t        |dd       | j'                  d       | j'                  d       | j)                          | j                  t        |dd       | j'                  d       | j)                          t+        t        |d            }	 t-        j.                  |t0        j2                         t5        j6                  t        j8                         | j                  t:        |dd       t-        j.                  |t0        j<                         | j'                  d       | j)                          	 d	d l}tD        g dz  a"| j                  t        |d       | j'                  d       | j'                  dd       | j'                  d       | j)                          tD        g dz  a"| j                  t        |d       | j'                  d       | j'                  d       | j'                  d       | j'                  d       | j)                          tD        ddgz  a"| j                  t        |d       | j'                  d        | j)                          | j                  t:        |d!d"       | j'                  d        | j'                  d#       | j)                          | j)                          | j                  t        |d$       | j'                  d       | j'                  d       y # t-        j.                  |t0        j<                         w xY w# t@        $ r}t        jB                  d|z        d }~ww xY w# | j)                          | j                  t        |d$       | j'                  d       | j'                  d       w xY w)%Nr   r   )r   Start %s ...)--asyncr   FTrC   shelloutputr   r   r  r!  r"  rG  r  z0.1zServer replied: pongrv   z1e-10z	timed outz%Skip test because of import error: %s)zecho INTERACT-ECHOstatusrQ   z-izINTERACT-ECHOStatuszNumber of jail:)reloadrestartrQ   zReading config files:r   zreload ~~unknown~jail~fail~~rQ   z@Failed during configuration: No section: '~~unknown~jail~fail~~'rR  z~~unknown~jail~fail~~r)  r   )#r   rj   r   r   fastr   r   sys
executabler6  r7  r   r.   r   
executeCmdr   r   rR   r   r   r   r   r   r   r   SIGSTOPr0   sleepDEFAULT_SHORT_INTERVALr   SIGCONTreadlineImportErrorr,  rS   )r   ry   r   cmdr  r   r\  r   s           r)   testClientStartBackgroundCallz0Fail2banClientTest.testClientStartBackgroundCallS  s    cU3	-BC+\\<<z12 ..%V,	-3	<<$	{	2	23			#|5	N3??3s8&A'c4S1N#--/F)<<fk:[!'(==?<<fe4+,==? 
E#y1	23!GGC JJu++,LLfg6 GGC [!==?I   8
 <<d+_%X01'(==?  8
 <<d+,-*+^$'(==?"
 8 <<d+WX==?<<X/FGWX)*==?==?<<f-*+'(c GGC   I


CaG
HHIN ==?<<f-*+'(sM   BQ	 AO7 :AQ	  P  E)Q	 7&PQ	  	Q)QQQ	 	ARc                     t        |d      }| j                  t        dddt        |d      d       | j	                  dt        |d      z   d	z          | j                          | j                  t        ddt        |d
      dt        |d      d       | j	                  d       | j                          t        t        |d      d      j                          | j                  t        dddt        |d
      dt        |d      d       | j	                  d       | j                          t        j                  t        |d             | j                  t        dd       | j	                  d       | j                          y )Nr   rJ  r:   rL  r}   missr   Base configuration directory  does not existrf   r~   ru   rR  Could not find serveraLFail2ban seems to be in unexpected state (not running but the socket exists)r<  
r   r   r   rj   r   r   rY   r[   r   remover#  s      r)   testClientFailStartz&Fail2banClientTest.testClientFailStart  s<    c[9+ ,,vrdE#v&13eC6HHK\\]--/ ,,vrsH	tU3
%;XG+,--/ uS*s#))+,,vrdE#x($c:0FQbc--/))E#z"# ,,vr4 I--/r+   c                    t        |d      }| j                  t        |dd       | j                  d       | j	                          | j                  t        |dddd       | j                  d       | j	                          y )	Nr   rJ  rR  jailrd  rL  z--xxxz"Unexpected argument(s) for reload:)r   r   r   r   r   r#  s      r)   testClientFailCommandsz)Fail2banClientTest.testClientFailCommands  sr     c[9+ ,,v{V+,--/ ,,v{h)89--/r+   c                     d}dD ]d  }d}t        |d      5 }|rI|j                          |r/t        j                  j                  st        j                  |       |dz  }|rId d d        f y # 1 sw Y   qxY w)NgQ?)r   r      r4   r   )r   	heartbeatr   r   rT  r0   rY  )r   	sleeptimeverbosecntrviss        r)   testVisualWaitz!Fail2banClientTest.testVisualWait  sv    ) g
47A #
]]_))
jj	QYT	   s   AA--A6	N)rI   rJ   rK   _exec_clientr7  r   r9  rB  r   rD  r   rH  r_  ri  rl  rt  r:   r+   r)   r4  r4    s    "F,. 	, 	, ,  ,: W)  W)r   :  "	r+   r4  c                   ~   e Zd ZeefZd Zeed               Z	eed               Z
eed               Zed        Z eddi      d	        Zej                   j#                  d
       edddd      d               Zej                   j#                  d       eddddd      d               Z e       d        Zy)Fail2banServerTestc                     | j                  t        dd       | j                  dt        z          | j                  d       y )Nr:   r;  r<  r=  )r   r   r   r8  r  s    r)   testServerUsagez"Fail2banServerTest.testServerUsage  s4    ,,wD!I&'%&r+   c                 *   t        |t        |d            }t        j                  t        t        t
              f}t        j                  d|       ||z   dz   }t        j                  |t        dd      }| j                  t        |      xr |d          | j                  |d|	       | j                  d
       | j                          	 | j!                  t"        |dd       | j!                  t$        |d       | j                          | j!                  t"        |d       | j                  d       | j                  d       y # | j                          | j!                  t"        |d       | j                  d       | j                  d       w xY w)Nr   rJ  rK  rF  FTrM  r   r   r  r!  r"  r   r   r   rG  )r   rj   rU  rV  r6  r8  r   r.   r   rW  r   r   rR   r   r   r   r   r   r   r   ry   r   r^  r  s        r)   testServerStartBackgroundz,Fail2banServerTest.testServerStartBackground  s>    cU3	-BC+	sF+,#,,~s#kG##l%M#//#c(%s1v&S$C0N#--/)<<fk:<<%=>==?<<f-*+'(	 ==?<<f-*+'(s   /E AFc                    t        |d      }| j                  t        ddt        |d             | j	                  dt        |d      z   dz          | j                          t        t        |d      d	      j                          | j                  t        ddt        |d
      dt        |d             | j	                  d       | j                          t        j                  t        |d             y )Nr   rJ  r:   r}   ra  rb  rc  ru   re  rf   r~   rf  rg  r#  s      r)   testServerFailStartz&Fail2banServerTest.testServerFailStart  s     c[9+ ,,vrsF	3eC6HHK\\]--/ uS*s#))+,,vrsH	tU3
%;=bc--/))E#z"#r+   c           	         t        |d      }t        |d      }| j                  d       | j                  t        |d       | j                  d       t        t        |d      dd	d
d	dd       | j                  d       | j                  t        |d       | j                  dddd       | j                  d       | j                  t        |dd       | j                  dddd       y )Nr   rJ  rf   z[test-phase 0]z--testz$OK: configuration test is successfulrh   re  rX   [broken-jail]filter = broken-jail-filterenabled = truez[test-phase 0a].Unable to read the filter 'broken-jail-filter'zErrors in jail 'broken-jail'.z ERROR: test configuration failedTr*  z[test-phase 0b]z-tr   )r   rj   r   r   r   r   r`   r   )r   ry   r   r   s       r)   testServerTestFailStartz*Fail2banServerTest.testServerTestFailStart!  s     c[9+c8# -- !,,wX.:; eC%sB$&68 --!",,v{H-D"%4  1
 --!",,v{D'2D"%4  1r+   c                 X   	 t        t        d            }t        j                  t        t        t
              f}t        j                  d|       ||z   dz   }t        j                  |t        dd      }| j                  t        |      xr |d          | j                  d|	       | j                  d
       | j                          t        j                  d       | j                  t!                     t        j"                  fdt               | j%                  t'        t        d                   | j                  d       | j                          | j                  t!                     | j                  d       y # | j                  t!                     w xY w)NzGf2b.log[format="SRV: %(relativeCreated)3d | %(message)s", datetime=off]rJ  rK  rF  FTrM  r   r   r  zKill server ... %sc                  0    t        t         d             S )Nrv   )r   rj   )ry   s   r)   r   z7Fail2banServerTest.testKillAfterStart.<locals>.<lambda>S  s    VE#y$9:: r+   rv   r   zcleanup: no pidfile for)r   rj   rU  rV  r6  r8  r   r.   r   rW  r   r   rR   r   r   r   r   r?   assertFalser   r{  s    `   r)   testKillAfterStartz%Fail2banServerTest.testKillAfterStart?  sD   #seCM/O P; ..%V,	-3	<<$	{	W	$3			#|5	N3??3s8&A'c4S1^$==?	<<$c*??9S>"..:LI6%Y/01)*--///)C.!-. ??9S>"s   C"F F)r   rg   r  c                    t        |d      t        |d      t        |d      t        |d      t        j                  t        d             	 	 dÈfd		}dĈfd
	} |d        |d        |dgg d       t        t        d      dddddd       t        dgt	        t        t        j                                     dz   fdz    t        d       t        d       | j                  d       t        j                  j                  t        j                  k  rt               | j                  t         |d       | j#                  dddt$               | j#                  dz         | j#                  d       | j#                  dd d!       | j#                  d"d#dt$               | j#                  d$d%d&d!       | j                  d'        |dd(g)       t        j                  j                  t        j                  k  rt               | j                  t         |d       | j#                  dt$        *       | j'                  d+dd!       | j#                  dz  dz  d!       | j#                  d,d-d!       | j#                  d.d/d!       | j#                  d0d1d!       | j'                  d2       | j                  d3        |dg)        |dd4dz  d5dz  d6dz  7       | j                  t         |d       | j#                  dt$        *       | j'                  d+dd!       | j'                  d8       | j#                  d,d9d!       | j#                  d:       | j#                  d;       | j'                  d<        |dd=>        |d(dg)       | j                  d?       t        d@gt	        t        t        j                                     dAz   fdz  t	        t        t        j                                     dBz   fdz  z   t	        t        t        j                                     dCz   fdz  z   t	        t        t        j                                     dDz   fdz  z     t        j                  j                  t        j                  k  rt               | j#                  dEdFdt$               | j                  t         |dGdHdIdJ       | j#                  dKt$        *       | j#                  dLdMdNdOdPdQdRd!       | j'                  dSdTdUdVd!       t)                | j+                  | j-                  |dW      dXdYg dZidHg d[igf       | j+                  | j-                  |dWd\d]d^      dXdYgdYdHgg gf       | j+                  | j-                  |d_dYdW      d   g dZ       | j+                  | j-                  |d_dHdW      d   g d[       | j/                  | j-                  |d_dYdWd`      d   d       | j/                  | j-                  |d_dYdWdJ      d   dX       | j/                  | j-                  |d_dYdWd`dJ      d   ddXg       | j                  da       | j                  t         |dbdH       | j#                  ddcdKdt$               | j#                  dddedfdgd/dhdidjd!	       | j#                  dkdldt$               | j'                  dmdnd!       | j                  do       | j                  t         |dGdHdIdp       | j                  t         |dGdHdIdq       | j#                  drdsdt$               t)                | j                  dt       | j                  t         |d_dHdIdu       | j#                  d]dvdpdqdt$               | j                  dw       | j                  t         |d_dYdI       | j#                  d\dxd`d]dvdt$               | j                  dy       | j                  t         |dbdzdH       | j#                  dd/dt$               | j#                  dgd/dddedfd!       | j#                  d{d|d!       | j#                  d}       | j'                  d~dd!       | j'                  dPdQd!        |dd=>        |g )       | j                  d       | j                  t         |ddY       | j#                  dt$        *       | j#                  ddd!       | j'                  dddd!       | j                  d        |dg       | j                  t         |d       | j#                  dt$        *       | j#                  d       | j#                  ddgd!       | j#                  dz  dz  d!       | j                  d       t        d@gt	        t        t        j                                     dz   fdz  t	        t        t        j                                     dz   fdz  z   t	        t        t        j                                     dz   fdz  z     t        j                  j                  t        j                  k  rt               | j#                  dddt$               | j#                  ddddd!       | j'                  d       | j                  d       | j                  t         |dddd       | j#                  dddt$               | j                  d       | j                  t         |ddd       | j#                  dddt$               | j                  t         |dddd       | j#                  dddt$               | j                  d       | j                  t         |ddGdYdIdd       | j#                  dddt$               | j                  t         |ddGdYdd       | j#                  dddt$               | j                  d       | j                  t         |ddz       | j#                  dt$        *       | j#                  dd+dd!       | j'                  ddddNd!       | j                  d       | j                  t         |ddd       | j#                  ddd!       | j                  d        |dgd       | j                  t0        |d       | j#                  dt$        *       | j#                  ddd!       | j                  d        |dg       | j                  t         |d       | j#                  dt$        *       | j                  d       | j                  t0        |dddH       | j#                  dt$        *       | j#                  d       | j                          | j                  t         |ddddH       | j#                  dt$        *       | j'                  d.d/d!       | j                  d       | j                  t         |dddd       | j#                  dt$        *       | j#                  dddt$               | j                  d       | j                  t         |ddGdYddd       | j                  t         |dd_dYd«       | j#                  ddd!       y )Nrf   	test1.logz	test2.logz	test3.logro   test-action1TrX   c                     t        dd| z        }|st        j                  |       y t        |ddddddd	d
dd|d|d|d|d|       t        j
                  j                  t        j                  k  rt        |       y y )Nro   %s.confrr   rx   z_exec_once = 0rX   rs   znorestored = %(_exec_once)sz
restore = zinfo = z<_use_flush_ = echo '[%(name)s] %(actname)s: -- flushing IPs'z6actionstart =  echo '[%(name)s] %(actname)s: ** start'z7actionreload = echo '[%(name)s] %(actname)s: .. reload'zMactionban =    echo '[%(name)s] %(actname)s: ++ ban <ip> %(restore)s%(info)s'z;actionunban =  echo '[%(name)s] %(actname)s: -- unban <ip>'z5actionstop =   echo '[%(name)s] %(actname)s: __ stop')
rj   r   rh  r`   r   r   r   r   r   r   )	actnameallowr   rR  banunbanr   r\   r   s	           r)   _write_action_cfgzBFail2banServerTest.testServerReloadTest.<locals>._write_action_cfgk  s    c:y7232
IIbM
r3!B<e=vSUXA5;T ll-bM .r+   c                    t        g t        d      ddddddddd	d
dddd|z   ddd|v rdndd|v rdndd|v rdnddz   d| v rdz   ndd| v rdz   ndd	d| v rdndd| v rdndddd|z   ddd|v rdndd|v rdnddz   d| v rdnd  t        j                  j                  t
        j                  k  rt        t        d             y y )Nrh   rr   rw   rX   rx   usedns = nomaxretry = 3zfindtime = 10mzBfailregex = ^\s*failure <F-ERRCODE>401|403</F-ERRCODE> from <HOST>datepattern = {^LN-BEG}EPOCHzignoreip = 127.0.0.1/8 ::1[test-jail1]
backend = filter =z	action = r   z*         test-action1[name='%(__name__)s']r   zj         test-action2[name='%(__name__)s', restore='restored: <restored>', info=', err-code: <F-ERRCODE>']   z         test-action2[name='%(__name__)s', actname=test-action3, _exec_once=1, restore='restored: <restored>', actionflush=<_use_flush_>]
logpath = z
          z@            ^\s*error <F-ERRCODE>401|403</F-ERRCODE> from <HOST>r  z[test-jail2]r`   rj   r   r   r   r   r   r   )enabledactionsbackendr   test1logtest2logtest3logs      r)   _write_jail_cfgz@Fail2banServerTest.testServerReloadTest.<locals>._write_jail_cfg  s"    $uS+& $ $$$$$ $ 	$
 $ J$ #$ !$ $ $ !7*$ -7$ $ 	
W 1$ 	
W q$$ 	
W(%$& 8'$(  !G|L8)$*  !G|L8+$, J-$0 	
W H1$2 W"3$4 5$6 7$6 !7*7$6 -77$8 9$< 	
W q=$B 	
W(C$D 8E$F W"G$J ll-eC%& .r+   )r  test-action2r   )r   r   r  )r  r  rh   re  r  r  r  rr   z# failure 401 from 192.0.2.1: test 1r  z[test-phase 1a]rR  Reload finished.z1 ticket(s) in 'test-jail1r   zAdded logfile: %rz[test-jail1] Ban 192.0.2.1z-stdout: '[test-jail1] test-action1: ** start'z-stdout: '[test-jail1] test-action2: ** start'r*  zPstdout: '[test-jail1] test-action2: ++ ban 192.0.2.1 restored: 0, err-code: 401'zAstdout: '[test-jail1] test-action3: ++ ban 192.0.2.1 restored: 0'r  z)Errors in jail 'broken-jail'. Skipping...z:Jail 'broken-jail' skipped, because of wrong configurationz[test-phase 1b]r   )r  r   z[test-jail1] Unban 192.0.2.1z.stdout: '[test-jail1] test-action1: .. reload'z.stdout: '[test-jail1] test-action2: .. reload'zCreating new jail 'test-jail2'zJail 'test-jail2' startedz4stdout: '[test-jail1] test-action3: -- flushing IPs'z,stdout: '[test-jail1] test-action3: __ stop'z7stdout: '[test-jail1] test-action3: -- unban 192.0.2.1'z[test-phase 2a]z+               echo '[<name>] %s: started.'z,               echo '[<name>] %s: reloaded.'z+               echo '[<name>] %s: stopped.')r  r   rR  r   zAdded logfile:z.stdout: '[test-jail1] test-action1: reloaded.'z7stdout: '[test-jail1] test-action2: -- unban 192.0.2.1'z,stdout: '[test-jail1] test-action2: __ stop'z7stdout: '[test-jail1] test-action1: -- unban 192.0.2.1'F)r  r  z[test-phase 2b]a+z#   error 403 from 192.0.2.2: test 2z#   error 403 from 192.0.2.3: test 2z# failure 401 from 192.0.2.4: test 2z# failure 401 from 192.0.2.8: test 2z2 ticket(s) in 'test-jail2z5 ticket(s) in 'test-jail1setz
test-jail2banip	192.0.2.9z3 ticket(s) in 'test-jail2z[test-jail1] Ban 192.0.2.2z[test-jail1] Ban 192.0.2.3z[test-jail1] Ban 192.0.2.4z[test-jail1] Ban 192.0.2.8z[test-jail2] Ban 192.0.2.4z[test-jail2] Ban 192.0.2.8z[test-jail2] Ban 192.0.2.9z[test-jail2] Found 192.0.2.2z[test-jail2] Ban 192.0.2.2z[test-jail2] Found 192.0.2.3z[test-jail2] Ban 192.0.2.3bannedr   
test-jail1)	192.0.2.4	192.0.2.1	192.0.2.8	192.0.2.3	192.0.2.2)r  r  r  r  r  z192.0.2.222r   r  z[test-phase 2c]rS  zRestore Banz[test-jail2] Unban 192.0.2.4z[test-jail2] Unban 192.0.2.8z[test-jail2] Unban 192.0.2.9zJail 'test-jail2' stoppedz"[test-jail2] Restore Ban 192.0.2.4z"[test-jail2] Restore Ban 192.0.2.8z"[test-jail2] Restore Ban 192.0.2.9zPstdout: '[test-jail2] test-action2: ++ ban 192.0.2.4 restored: 1, err-code: 401'zPstdout: '[test-jail2] test-action2: ++ ban 192.0.2.8 restored: 1, err-code: 401'zAstdout: '[test-jail2] test-action3: ++ ban 192.0.2.4 restored: 1'zAstdout: '[test-jail2] test-action3: ++ ban 192.0.2.8 restored: 1'z[test-phase 2d]z
192.0.2.21z
192.0.2.22z5stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22z6stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22 z[test-phase 2d.1]rW   r  z[test-phase 2d.2]r  z[test-phase 2e]z--unbanz7stdout: '[test-jail2] test-action2: -- unban 192.0.2.21z8stdout: '[test-jail2] test-action2: -- unban 192.0.2.22'z4stdout: '[test-jail2] test-action3: -- flushing IPs'z8stdout: '[test-jail2] test-action3: -- unban 192.0.2.21'z8stdout: '[test-jail2] test-action3: -- unban 192.0.2.22'z[test-phase 3]zReload jail 'test-jail1'zJail 'test-jail1' reloadedzReload jail 'test-jail2'zJail 'test-jail2' reloadedzJail 'test-jail1' startedz[test-phase 4])r  zStopping jail 'test-jail2'zRemoved logfile: %rz[test-phase 5]z# failure 401 from 192.0.2.1: test 5z#   error 403 from 192.0.2.5: test 5z# failure 401 from 192.0.2.6: test 5z6 ticket(s) in 'test-jail1z%[test-jail1] 192.0.2.1 already bannedz[test-jail1] Found 192.0.2.1z[test-jail1] Found 192.0.2.6z[test-jail1] Ban 192.0.2.6z[test-jail1] Found 192.0.2.5z[test-phase 6a]rL  r  z	192.0.2.5z	192.0.2.6z192.0.2.5 is not bannedz[test-jail1] Unban 192.0.2.6z[test-phase 6b]z192.0.2.2/31z[test-jail1] Unban 192.0.2.2z[test-jail1] Unban 192.0.2.3z192.0.2.8/31z192.0.2.100/31z[test-jail1] Unban 192.0.2.8z192.0.2.100/31 is not bannedz[test-phase 6c]z192.0.2.96/28z192.0.2.112/28z[test-jail1] Ban 192.0.2.96/28z[test-jail1] Ban 192.0.2.112/28unbanipz192.0.2.64/26z [test-jail1] Unban 192.0.2.96/28z![test-jail1] Unban 192.0.2.112/28z[test-phase 7]z[test-jail1] Unban 192.0.2.4zJail 'test-jail1' stoppedz[test-phase 7b]--allzFlush ban listz'Unbanned 0, 0 ticket(s) in 'test-jail1'z[test-phase 8a]zxxx-unknown-backend-zzz)r  r  z0Restart jail 'test-jail1' (reason: 'polling' != zUnknown backend z[test-phase 8b]z[test-phase end-1]z$the jail 'test-jail2' does not existz--if-existsz[test-phase end-2]	--restartz[test-phase end-3]addignoreipz192.0.2.1/32z2001:DB8::1/96ignoreip)r  TrX   rX   rX   rX   rX   ))r   r   r:   polling)rj   r   r   r`   r   r   r   r0   r   r   r   r   r   r   r   r   r   r   r8   assertNotLoggedr;   assertSortedEqualr  assertEqualr   )	r   ry   r   r  r  r   r  r  r  s	        @@@@r)   testServerReloadTestz'Fail2banServerTest.testServerReloadTest[  s2    	c8#3$(3$(3$(((5j!"6:/10'' ''T N+N+1#w/eC%sB$&68 hgC$6 7:_ _adeeghh --!"\\gmm+X,,wX.T  > '(230122  > UF,    3.?T  K --!"1Q% \\gmm+X,,wX.&\:!T  + !!t  - 33  ? #D  * 91t  = <> --!"1#N
7.
H
8>
I
7.
HJ ,,wX.&\:!T  + '(33  ? <> 13<> N%81Q% --!"h FKKMCCEIV[[]	DDFJKV[[]	DDFJK 	V[[]	DDFJK \\gmm+XT  > ,,w,.l  4T  + !!   ++KTU:;  ++K[+}689^lL12< 8
 ++K,""#%'EF ++K,""#%'+, 4%%k,+//024574%%k,+//024574%%k,+{<<=?BCQI --!",,wlT  >
 !!!'''T  	 UU,   
 FF   --!",,w,/,,w,/:;L  Z
 --#$,,wUL'4H\<T  V--#$,,wUL'B[+{S_  a --!",,wi'D|  = !!!t   <=4  I 9;==4  I T   N%8" -- !,,wX|<&\:T  + D   -- !1#,,wX.&\: D  * 8#8#  /
 -- !h FKKMCCEIFKKMCCEIJFKKMCCEIJ
 \\gmm+X*<  I !!*T	  + 56 --!",,wg{K1!t,  
 --!",,wg~'!!t,   ,,wg~'79!!t,  @
 --!",,we\7O=MO#$$\   ,,we\9o?%&D|   -- !,,wY&\:!!t   T	   --!",,wgw ,$  8
 --!"1#'@A,,v{H-&\:54  ! --!"1#,,wX.&\: --$%,,v{h&&\::;--/,,wh|5&\:#D  *
 --$%,,whW.&\:D|  =
 --$%,,we\=.BRT,,we\:/N$4$?r+   znginx-block-map)action)%(tmp)s/blck-failures.log)ro   )z[nginx-blck-lst]rq   r  z#logpath = %(tmp)s/blck-failures.logzoaction = nginx-block-map[srv_cmd="echo nginx", srv_pid="%(tmp)s/f2b.pid", blck_lst_file="%(tmp)s/blck-lst.map"]z         blocklist_de[actionban='curl() { echo "*** curl" "$*";}; <Definition/actionban>', email="Fail2Ban <fail2ban@localhost>", apikey="TEST-API-KEY", agent="fail2ban-test-agent", service=<name>]r  datepattern = ^Epochz3failregex = ^ failure "<F-ID>[^"]+</F-ID>" - <ADDR>zmaxretry = 1r  )r   r   r   c                    t        |d      }dd|iz  }dd|iz  }t        |dt        t        t	        j
                                     dz   t        t        t	        j
                                     dz   t        t        t	        j
                                     dz   t        t        t	        j
                                     d	z   t        t        t	        j
                                     d
z          | j                  dddddddt               t        |       t        |      }| j                  d|       | j                  d|       | j                  d|       | j                  d|       | j                  d|       | j                  ddd       | j                  dddt               | j                  t        |dddd        t        |       t        |      }| j                  d|       | j                  d|       | j                  d|       | j                  d|       | j                  d|       | j                  t               | j                  d!       t        |       t        |      }| j                  |d"       y )#Nrf   r  ry   z%(tmp)s/blck-lst.mapw+z" failure "125-000-001" - 192.0.2.1z" failure "125-000-002" - 192.0.2.1u1    failure "125-000-003" - 192.0.2.1 (òðåòèé)u1    failure "125-000-004" - 192.0.2.1 (òðåòèé)z" failure "125-000-005" - 192.0.2.1z [nginx-blck-lst] Ban 125-000-001z [nginx-blck-lst] Ban 125-000-002z [nginx-blck-lst] Ban 125-000-003z [nginx-blck-lst] Ban 125-000-004z [nginx-blck-lst] Ban 125-000-005z5 ticket(s)Tr   z\125-000-001 1;
z\125-000-002 1;
z\125-000-003 1;
z\125-000-004 1;
z\125-000-005 1;
zstdout: 'nginx -qt'zstdout: 'nginx -s reload'r*  zstdout: '*** curl --fail --data-urlencode server=Fail2Ban <fail2ban@localhost> --data apikey=TEST-API-KEY --data service=nginx-blck-lst z=stdout: ' --data format=text --user-agent fail2ban-test-agentr  z125-000-001z125-000-002z125-000-005z5[nginx-blck-lst] Flush ticket(s) with nginx-block-maprX   )rj   r`   r   r   r   r0   r   r8   r   rd   assertInr   r   assertNotInr   r  )r   ry   r   r   lgfnmpfnmps          r)   testServerActions_NginxBlockMapz2Fail2banServerTest.testServerActions_NginxBlockMapG  s5   . 	c8#	$s|	3$	5#,	.$dDs6;;=AAs6;;=AAs6;;=\\s6;;=\\s6;;=AA %%%%%,   D/$"--$b)--$b)--$b)--$b)--$b) )+FDQQB,	   ,,wWm]MZD/$"',',',--$b)--$b) w' KLD/$"2rr+   zsendmail-auth)filter)%(tmp)s/test.logT)rx   zdbmaxmatches = 1)a  test_action = dummy[actionstart_on_demand=1, init="start: %(__name__)s", target="%(tmp)s/test.txt",
      actionban='<known/actionban>; echo "found: <jail.found> / <jail.found_total>, banned: <jail.banned> / <jail.banned_total>"
        echo "<matches>"; printf "=====\n%%b\n=====\n\n" "<matches>" >> <target>',
      actionstop='<known/actionstop>; echo "stats <name> - found: <jail.found_total>, banned: <jail.banned_total>"']z[sendmail-auth]rq   r  logpath = %(tmp)s/test.logaction = %(test_action)sz%filter = sendmail-auth[logtype=short]r  r  zmaxmatches = 2r  z[sendmail-reject]rq   r  r  r  z'filter = sendmail-reject[logtype=short]r  r  r  )r   r   r   r   c           	         t        |d      }dd|iz  }dd|iz  }t        t        t        j                                     dz   t        t        t        j                                     dz   t        t        t        j                                     dz   f}t        t        t        j                                     dz   t        t        t        j                                     d	z   t        t        t        j                                     d
z   f}| j                  d       t        |dg|  | j                  ddddt               t        |       t        |      }|d   }	| j                  |	|       |dd  D ]  }	| j                  |	|        | j                  d       t        |dg|  | j                  ddddt               t        |       t        |      }|D ]  }	| j                  |	|        | j                  d       | j                  t        |ddd       | j                  ddddddt               t        |      }|d    }	| j                  |	       | j                  |	|       |dd  D ]%  }	| j                  |	       | j                  |	|       ' | j                  d!ddt               t        |      }|d    }	| j                  |	       | j                  |	|       |dd  D ]%  }	| j                  |	       | j                  |	|       ' | j                  d"       | j!                  t               | j#                  t%        |             y )#Nrf   r  ry   z%(tmp)s/test.txtz] smtp1 sm-mta[5133]: s1000000000001: [192.0.2.1]: possible SMTP attack: command=AUTH, count=1z] smtp1 sm-mta[5133]: s1000000000002: [192.0.2.1]: possible SMTP attack: command=AUTH, count=2z] smtp1 sm-mta[5133]: s1000000000003: [192.0.2.1]: possible SMTP attack: command=AUTH, count=3z smtp1 sm-mta[21134]: s2000000000001: ruleset=check_rcpt, arg1=<123@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <123@example.com>... Relaying denied. Proper authentication required.z smtp1 sm-mta[21134]: s2000000000002: ruleset=check_rcpt, arg1=<345@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <345@example.com>... Relaying denied. Proper authentication required.z smtp1 sm-mta[21134]: s3000000000003: ruleset=check_rcpt, arg1=<567@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <567@example.com>... Relaying denied. Proper authentication required.z[test-phase sendmail-auth]r  z[sendmail-auth] Ban 192.0.2.1z%stdout: 'found: 0 / 3, banned: 1 / 1'z1 ticket(s) in 'sendmail-auth'Tr   r   r   z[test-phase sendmail-reject]r  z[sendmail-reject] Ban 192.0.2.2z 1 ticket(s) in 'sendmail-reject'z[test-phase restart sendmail-*]rR  r  r  r  z3stdout: 'stats sendmail-auth - found: 3, banned: 1'z5stdout: 'stats sendmail-reject - found: 3, banned: 1'z%[sendmail-auth] Restore Ban 192.0.2.1r   z'[sendmail-reject] Restore Ban 192.0.2.2z[test-phase stop server])rj   r   r   r   r0   r   r`   r   r8   r   rd   r  r  r   r   r  r   r  r   )
r   ry   r   r   r  tofn	smaut_msg	smrej_msgtdms
             r)   testServerJails_Sendmailz+Fail2banServerTest.testServerJails_Sendmail  sN   R 	c8#	ucl	*$	ucl	*$ s6;;=||s6;;=||s6;;=||) s6;;=  s  ss6;;=  s  ss6;;=  s  s) --,-dD%9%"%L#L  B D/$"l!1bQR= a==B --./dD%9%$&M%4l  D D/$" a==B --12,,w['# 8:*,LRV]i	  k $"m!A--2Qr? aAr ,.PVZam  o$"m!A--2Qr? aAr --*+w' 6$< r+   c           	        	
 t        |d      t        |d      t        j                  t        d             d8fd	}d9fd	} |dd	        |d
d	        |        t        d       | j	                  d       | j                  t        |d       t        dgt        t        t        j                                     dz   fdz    t                | j                  dddt               t                | j	                  d       t        d       t                | j                  ddddt               t                | j	                  d       dt        fd       t        dgt        t        t        j                                     dz   fdz    | j                  dddt               | j	                  d        | j                  t        |d!d"d#d$       | j                  d%d&dt               dt                | j	                  d'       t        d(       t                | j                  d)dt               t                | j	                  d*       | j                  t        |d!d"d#d$       | j                  d%d+dt               | j	                  d,       t!                d-d.it"        j$                  		fd/}	j'                  d0|       	j'                  d0d1        t)        j*                  fd2t,               	j.                  
t0        j2                  j4                  rd3nd4df
fd5	}|	_        | j7                  t               | j9                  d6       | j;                  	j<                         | j?                  	j@                  d        dd-<   | j                  d6d7       	jC                          y ):Nrf   r  ro   r  Tc           
          t        dd| z        }t        |ddddd|rdndd	       t        j                  j                  t
        j                  k  rt        |       y y )
Nro   r  rr   rx   rX   rs   zeactionban =     printf %%s "[%(name)s] %(actname)s: ++ ban <ip> -c <bancount> -t <bantime> : <F-MSG>"ziactionprolong = printf %%s "[%(name)s] %(actname)s: ++ prolong <ip> -c <bancount> -t <bantime> : <F-MSG>"zBactionunban =   printf %%b '[%(name)s] %(actname)s: -- unban <ip>')rj   r`   r   r   r   r   r   r   )r  prolongr\   r   s      r)   r  z@Fail2banServerTest.testServerObserver.<locals>._write_action_cfg  sa    c:y7232r3m rH ll-bM .r+   c                     t        t        d      ddddddddd	d
dddd| z   ddddz   ddd       t        j                  j                  t
        j                  k  rt        t        d             y y )Nrh   rr   rw   rX   rx   r  r  zfindtime = 1mzbantime = 5mzbantime.increment = truer  r  r  r  z*action = test-action1[name='%(__name__)s']z*         test-action2[name='%(__name__)s']r  zXfailregex = ^\s*failure <F-ERRCODE>401|403</F-ERRCODE> from <HOST>:\s*<F-MSG>.*</F-MSG>$r  r  )r  r   r  s    r)   r  z>Fail2banServerTest.testServerObserver.<locals>._write_jail_cfg%  s    uS+&""L7*J008_!$ ll-eC%& .r+   F)r  r  r  rr   z[test-phase 0) time-0]rR  r  z> failure 401 from 192.0.2.11: I'm bad "hacker" `` $(echo test)r  zDstdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 1 -t 300 : zDstdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 1 -t 300 : r   z[test-phase 1) time+10m]
   z7stdout: '[test-jail1] test-action1: -- unban 192.0.2.11z7stdout: '[test-jail1] test-action2: -- unban 192.0.2.11z0 ticket(s) in 'test-jail1'z[test-phase 2) time+10m]c                       S rb   r:   )wakeObss   r)   r   z7Fail2banServerTest.testServerObserver.<locals>.<lambda>`  s     r+   r  zC failure 401 from 192.0.2.11: I'm very bad "hacker" `` $(echo test)r   zDstdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 2 -t 300 : zDstdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 2 -t 300 : z"[test-phase 2) time+10m - get-ips]r   r  r  z--with-timez
192.0.2.11z+ 300 =z[test-phase 2) time+11m]r   zHstdout: '[test-jail1] test-action2: ++ prolong 192.0.2.11 -c 2 -t 600 : z"[test-phase 2) time+11m - get-ips]z+ 600 =z'[test-phase end) stop on busy observer]stater   c                      t         j                  d       d d<   t        j                   fdt               j                          t         j                  d       y )Nz!++ observer enters busy state ...r   r  c                       d   dk(  S )Nr  r   r:   re  s   r)   r   zMFail2banServerTest.testServerObserver.<locals>._long_action.<locals>.<lambda>  s    !G*/ r+   z-- observer leaves busy state.)r   r&   r   r?   r   db_purge)re  obsMains   r)   _long_actionz;Fail2banServerTest.testServerObserver.<locals>._long_action  sA    	;;231W:>>)<8
	;;/0r+   callc                       y rb   r:   r:   r+   r)   r   z7Fail2banServerTest.testServerObserver.<locals>.<lambda>  r   r+   c                       d   dk(  S )Nr  r   r:   r  s   r)   r   z7Fail2banServerTest.testServerObserver.<locals>.<lambda>  s    7q r+   g{Gz?g?c                      | |      S rb   r:   )wtime	forceQuitobsMain_stops     r)   _stopz4Fail2banServerTest.testServerObserver.<locals>._stop  s    
ui
((r+   zobserver leaves busy stater  )r  T)r  )"rj   r   r   r`   r   r   r   r   r   r   r0   r;   r   r8   r2   rE   r"   r5   r6   addr   r?   r   r   r   r   rT  r   r  r  idler  _ObserverThread__dbr   )r   ry   r   r  r  r  r  re  r   r  r  r  r  s          @@@@@@r)   testServerObserverz%Fail2banServerTest.testServerObserver  sD   c8#3$(((5j!"'. NE:ND9h--(),,wX.h V[[]	aacfgg II,   
 --*+b/<< ,	   
 --*+ '0h V[[]	ffhkll II,   
 --45,,wUL'=Q<  9 '--*+a.M,   
 --45,,wUL'=Q<  9 --9:l!NN'1 
++fl#	++fl#..(,7,#<<,,4#$ )',w'347<< 7..5!G*0t<	,,.r+   N)rI   rJ   rK   _exec_serverr8  r   ry  r   r   r|  r~  r  r  r   r  r   r   skip_if_cfg_missingr  r  r  _testServerStartStoptestServerStartStopr:   r+   r)   rw  rw    sN   "F,'
 )  ). $  $$ 1  18 / /6  D&>:h@ ;h@V ,,""*;"<7 , *:+ =,:x ,,""/":.
&, &NN!O& ;PN!`  !O "Od 
r+   rw  )FNz	/dev/nullz:memory:r:   )rX   N)`
__author____copyright____license__r   r   r   rU  r0   r   r   os.pathr   rj   r   r   r   r   	functoolsr
   	threadingr   clientr   r   r   client.fail2bancmdliner   client.fail2banclientr   ru  r   r   client.fail2banserverr   r  rX   r   r   server.mytimer   server.utilsr   utilsr   r   r   r   r   r   r   r    r   r!   r"   helpersr#   rI   r7  r8  getServerPathr6  r   maxWaitTimer   r8   r   r  r  r	  r*   rO  r2   r5   r;   rE   rG   rO   r   r   rS   rU   input_command
PRODUCTIONdumpFiler   r`   rd   r   r   r   r   r   r   r   r4  rw  r:   r+   r)   <module>r     s8  , 
[  	 	 
    A A   D D 4 Z Z U   "  ? ? ?   
8			*n**,-||''(A(AB||''(A(AB  ,a/        (( && 
        * 	- 1= &*O11 
55 
 	  3  ""   ''	
 7;;@Un)X .0 CLF#1 F#RV1 VrA 1 A r+   