
    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	m
Z
 ddlZddlmZmZmZ ddlmZ ej$                  d	k\  rddlZnddlZ ee      Zd
diZ ed ej4                  j7                         D              Z G d d      Zy)z2Serg G. Brester (sebres) and Fail2Ban ContributorszYCopyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko, 2012-2015 Serg G. BresterGPL    N)Lock   )	getLogger_merge_dicts
uni_decode)OrderedDict   r      am  "Command not found".  Make sure that all commands in %(realCmd)r are in the PATH of fail2ban-server process (grep -a PATH= /proc/`pidof -x fail2ban-server`/environ). You may want to start "fail2ban-server -f" separately, initiate it with "fail2ban-client reload" in another shell session and observe if additional informative error messages appear in the terminals.c              #   L   K   | ]  \  }}|j                  d       r||f  yw)SIGN)
startswith).0namenums      7/usr/lib/python3/dist-packages/fail2ban/server/utils.py	<genexpr>r   7   s-      ET3T__U-C T{ Es   "$c                       e Zd ZdZdZdZdZedz  Z G d de      Z	e
d        Ze
d	        Ze
	 	 dd       Ze
dd       Zej                   dk(  r	e
d        Zne
d        Ze
d        Zy
)UtilszPUtilities provide diverse static methods like executes OS shell commands, etc.
	r   g?gMbP?d   c                   >    e Zd ZdZd Zd
dZd ZddZd Zd Z	d	 Z
y)Utils.Cachez.A simple cache with a TTL and limit on size
		c                 d     | j                   |i | t               | _        t               | _        y N)
setOptionsr	   _cacher   _Cache__lock)selfargskwargss      r   __init__zUtils.Cache.__init__H   s'    4??D#F#4;4;    c                      || _         || _        y r   )maxCountmaxTime)r   r%   r&   s      r   r   zUtils.Cache.setOptionsM   s    4=4<r#   c                 ,    t        | j                        S r   )lenr   r   s    r   __len__zUtils.Cache.__len__Q   s    
dkk
r#   Nc                     | j                   j                  |      }|r0|d   t        j                         kD  r|d   S | j                  |       |S )N   r   )r   gettimeunset)r   kdefvvs       r   r-   zUtils.Cache.getT   sB    {{q1tdiikaD[JJqM
;r#   c                 T   t        j                          }| j                  }| j                  5  t        |      | j                  k\  r;|r9|j                  d      \  }}|d   |kD  rt        |      | j                  k  rn|r9||| j                  z   f||<   d d d        y # 1 sw Y   y xY w)NF)lastr,   )r.   r   r   r(   r%   popitemr&   )r   r0   r2   tcacheckcvs          r   setzUtils.Cache.set\   s    yy{1;;5 
%
5zT]]"E*hr2	As5zDMM1	  1t||#$E!H
% 
% 
%s   ABBB'c                 ~    | j                   5  | j                  j                  |d        d d d        y # 1 sw Y   y xY wr   )r   r   pop)r   r0   s     r   r/   zUtils.Cache.unsetl   s0     KKOOAt  s   3<c                 z    | j                   5  | j                  j                          d d d        y # 1 sw Y   y xY wr   )r   r   clearr)   s    r   r>   zUtils.Cache.clearp   s.     KK  s   1:)i  <   r   )__name__
__module____qualname____doc__r"   r   r*   r-   r:   r/   r>    r#   r   Cacher   D   s*    
% r#   rE   c                     t        j                   | t         j                        }|s|t        j                  z  }n|t        j                   z  }t        j                   | t         j                  |       |S r   )fcntlF_GETFLos
O_NONBLOCKF_SETFL)fhandlevalueflagss      r   setFBlockModezUtils.setFBlockModeu   sP    
++gu}}
-%	BMM5R]]N5++gu}}e,	,r#   c                     d}t        | t              s| g} t        |       dz
  }|j                         D ]&  \  }}||d|dz  }| j	                  |       |dz  }( |dz   | d   z   | d<   | S )a  Generates new shell command as array, contains map as variables to
		arguments statement (varsStat), the command (realCmd) used this variables and
		the list of the arguments, mapped from varsDict

		Example:
			buildShellCmd('echo "V2: $v2, V1: $v1"', {"v1": "val 1", "v2": "val 2", "vUnused": "unused var"})
		returns:
			['v1=$0 v2=$1 vUnused=$2 
echo "V2: $v2, V1: $v1"', 'val 1', 'val 2', 'unused var']
		 r,   z=$ 
r   )
isinstancelistr(   itemsappend)realCmdvarsDictvarsStatir0   r2   s         r   buildShellCmdzUtils.buildShellCmd   s     (	GT	"Y7	'l1n!nn 
daAq!!8
>>!61
 $+'!*	.r#   Nc           	          dx}}d}	dx}
|r3|rt         j                   |       nt        t        j                  |      }
t                fd}	 t        j                   t        j                  t        j                  ||
t        j                        j                         }	|	1fd}t         j                  ||t         j                        }	|	r|	d   }	|	.|r |t        j                         d}t        j!                  d|fz         t        j"                  j$                        }t        j&                  |t(        j*                         t-        j.                  t         j0                         j                         }	|	|rYt        j&                  |t(        j2                         t-        j.                  t         j0                         |	j                         }	|	%t         j5                  |      st(        j2                  }	|	|v rt        j8                  nt        j                  }|t        j;                         k\  r2|r0 ||t        j8                  k(  r|dz
  nt        j                         d}|s|t        j;                         k\  rDj<                  r	 |	|	d	k  r t         j?                  j<                  d       j<                  jA                         }|R|dk7  rM|t        j;                         k\  r6|jE                         D ]#  }t        jG                  |dtI        |             % jJ                  r	 |	|	d	k  r t         j?                  jJ                  d       jJ                  jA                         }|R|dk7  rM|t        j;                         k\  r6|jE                         D ]#  }t        jG                  |dtI        |             % j<                  rj<                  jM                          jJ                  rjJ                  jM                          d}|	|v rt        jO                  d|	       d}n|	"t        j!                  dj$                         n|	d	k  s|	dkD  r=|	d	k  r|	 n|	dz
  }t        j!                  dtP        jS                  |d|z        |	       nQtT        jS                  |	d      }t        j!                  d|	       |r"t        jW                  d|	|tY               z         |r||||	fS t[        |      dk(  r|S ||	fS # t6        $ rR}|r |t        j                         d} d|}t        j!                  |       s|sdnd|||	fcY d}~S Y d}~ed}~ww xY w# tB        $ r!}t        j!                  d
