
,yW^R  ã               @   s—   d  Z  d d l Z d d l Z d d l Z d d l m Z d Z d Z d Z e Z	 d Z
 d Z d	 Z d
 Z Gd d „  d e ƒ Z Gd d „  d ƒ Z d S)z!common.py: common classes for ufwé    N)ÚdebugÚufwz/lib/ufwz/usr/share/ufwz/etcz/usrz/sbinTc               @   s.   e  Z d  Z d Z d d „  Z d d „  Z d S)ÚUFWErrorz$This class represents ufw exceptionsc             C   s   | |  _  d  S)N)Úvalue)Úselfr   © r   ú,/usr/lib/python3/dist-packages/ufw/common.pyÚ__init__"   s    zUFWError.__init__c             C   s   t  |  j ƒ S)N)Úreprr   )r   r   r   r   Ú__str__%   s    zUFWError.__str__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r   r   r   r   r   r       s   r   c            	   @   sN  e  Z d  Z d Z d d d d d d d d d „ Z d	 d
 „  Z d d „  Z d d „  Z d d „  Z d d „  Z	 d d d „ Z
 d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d  d! „  Z d" d# „  Z d$ d% „  Z d& d' „  Z d( d) „  Z d* d+ „  Z d, d- „  Z d. d/ „  Z d0 d1 „  Z d2 d3 „  Z d4 d5 „  Z d6 d7 „  Z d8 S)9ÚUFWRulez$This class represents firewall rulesÚanyz	0.0.0.0/0ÚinFÚ c
       
      C   s6  d |  _  d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ d |  _	 d |  _
 d |  _ d |  _ d |  _ d |  _ d |  _ d |  _ | |  _ d |  _ yo |  j | ƒ |  j | ƒ |  j | ƒ |  j | d ƒ |  j | ƒ |  j | ƒ |  j | ƒ |  j |	 ƒ Wn t k
 r1‚  Yn Xd  S)NFr   r   Úsrc)ÚremoveÚupdatedÚv6Údstr   ÚdportÚsportÚprotocolÚmultiÚdappÚsappÚactionÚpositionÚlogtypeÚinterface_inÚinterface_outÚ	directionÚforwardÚcommentÚ
set_actionÚset_protocolÚset_portÚset_srcÚset_dstÚset_directionÚset_commentr   )
r   r   r   r   r   r   r   r$   r%   r&   r   r   r   r	   +   s<    																			zUFWRule.__init__c             C   s
   |  j  ƒ  S)N)Úformat_rule)r   r   r   r   r   N   s    zUFWRule.__str__c             C   sS   d |  } t  |  j ƒ } | j ƒ  x) | D]! } | d | |  j | f 7} q* W| S)zPrint rule to stdoutz'%s'z, %s=%s)ÚlistÚ__dict__Úsort)r   ÚresÚkeysÚkr   r   r   Ú_get_attribQ   s    

zUFWRule._get_attribc             C   så   t  |  j |  j ƒ } |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j	 | _	 |  j
 | _
 |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ |  j | _ | S)zReturn a duplicate of a rule)r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   )r   Zruler   r   r   Údup_ruleZ   s&    zUFWRule.dup_rulec             C   sF  d } |  j  d k r& | d |  j  7} |  j d k rF | d |  j 7} |  j d k rb | d 7} n´ | d |  j 7} |  j r| d 7} |  j d k rÓ |  j d k rÓ | d |  j 7} | d 7} | d	 |  j 7} nC |  j d k rö | d |  j 7} n  |  j d k r| d	 |  j 7} |  j d
 k rE|  j d k rE| d |  j 7} |  j ro|  j d k ro| d |  j 7} |  j d
 k rž|  j d k rž| d |  j 7} |  j rÈ|  j d k rÈ| d |  j 7} d } |  j d k rêd |  j } |  j	 d k r
| d | 7} ng |  j	 d k rC| d | 7} |  j d k rq| d 7} n. |  j	 d k rc| d | 7} n | d | 7} |  j
 d k s|  j d k r<d } t j d ƒ } |  j
 d k rÐ| d | j d |  j
 ƒ 7} |  j
 d k rø|  j d k rø| d 7} |  j d k r$| d | j d |  j ƒ 7} | d  7} | d | 7} | j ƒ  S)!zFormat rule for later parsingr   z -i %sz -o %sr   z -p allz -p z -m multiportz
 --dports z
 --sports z	0.0.0.0/0z::/0z -d z	 --dport z -s z	 --sport Ú_Úallowz -j ACCEPT%sÚrejectz -j REJECT%sZtcpz --reject-with tcp-resetÚlimitz -j LIMIT%sz
 -j DROP%sz-m comment --comment 'ú Zdapp_z%20ú,Zsapp_ú')r"   r#   r   r   r   r   r   r   r!   r   r   r   ÚreÚcompileÚsubÚstrip)r   Zrule_strZlstrr&   Z	pat_spacer   r   r   r.   q   sd    	



