
$Sc           @   s  d  Z  d Z d Z d d l 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 d d
 l m Z d d l m Z m Z 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 e j d  Z d e
 f d     YZ d e f d     YZ y d d l  Z  e  j! Z" Wn& e# k
 rzd d l! Z! e! j$ Z" n Xd f  d     YZ% d d l& Z& d d l' Z' d f  d     YZ( d S(   s'   Cyril Jaquier and Fail2Ban Contributorss>   Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenkot   GPLiN(   t   FailManagerEmpty(   t   FailManager(   t
   FailTicket(   t
   JailThread(   t   DateDetector(   t   MyTime(   t	   FailRegext   Regext   RegexException(   t   Actions   fail2ban.filtert   Filterc           B   s
  e  Z d  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   Z d   Z d   Z d   Z d   Z d   Z e e d  Z d   Z d   Z e e d  Z d   Z RS(   t   warnc         C   s   t  j |   | |  _ t   |  _ t   |  _ t   |  _ |  j |  d |  _	 g  |  _
 t |  _ t   |  _ |  j j   t j d |   d  S(   Nip  s
   Created %s(   R   t   __init__t   jailR   t   failManagert   listt   _Filter__failRegext   _Filter__ignoreRegext	   setUseDnst   _Filter__findTimet   _Filter__ignoreIpListt   Falset   _Filter__ignoreCommandR   t   dateDetectort   addDefaultTemplatet   logSyst   debug(   t   selfR   t   useDns(    (    s$   /usr/share/fail2ban/server/filter.pyR   7   s    				c         C   s   d |  j  j |  j f S(   Ns   %s(%r)(   t	   __class__t   __name__R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   __repr__O   s    c         C   sM   y  t  |  } |  j j |  Wn& t k
 rH } t j |  |  n Xd  S(   N(   R   R   t   appendR	   R   t   error(   R   t   valuet   regext   e(    (    s$   /usr/share/fail2ban/server/filter.pyt   addFailRegexY   s    c         C   s7   y |  j  | =Wn" t k
 r2 t j d |  n Xd  S(   Ns7   Cannot remove regular expression. Index %d is not valid(   R   t
   IndexErrorR   R"   (   R   t   index(    (    s$   /usr/share/fail2ban/server/filter.pyt   delFailRegexb   s
    	c         C   s4   t    } x$ |  j D] } | j | j    q W| S(   N(   R   R   R!   t   getRegex(   R   t	   failRegexR$   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getFailRegexn   s    	c         C   sM   y  t  |  } |  j j |  Wn& t k
 rH } t j |  |  n Xd  S(   N(   R   R   R!   R	   R   R"   (   R   R#   R$   R%   (    (    s$   /usr/share/fail2ban/server/filter.pyt   addIgnoreRegex{   s    c         C   s7   y |  j  | =Wn" t k
 r2 t j d |  n Xd  S(   Ns7   Cannot remove regular expression. Index %d is not valid(   R   R'   R   R"   (   R   R(   (    (    s$   /usr/share/fail2ban/server/filter.pyt   delIgnoreRegex   s
    	c         C   s4   t    } x$ |  j D] } | j | j    q W| S(   N(   R   R   R!   R*   (   R   t   ignoreRegexR$   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getIgnoreRegex   s    	c         C   s   t  | t  r* i d t 6d t 6| } n  | j   } | d k r_ t j d | f  d } n  t j d | |  f  | |  _ d  S(   Nt   yest   noR   s8   Incorrect value %r specified for usedns. Using safe 'no's   Setting usedns = %s for %s(   s   yess   nos   warn(	   t
   isinstancet   boolt   TrueR   t   lowerR   R"   R   t   _Filter__useDns(   R   R#   (    (    s$   /usr/share/fail2ban/server/filter.pyR      s    		c         C   s   |  j  S(   N(   R7   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt	   getUseDns   s    c         C   s.   | |  _  |  j j |  t j d |  d  S(   Ns   Set findtime = %s(   R   R   t
   setMaxTimeR   t   info(   R   R#   (    (    s$   /usr/share/fail2ban/server/filter.pyt   setFindTime   s    	c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getFindTime   s    c         C   s%   |  j  j |  t j d |  d  S(   Ns   Set maxRetry = %s(   R   t   setMaxRetryR   R:   (   R   R#   (    (    s$   /usr/share/fail2ban/server/filter.pyR=      s    c         C   s   |  j  j   S(   N(   R   t   getMaxRetry(   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR>      s    c         C   s   t  d   d  S(   Ns   run() is abstract(   t	   Exception(   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   run   s    c         C   s   | |  _  d  S(   N(   R   (   R   t   command(    (    s$   /usr/share/fail2ban/server/filter.pyt   setIgnoreCommand   s    c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getIgnoreCommand   s    c         C   s   |  j  |  r# t j d |  n  t j   } x6 t |  j j    D] } |  j j t	 | |   qE Wy0 x) t
 r |  j j   } |  j j |  qn WWn' t k
 r |  j j t j    n X| S(   NsR   Requested to manually ban an ignored IP %s. User knows best. Proceeding to ban it.(   t   inIgnoreIPListR   t   warningR   t   timet   xrangeR   R>   t
   addFailureR   R5   t   toBanR   t   putFailTicketR   t   cleanup(   R   t   ipt   unixTimet   it   ticket(    (    s$   /usr/share/fail2ban/server/filter.pyt   addBannedIP   s    	c         C   s)   t  j d | d  |  j j |  d  S(   Ns   Add s    to ignore list(   R   R   R   R!   (   R   RL   (    (    s$   /usr/share/fail2ban/server/filter.pyt   addIgnoreIP  s    c         C   s)   t  j d | d  |  j j |  d  S(   Ns   Remove s    from ignore list(   R   R   R   t   remove(   R   RL   (    (    s$   /usr/share/fail2ban/server/filter.pyt   delIgnoreIP  s    c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getIgnoreIP  s    c         C   sz  x0|  j  D]%} | d k r" q
 n  | j d d  } t |  d k rY | j d d  nH d | d k r t t j d t t j | d    j	    | d <n  t
 | d  | d <y4 t j | d | d  } t j | | d  } Wn3 t k
 rt j |  } | | k r
 t Sq
 n X| | k r
 t Sq
 W|  j rvt j |  j i | d 6 } t j d	 |  t j |  St S(
   Nt    t   /i   t   32t   .s   (?<=b)1+i    RL   s   ignore command: (   R   t   splitt   lent   insertt   ret   searcht   bint   DNSUtilst   addr2bint   groupt   longt   cidrR?   t   dnsToIpR5   R   R
   t
   replaceTagR   R   t
   executeCmdR   (   R   RL   RN   t   st   at   bt   ipsRA   (    (    s$   /usr/share/fail2ban/server/filter.pyRD     s2    	/	c         C   s   y | j  d  } Wn t k
 r, | } n X| j d  } t j d d |  |  j j |  } | r | j   } | | j    | | j	   } n | } | } | |  j
 | | | |  f S(   sF   Split the time portion from log msg and return findFailures on them
		s   utf-8s   
i   s   Working on line %r(   t   decodet   UnicodeDecodeErrort   rstripR   t   logR   t	   matchTimeRa   t   startt   endt   findFailure(   R   t   linet   returnRawHostt   checkAllRegext   lt	   timeMatcht   timeLinet   logLine(    (    s$   /usr/share/fail2ban/server/filter.pyt   processLine<  s    
!c         C   s   x |  j  |  d D] } | d } | d } | d } t j d | | f  | t j   |  j   k  r t j d | t j   |  j   f  Pn  |  j |  r t j d |  q n  t j d |  |  j j t	 | | | g   q Wd S(	   s<   Processes the line for failures and populates failManager
		i   i    i   s&   Processing line with time:%s and ip:%ss#   Ignore line since time %s < %s - %ss	   Ignore %ss   Found %sN(
   Rz   R   R   R   RF   R<   RD   R   RH   R   (   R   Rs   t   elementt	   failregexRL   RM   (    (    s$   /usr/share/fail2ban/server/filter.pyt   processLineAndAddT  s    


		c         C   sA   x: t  |  j  D]) \ } } | j |  | j   r | Sq Wd  S(   N(   t	   enumerateR   R]   t
   hasMatchedt   None(   R   Rs   t   ignoreRegexIndexR/   (    (    s$   /usr/share/fail2ban/server/filter.pyt
   ignoreLineo  s
    c         C   s~  t  j d d | |  t   } |  j |  d  k	 rH t  j d d  | S|  j j |  } xt |  j  D]\ } } | j	 |  | j
   rj t  j d d |  | d  k r t  j d | | f  qvy | j   }	 | r | j | |	 | g  | sOPqOnO t j |	 |  j  }
 |
 rOx$ |
 D] } | j | | | g  q"W| sOPqOn  Wqvt k
 rr} t  j |  qvXqj qj W| S(   Ni   s   Date: %r, message: %ri   s#   Matched ignoreregex and was ignoreds
   Matched %ss   Found a match for %r but no valid date/time found for %r. Please file a detailed issue on https://github.com/fail2ban/fail2ban/issues in order to get support for this format.(   R   Rn   R   R   R   R   t   getUnixTimeR~   R   R]   R   R   t   getHostR!   R_   t   textToIpR7   R	   R"   (   R   Rx   Ry   Rt   Ru   t   failListt   datet   failRegexIndexR+   t   hostt   ipMatchRL   R%   (    (    s$   /usr/share/fail2ban/server/filter.pyRr   }  s8    		c         C   s.   d |  j  j   f d |  j  j   f g } | S(   Ns   Currently faileds   Total failed(   R   t   sizet   getFailTotal(   R   t   ret(    (    s$   /usr/share/fail2ban/server/filter.pyt   status  s    (   R   t
   __module__R   R    R&   R)   R,   R-   R.   R0   R   R8   R;   R<   R=   R>   R@   RB   RC   RP   RQ   RS   RT   RD   R   Rz   R}   R   Rr   R   (    (    (    s$   /usr/share/fail2ban/server/filter.pyR   /   s6   	
							
		
	
				
									"		/t
   FileFilterc           B   se   e  Z d    Z e d  Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d	   Z RS(
   c         K   s    t  j |  | |  g  |  _ d  S(   N(   R   R   t   _FileFilter__logPath(   R   R   t   kwargs(    (    s$   /usr/share/fail2ban/server/filter.pyR     s    c         C   sd   |  j  |  r# t j | d  n= t | |  } |  j j |  t j d |  |  j |  d  S(   Ns    already existss   Added logfile = %s(   t   containsLogPathR   R"   t   FileContainerR   R!   R:   t   _addLogPath(   R   t   patht   tailt	   container(    (    s$   /usr/share/fail2ban/server/filter.pyt
   addLogPath  s    c         C   s   d  S(   N(    (   R   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR     s    c         C   s\   xU |  j  D]J } | j   | k r
 |  j  j |  t j d |  |  j |  d  Sq
 Wd  S(   Ns   Removed logfile = %s(   R   t   getFileNameRR   R   R:   t   _delLogPath(   R   R   Rn   (    (    s$   /usr/share/fail2ban/server/filter.pyt
   delLogPath  s    c         C   s   d  S(   N(    (   R   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR     s    c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt
   getLogPath  s    c         C   s.   x' |  j  D] } | j   | k r
 t Sq
 Wt S(   N(   R   R   R5   R   (   R   R   Rn   (    (    s$   /usr/share/fail2ban/server/filter.pyR     s    c         C   s.   x' |  j  D] } | j   | k r
 | Sq
 Wd  S(   N(   R   R   R   (   R   R   Rn   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getFileContainer  s    c         C   s$  |  j  |  } | d  k r0 t j d |  t Sy | j   } Wn t k
 rt } t j d |  t j |  t St k
 r } t j d |  t j |  t St k
 r } t j d  t j |  t SXx@ | r| j	   } | d k s|  j
   rPn  |  j |  q W| j   t S(   Ns   Unable to get failures in s   Unable to open %ss   Error opening %sst   Internal errror in FileContainer open method - please report as a bug to https://github.com/fail2ban/fail2ban/issuesRU   (   R   R   R   R"   R   t   opent   IOErrort	   exceptiont   OSErrort   readlinet	   _isActiveR}   t   closeR5   (   R   t   filenameR   t   has_contentR%   Rs   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getFailures  s2    	
c         C   sK   t  j |   } g  |  j   D] } | j   ^ q } | j d | f  | S(   Ns	   File list(   R   R   R   R   R!   (   R   R   t   mR   (    (    s$   /usr/share/fail2ban/server/filter.pyR   %  s    %(   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s$   /usr/share/fail2ban/server/filter.pyR     s   	
				
					$R   c           B   sA   e  Z e d   Z d   Z d   Z d   Z d   Z d   Z RS(   c         C   s   | |  _  | |  _ d  |  _ t |  } t j | j    } | j |  _	 zV | j
   } t |  j   |  _ | r | j d d  | j   |  _ n	 d |  _ Wd  | j   Xd  S(   Ni    i   (   t   _FileContainer__filenamet   _FileContainer__tailR   t   _FileContainer__handlerR   t   ost   fstatt   filenot   st_inot   _FileContainer__inoR   t   md5sumt   digestt   _FileContainer__hasht   seekt   tellt   _FileContainer__posR   (   R   R   R   t   handlert   statst	   firstLine(    (    s$   /usr/share/fail2ban/server/filter.pyR   =  s    			c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR   R  s    c         C   s   |  j  S(   N(   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyt   getPosU  s    c         C   s  t  |  j  |  _ |  j j   } t j | t j  } t j | t j | t j B t j	 |  j j    } | j
 sx t S|  j j   } t |  j   } |  j | k s |  j | j k r t j d |  j  | |  _ | j |  _ d |  _ n  |  j j |  j  t S(   Ns   Log rotation detected for %si    (   R   R   R   R   t   fcntlt   F_GETFDt   F_SETFDt
   FD_CLOEXECR   R   t   st_sizeR   R   R   R   R   R   R   R   R   R   R   R5   (   R   t   fdt   flagsR   R   t   myHash(    (    s$   /usr/share/fail2ban/server/filter.pyR   X  s     	!	c         C   s    |  j  d  k r d S|  j  j   S(   NRU   (   R   R   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR   v  s    c         C   s>   |  j  d  k	 r: |  j  j   |  _ |  j  j   d  |  _  n  d  S(   N(   R   R   R   R   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR   {  s    (	   R   R   R   R   R   R   R   R   R   (    (    (    s$   /usr/share/fail2ban/server/filter.pyR   ;  s   				R_   c           B   s   e  Z e j d   Z d   Z e e  Z d   Z e e  Z d   Z e e  Z d   Z	 e e	  Z	 d   Z
 e e
  Z
 d   Z e e  Z d   Z e e  Z RS(   s   ^(?:\d{1,3}\.){3}\d{1,3}$c         C   sM   y t  j |   d SWn1 t  j k
 rH } t j d |  | f  t   SXd S(   s_    Convert a DNS into an IP address using the Python socket module.
			Thanks to Kevin Drapel.
		i   s4   Unable to find a corresponding IP address for %s: %sN(   t   sockett   gethostbyname_exR"   R   R   R   (   t   dnsR%   (    (    s$   /usr/share/fail2ban/server/filter.pyRd     s    	c         C   s$   t  j j |   } | r | Sd Sd S(   sC    Search if an IP address if directly available and return
			it.
		N(   R_   t   IP_CREt   matchR   (   t   textR   (    (    s$   /usr/share/fail2ban/server/filter.pyt   searchIP  s    c         C   sG   |  j  d d  } y t j | d  t SWn t j k
 rB t SXd S(   s$    Return true if str is a valid IP
		RV   i   i    N(   RY   R   t	   inet_atonR5   R"   R   (   t   stringRg   (    (    s$   /usr/share/fail2ban/server/filter.pyt	   isValidIP  s    c         C   s   t    } t j |   } | d k	 rU | j d  } t j |  rU | j |  qU n  | d k r | r t j |   } | j |  | r | d k r t	 j
 d |  |  q n  | S(   s/    Return the IP of DNS found in a given text.
		i    R1   R   s'   Determined IP using DNS Lookup: %s = %sN(   s   yess   warn(   R   R_   R   R   Ra   R   R!   Rd   t   extendR   RE   (   R   R   t   ipListt   plainIPt
   plainIPStrRL   (    (    s$   /usr/share/fail2ban/server/filter.pyR     s    		c         C   s    d } | | ?| @t  j |   @S(   sK    Convert an IP address string with a CIDR mask into a 32-bit
			integer.
		l    (   R_   R`   (   RN   t   nt   MASK(    (    s$   /usr/share/fail2ban/server/filter.pyRc     s    c         C   s   t  j d t j |    d S(   s;    Convert a string IPv4 address into an unsigned integer.
		s   !Li    (   t   structt   unpackR   R   (   R   (    (    s$   /usr/share/fail2ban/server/filter.pyR`     s    c         C   s   t  j t j d |    S(   s<    Convert a numeric IPv4 address into string n.n.n.n form.
		s   !L(   R   t	   inet_ntoaR   t   pack(   t   addr(    (    s$   /usr/share/fail2ban/server/filter.pyt   bin2addr  s    (   R   R   R\   t   compileR   Rd   t   staticmethodR   R   R   Rc   R`   R   (    (    (    s$   /usr/share/fail2ban/server/filter.pyR_     s   	
								()   t
   __author__t   __copyright__t   __license__t   syst   failmanagerR   R   RO   R   t
   jailthreadR   t   datedetectorR   t   mytimeR   R|   R   R   R	   t   actionR
   t   loggingR\   R   R   RF   t   shlext
   subprocesst	   getLoggerR   R   R   t   hashlibt   md5R   t   ImportErrort   newR   R   R   R_   (    (    (    s$   /usr/share/fail2ban/server/filter.pyt   <module>   s2   T	 R