|       Y d}~d}~ww xY w# tB        $ r!}t        j!                  d|       Y d}~Hd}~ww xY w)a  Executes a command.

		Parameters
		----------
		realCmd : str
			The command to execute.
		timeout : int
			The time out in seconds for the command.
		shell : bool
			If shell is True (default), the specified command (may be a string) will be 
			executed through the shell.
		output : bool
			If output is True, the function returns tuple (success, stdoutdata, stderrdata, returncode).
			If False, just indication of success is returned
		varsDict: dict
			variables supplied to the command (or to the shell script)

		Returns
		-------
		bool or (bool, str, str, int)
			True if the command succeeded and with stdout, stderr, returncode if output was set to True

		Raises
		------
		OSError
			If command fails to be executed.
		RuntimeError
			If command execution times out.
		Nc                 4    t         j                  | d      S )Nz%x -- exec: %s)logSyslog)levelrX   	realCmdIds    r   <lambda>z"Utils.executeCmd.<locals>.<lambda>   s    E+;YP r#   )stdoutstderrshellenv
preexec_fnc                  4    j                         } | d| fS d S )NT)poll)retcodepopens    r   _popen_wait_endz)Utils.executeCmd.<locals>._popen_wait_end   s"    zz|W&2T7O<<r#   r,   z!%x -- timed out after %s seconds.z -- failed with Fr   z  ... -- failed to read stdout %srQ   z%x -- stdout: %rz  ... -- failed to read stderr %sz%x -- stderr: %rz%x -- returned successfully %iTz%x -- unable to kill PID %i   z&%x -- killed with %s (return code: %s)z	signal %iz%x -- returned %izHINT on %i: %s).r   r\   r   rI   environid
subprocessPopenPIPEsetsidrj   wait_forDEFAULT_SHORTEST_INTERVALloggingERRORr_   errorgetpgidpidkillpgsignalSIGTERMr.   sleepDEFAULT_SLEEP_INTERVALSIGKILL
pid_existsOSErrorDEBUGgetEffectiveLevelrd   rO   readIOError
splitlinesr`   r   re   closedebugsignamer-   _RETCODE_HINTSinfolocalsr(   )rX   timeoutrf   outputtout_kill_treesuccess_codesrY   rd   re   rk   rg   logCmdrm   pgide	std_levellsuccesssigcodemsgrl   rb   s   `                   @@r   
executeCmdzUtils.executeCmd   s   @ &6'%#!!'84G
rzz8
,Ck)P&'EJOOJOO5cyy5
 ZZ\7o= nn_gu7V7VWGqzWovgmm$tf