zUFWRule.format_rulec             C   s‘   | j  ƒ  j d ƒ } | d d k sE | d d k sE | d d k rU | d |  _ n	 d |  _ d } t | ƒ d k r€ | d } |  j | ƒ d	 S)
zSets action of the ruler7   r   r8   r9   r:   Zdenyr   é   N)ÚlowerÚsplitr   ÚlenÚset_logtype)r   r   Útmpr!   r   r   r   r'   ´   s    0	
zUFWRule.set_actionr   c       	      C   sˆ  t  d ƒ | } | d k r n8| d k r7 |  j r7 n | d k rO |  j rO nt j d | ƒ ss t j d | ƒ r‚ t | ƒ ‚ nÕ| j d ƒ | j d ƒ d	 k r³ t | ƒ ‚ n¤| j d ƒ } t | ƒ d
 k rÝ d |  _	 d } xk| D]c} t j d | ƒ rŠd |  _	 | j d ƒ } x> | D]6 } t
 | ƒ d
 k  sKt
 | ƒ d k r!t | ƒ ‚ q!Wt
 | d ƒ t
 | d
 ƒ k r$t | ƒ ‚ nš t j d | ƒ rÏt
 | ƒ d
 k  sÀt
 | ƒ d k r$t | ƒ ‚ nU t j d | ƒ ry t j | ƒ } Wq$t k
 rt | ƒ ‚ Yq$Xn t | ƒ ‚ | rA| d t | ƒ 7} qê t | ƒ } qê W| } | d k rut | ƒ |  _ n t | ƒ |  _ d S)z:Sets port and location (destination or source) of the rulezBad port '%s'r   r   r   z^[,:]z[,:]$r<   ú:é   rB   Tr   z	^\d+:\d+$iÿÿ  r   z^\d+$z
^\w[\w\-]+N)r7   r   r   r>   Úmatchr   ÚcountrD   rE   r   ÚintÚsocketZgetservbynameÚ	ExceptionÚstrr   r   )	r   ÚportÚlocÚerr_msgÚportsrG   ÚpZranÚqr   r   r   r)   Á   sP    $"		$ $zUFWRule.set_portc             C   sE   | t  j j d g k r% | |  _ n t d ƒ | } t | ƒ ‚ d S)zSets protocol of the ruler   zUnsupported protocol '%s'N)r   ÚutilZsupported_protocolsr   r7   r   )r   r   rR   r   r   r   r(   ö   s    zUFWRule.set_protocolc             C   sÐ   |  j  rl |  j r9 |  j d k s0 |  j d k r9 d |  _ |  j rÌ |  j d k s` |  j d k rÌ d |  _ n` |  j rœ |  j d k s“ |  j d k rœ d |  _ |  j rÌ |  j d k sÃ |  j d k rÌ d |  _ d S)zAdjusts src and dst based on v6r   z	0.0.0.0/0z::/0N)r   r   r   )r   r   r   r   Ú_fix_anywhereþ   s    	'	''	'zUFWRule._fix_anywherec             C   s   | |  _  |  j ƒ  d S)zXSets whether this is ipv6 rule, and adjusts src and dst
           accordingly.
        N)r   rW   )r   r   r   r   r   Úset_v6  s    	zUFWRule.set_v6c             C   s]   | j  ƒ  } | d k rF t j j | d ƒ rF t d ƒ } t | ƒ ‚ | |  _ |  j ƒ  d S)zSets source address of ruler   zBad source addressN)rC   r   rV   Úvalid_addressr7   r   r   rW   )r   ÚaddrrG   rR   r   r   r   r*     s    "	zUFWRule.set_srcc             C   s]   | j  ƒ  } | d k rF t j j | d ƒ rF t d ƒ } t | ƒ ‚ | |  _ |  j ƒ  d S)z Sets destination address of ruler   zBad destination addressN)rC   r   rV   rY   r7   r   r   rW   )r   rZ   rG   rR   r   r   r   r+     s    "	zUFWRule.set_dstc             C   sÙ   | d k r0 | d k r0 t  d ƒ } t | ƒ ‚ d t | ƒ k rZ t  d ƒ } t | ƒ ‚ t j d t | ƒ ƒ sŠ t  d ƒ } t | ƒ ‚ d t | ƒ k r´ t  d	 ƒ } t | ƒ ‚ | d k rÌ | |  _ n	 | |  _ d
 S)zSets an interface for ruler   ÚoutzBad interface typeú!z+Bad interface name: reserved character: '!'z!^[a-zA-Z][a-zA-Z0-9:]*[a-zA-Z0-9]zBad interface namerH   z/Bad interface name: can't use interface aliasesN)r7   r   rO   r>   rJ   r"   r#   )r   Zif_typeÚnamerR   r   r   r   Úset_interface&  s    zUFWRule.set_interfacec             C   sG   t  j d t | ƒ ƒ s4 t d ƒ | } t | ƒ ‚ t | ƒ |  _ d S)zSets the position of the rulez^[0-9]+z,Insert position '%s' is not a valid positionN)r>   rJ   rO   r7   r   rL   r    )r   ZnumrR   r   r   r   Úset_position=  s    zUFWRule.set_positionc             C   sb   | j  ƒ  d k s0 | j  ƒ  d k s0 | d k rB | j  ƒ  |  _ n t d ƒ | } t | ƒ ‚ d S)zSets logtype of the ruleÚlogzlog-allr   zInvalid log type '%s'N)rC   r!   r7   r   )r   r!   rR   r   r   r   rF   D  s
    $zUFWRule.set_logtypec             C   sD   | d k s | d k r$ | |  _  n t d ƒ | } t | ƒ ‚ d S)zSets direction of the ruler   r[   zUnsupported direction '%s'N)r$   r7   r   )r   r$   rR   r   r   r   r,   M  s    zUFWRule.set_directionc             C   s   t  j j |  j ƒ S)zGet decoded comment of the rule)r   rV   Z