LL4 ::eii DIIdFNN#JJu++,jjlG.YYtV^^$	ZZ,,-

gu//5~~W  '-7gmmW]])&**,,fI$>Yq[GMMR]aTZyF4466 ll97Q;%,,.ll!V flyF<T<T<V/V! Jjj.	:a=IJll97Q;%,,.ll!V flyF<T<T<V/V! Jjj.	:a=IJ \\5<<%%'
\\5<<%%''	<<0)WE7	<<-y%))D{gm 1gX'C-7	<<8w{{7K'$9:GE 
		GT	*3	<<#Y8	
KK '3>:
667
**&!+C'71CCq 
 EfW]]#dV&-q16	<<
5UFFG$DD 	E&  9\\4a889  9\\4a889sR   F9T "AU; AV( 	U8&AU3'U83U8;	V%V  V%(	W1WWc                    d}	  |        }|r|S |r.dx}}t        |      st        j                         |z   fd}n|}        r	 |S t        |xs t        j                  z   t        j
                        }t        j                  |       )a5  Wait until condition expression `cond` is True, up to `timeout` sec

		Parameters
		----------
		cond : callable
			The expression to check condition 
			(should return equivalent to bool True if wait successful).
		timeout : float or callable
			The time out for end of wait
			(in seconds or callable that returns True if timeout occurred).
		interval : float (optional)
			Polling start interval for wait cycle in seconds.

		Returns
		-------
		variable
			The return value of the last call of `cond`, 
			logical False (or None, 0, etc) if timeout occurred.
		r,   r   c                  2    t        j                           kD  S r   )r.   )time0s   r   rc   z Utils.wait_for.<locals>.<lambda><  s    DIIK%/ r#   )callabler.   minr   r   DEFAULT_SLEEP_TIMEr   )condr   intervaliniretstmtimeout_exprr   s          @r   ru   zUtils.wait_for  s    , 	
#	3	J	MC#GYY[7"U/\\n	 
* 
SH< < <=u?W?W	X3::c? 	r#   posixc                     ddl }| dk  ry	 t        j                  | d       y# t        $ r#}|j                   |j                  k(  cY d}~S d}~ww xY w)z6Check whether pid exists in the current process table.r   NFT)errnorI   killr   EPERM)r{   r   r   s      r   r   zUtils.pid_existsH  sM     	AgGGCO   "77ekk!!"s   # 	AA
A
Ac                     dd l }|j                  j                  }d}|j                  |d|       }|dk7  r|j	                  |       yy)Nr   i   TF)ctypeswindllkernel32OpenProcessCloseHandle)r{   r   r   SYNCHRONIZEprocesss        r   r   zUtils.pid_existsU  sH    mm$$8;!!+q#67l!r#   c                 6   t         j                  j                  t         j                  j                  |             d   }t        j
                  dk\  r0t        j                  j                  ||       j                         }|S t        j                  ||       }|S )Nr   r
   )rI   pathsplitextbasenamesysversion_info	importlib	machinerySourceFileLoaderload_moduleimpload_source)pythonModulepythonModuleNamemods      r   load_python_modulezUtils.load_python_moduleb  s    WW%%77L!##$&				-	-l
$$/KM 
 
* 
l
$3	*r#   )r?   TFT)r   Nr   )r@   rA   rB   rC   r   r   DEFAULT_SHORT_INTERVALrv   objectrE   staticmethodrO   r\   r   ru   rI   r   r   r   rD   r#   r   r   r   :   s     3c9.V .b    , NR#DD DDL % %R GGw
 
 
 
 	 	r#   r   )
__author____copyright____license__rG   rw   rI   r}   rq   r   	threadingr   r.   helpersr   r   r   collectionsr	   r   importlib.machineryr   r   r@   r_   r   dict__dict__rV   r   r   rD   r#   r   <module>r      s   ( B
k   	   
   9 9 #v 
8	  D  E//'')E Er rr#   