hex_decoder&   )r   r   r   r   Úget_commentU  s    zUFWRule.get_commentc             C   s   | |  _  d S)zSets comment of the ruleN)r&   )r   r&   r   r   r   r-   Y  s    zUFWRule.set_commentc             C   s^  d } |  j  rs y( t j j |  j  |  j ƒ \ |  _  } Wn* t k
 rc t d ƒ } t | ƒ ‚ Yn X| rs | |  _ |  j	 rà y( t j j |  j	 |  j ƒ \ |  _	 } Wn* t k
 rÐ t d ƒ } t | ƒ ‚ Yn X| rà | |  _ |  j
 r|  j
 j d ƒ } t j j | ƒ d j | ƒ |  _
 |  j rZ|  j j d ƒ } t j j | ƒ d j | ƒ |  _ d S)z&Normalize src and dst to standard formFz"Could not normalize source addressz'Could not normalize destination addressr<   N)r   r   rV   Znormalize_addressr   rN   r7   r   r   r   r   rD   Z
human_sortÚjoinr   )r   ZchangedrR   rS   r   r   r   Ú	normalize]  s6    						zUFWRule.normalizec             C   s›  |  s | r t  ƒ  ‚ d |  | f } |  j | j k rG t | ƒ d S|  j | j k rg t | ƒ d S|  j | j k r‡ t | ƒ d S|  j | j k r§ t | ƒ d S|  j | j k rÇ t | ƒ d S|  j | j k rç t | ƒ d S|  j | j k rt | ƒ d S|  j	 | j	 k r't | ƒ d S|  j
 | j
 k rGt | ƒ d S|  j | j k rgt | ƒ d S|  j | j k r‡t | ƒ d S|  j | j k r§t | ƒ d S|  j | j k r÷|  j | j k r÷|  j | j k r÷t d ƒ } t | ƒ d S|  j | j k rG|  j | j k rG|  j | j k rGt d ƒ } t | ƒ d St d ƒ d |  j d	 | j d
 |  j d | j d |  j d | j i } t | ƒ d S)zºCheck if rules match
        Return codes:
          0  match
          1  no match
         -1  match all but action, log-type and/or comment
         -2  match all but comment
        zNo match '%s' '%s'rB   zFound exact matchr   z$Found exact match, excepting commenté   zZFound non-action/non-logtype/comment match (%(xa)s/%(ya)s/'%(xc)s' %(xl)s/%(yl)s/'%(yc)s')ZxaZyaZxlZylZxcZycéþÿÿÿéÿÿÿÿ)Ú
ValueErrorr   r   r   r   r   r   r   r   r   r"   r#   r$   r%   r   r!   r&   r7   )ÚxÚyÚdbg_msgr   r   r   rJ   €  sn    	











$
$
	
zUFWRule.matchc             C   s–  d d „  } |  s | r# t  ƒ  ‚ |  j | ƒ d k r< d Sd |  |  j | | j f } | j d k r} t d | d ƒ d S| j |  j k r¡ t | d	 ƒ d S|  j | j k rÔ | j d
 k rÔ t d | ƒ d S| j d
 k r| |  j | j ƒ rt d | ƒ d S| j d k rï|  j d k r>|  j	 |  j
 ƒ r>q:|  j
 | j
 k rqd | j
 k rqt d | ƒ d S|  j
 | j
 k r:d | j
 k r:|  j | j k r:t j j |  j
 | j
 |  j ƒ r:t d | d |  j
 | j
 f ƒ d SnK|  j d k r6|  j | j k r6t d | d |  j | j f ƒ d Sy t j j | j |  j ƒ } Wn/ t k
 r†t d | d | j ƒ d SYn X| j
 | k rÈd | j
 k rÈt d | d | j
 | f ƒ d S| j
 | k r:d | j
 k r:|  j | j k r:t j j | | j
 |  j ƒ r:t d | d | | j
 f ƒ d S|  j | j k rrt d | d |  j
 | j
 f ƒ d St d |  |  j | | j f ƒ d S)a®  This will match if x is more specific than y. Eg, for protocol if x
	   is tcp and y is all or for address if y is a network and x is a
           subset of y (where x is either an address or network). Returns:

            0  match
            1  no match
           -1  fuzzy match

           This is a fuzzy destination match, so source ports or addresses
           are not considered, and (currently) only incoming.
        c             S   s¯   d |  k s d |  k r, |  | k r( d Sd Sx| | j  d ƒ D]k } |  | k rR d Sd | k r< | j  d ƒ \ } } t |  ƒ t | ƒ k r< t |  ƒ t | ƒ k r< d Sq< Wd S)z:Returns True if p is an exact match or within a multi ruler<   rH   TF)rD   rL   )Ztest_pZto_matchrP   ZlowZhighr   r   r   Ú_match_portsÏ  s    0z-UFWRule.fuzzy_dst_match.<locals>._match_portsr   z(No fuzzy match '%s (v6=%s)' '%s (v6=%s)'r   z(direction) z (not incoming)rB   z (forward does not match)r   z(protocol) z(dport) r   ú/z(dst) z ('%s' not in network '%s')z(interface) z (%s != %s)z %s does not existz(v6) z'(fuzzy match) '%s (v6=%s)' '%s (v6=%s)'rf   )rg   rJ   r   r$   r   r%   r   r   r"   Ú_is_anywherer   r   rV   Z
in_networkZget_ip_from_ifÚIOError)rh   ri   rk   rj   Zif_ipr   r   r   Úfuzzy_dst_matchÃ  sl    	!%!!3"!	0
" zUFWRule.fuzzy_dst_matchc             C   s    | d k s | d k r d Sd S)zCheck if address is anywherez::/0z	0.0.0.0/0TFr   )r   rZ   r   r   r   rm   1  s    zUFWRule._is_anywherec             C   sì   d } |  j  d k s$ |  j d k rè d |  j  |  j |  j |  j f } |  j  d k rw d |  j |  j |  j |  j f } |  j d k r¨ d |  j  |  j |  j |  j f } |  j d k rÈ | d |  j 7} |  j d k rè | d |  j 7} | S)a$  Returns a tuple to identify an app rule. Tuple is:
             dapp dst sapp src
           or
             dport dst sapp src
           or
             dapp dst sport src

           All of these might have in_eth0 out_eth0 (or similar) if an
           interface is also defined.
        r   z%s %s %s %sz in_%sz out_%s)r   r   r   r   r   r   r"   r#   )r   Ztuplr   r   r   Úget_app_tuple7  s    "zUFWRule.get_app_tuplec             C   sâ   |  j  d k rL |  j d k s- |  j d k rL t d ƒ |  j  } t | ƒ ‚ |  j  t j j k rŒ | d k rŒ t d ƒ |  j  } t | ƒ ‚ |  j  t j j k rÞ |  j	 d k s¿ |  j
 d k rÞ t d ƒ |  j  } t | ƒ ‚ d S)zVerify ruler   r   z3Improper rule syntax ('%s' specified with app rule)r   z'Invalid IPv6 address with protocol '%s'zInvalid port with protocol '%s'N)r   r   r   r7   r   r   rV   Zipv4_only_protocolsZportless_protocolsr   r   )r   Zrule_iptyperR   r   r   r   ÚverifyT  s    	
	
	
zUFWRule.verifyN)r   r   r   r   r	   r   r5   r6   r.   r'   r)   r(   rW   rX   r*   r+   r^   r_   rF   r,   ra   r-   rc   rJ   ro   rm   rp   rq   r   r   r   r   r   )   s6   !	C5

	#Cnr   )r   r>   rM   Zufw.utilr   r   ZprogramNameZ	state_dirZ	share_dirZ	trans_dirZ
config_dirZ
prefix_dirZiptables_dirZ	do_checksrN   r   r   r   r   r   r   Ú<module>   s   	