U
    LdX                     @   sj   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G dd deZG dd dZdS )z!common.py: common classes for ufw    N)debugufwz/lib/ufwz/usr/share/ufwz/etcz/usrz	/usr/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 r   )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                   @   s   e Zd ZdZd9d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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8S );UFWRulez$This class represents firewall rulesany	0.0.0.0/0inF c
           
      C   s   d| _ d| _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
d| _d| _d| _d| _d| _d| _|| _d| _zV| | | | | | | |d | | | | | | | |	 W n tk
r    Y nX d 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   |   S r   )format_ruler   r   r   r	   r   O   s    zUFWRule.__str__c                 C   s>   d|  }t | j}|  |D ]}|d|| j| f 7 }q|S )zPrint rule to stdoutz'%s'z, %s=%s)list__dict__sort)r   reskeyskr   r   r	   _get_attribR   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_rule[   s&    zUFWRule.dup_rulec                 C   s  d}| j dkr|d| j  7 }| jdkr4|d| j 7 }| jdkrH|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 }n2| jdkr|d| j 7 }n| jdkr|d	| j 7 }| jd
kr| jdkr|d| j 7 }| js| jdkr|d| j 7 }| jd
kr:| jdkr:|d| j 7 }| js\| jdkr\|d| j 7 }d}| jdkrvd| j }| j	dkr|d| 7 }nT| j	dkr|d| 7 }| jdkr|d7 }n&| j	dkr|d| 7 }n|d| 7 }| j
dks| jdkrd}td}| j
dkr,|d|d| j
 7 }| j
dkrL| jdkrL|d7 }| jdkrn|d|d| j 7 }|d 7 }|d| 7 }| S )!zFormat rule for later parsingr   z -i %sz -o %sr   z -p allz -p z -m multiportz
 --dports z
 --sports r   ::/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	   r1   r   sd    








zUFWRule.format_rulec                 C   sj   |  d}|d dks2|d dks2|d dkr>|d | _nd| _d}t|dkr\|d }| | d	S )
zSets action of the ruler;   r   r<   r=   r>   Zdenyr      N)lowersplitr"   lenset_logtype)r   r"   tmpr$   r   r   r	   r*      s    $zUFWRule.set_actionr   c           	   	   C   s  t d| }|dkrn|dkr*| jr*n|dkr<| jr<n~td|sTtd|r`t|nZ|d|d d	krt|n6|d}t|d
krd| _	d}|D ]
}td|rd| _	|d}|D ]$}t
|d
k st
|dkrt|qt
|d t
|d
 krt|nztd|rNt
|d
k sDt
|dkrt|nFtd|rzt|}W n tk
r   t|Y nX nt||r|dt| 7 }qt|}q|}|dkrt|| _n
t|| _dS )z:Sets port and location (destination or source) of the rulezBad port '%s'r   r   r   z^[,:]z[,:]$r@   :   rF   Tr   z	^\d+:\d+$i  r   z^\d+$z
^\w[\w\-]+N)r;   r    r!   rB   matchr   countrH   rI   r   intsocketZgetservbyname	Exceptionstrr   r   )	r   portZlocerr_msgportsrK   pZranqr   r   r	   r,      sP    







zUFWRule.set_portc                 C   s2   |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   r;   r   )r   r   rU   r   r   r	   r+      s    zUFWRule.set_protocolc                 C   s   | j rH| jr&| jdks | jdkr&d| _| jr| jdks@| jdkrd| _n@| jrh| jdksb| jdkrhd| _| jr| jdks| jdkrd| _dS )zAdjusts src and dst based on v6r   r   r:   N)r   r   r   r   r   r   r	   _fix_anywhere   s    zUFWRule._fix_anywherec                 C   s   || _ |   dS )zXSets whether this is ipv6 rule, and adjusts src and dst
           accordingly.
        N)r   rZ   )r   r   r   r   r	   set_v6  s    zUFWRule.set_v6c                 C   s@   |  }|dkr.tj|ds.td}t||| _|   dS )zSets source address of ruler   zBad source addressN)rG   r   rY   valid_addressr;   r   r   rZ   r   addrrK   rU   r   r   r	   r-     s    zUFWRule.set_srcc                 C   s@   |  }|dkr.tj|ds.td}t||| _|   dS )z Sets destination address of ruler   zBad destination addressN)rG   r   rY   r\   r;   r   r   rZ   r]   r   r   r	   r.     s    zUFWRule.set_dstc                 C   s   |dkr |dkr t d}t|dt|kr<t d}t|dt|krXt d}t|t|dkspt|d	krt d
}t|tt|dkrt d}t|tt|dkrt d}t|tdt|st d}t||dkr|| _n|| _dS )zSets an interface for ruler   outzBad interface type!z+Bad interface name: reserved character: '!'rL   z/Bad interface name: can't use interface aliases.z..z)Bad interface name: can't use '.' or '..'r   z+Bad interface name: interface name is empty   z+Bad interface name: interface name too longz^[a-zA-Z0-9_\-\.\+,=%@]+$zBad interface nameN)r;   r   rS   rI   rB   rN   r%   r&   )r   Zif_typenamerU   r   r   r	   set_interface'  s0    zUFWRule.set_interfacec                 C   s>   t |dkr0tdt |s0td| }t|t|| _dS )zSets the position of the rulez-1z^[0-9]+z,Insert position '%s' is not a valid positionN)rS   rB   rN   r;   r   rP   r#   )r   ZnumrU   r   r   r	   set_positionW  s    zUFWRule.set_positionc                 C   sD   |  dks |  dks |dkr,|  | _ntd| }t|dS )zSets logtype of the rulelogzlog-allr   zInvalid log type '%s'N)rG   r$   r;   r   )r   r$   rU   r   r   r	   rJ   a  s    zUFWRule.set_logtypec                 C   s0   |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'   r;   r   )r   r'   rU   r   r   r	   r/   j  s    zUFWRule.set_directionc                 C   s   t j| jS )zGet decoded comment of the rule)r   rY   Z
hex_decoder)   r   r   r   r	   get_commentr  s    zUFWRule.get_commentc                 C   s
   || _ dS )zSets comment of the ruleN)r)   )r   r)   r   r   r	   r0   v  s    zUFWRule.set_commentc                 C   s   d}| j rVztj| j | j\| _ }W n$ tk
rJ   td}t|Y nX |rV|| _| j	rztj| j	| j\| _	}W n$ tk
r   td}t|Y nX |r|| _| j
r| j
d}tj| d|| _
| jr| jd}tj| d|| _dS )z&Normalize src and dst to standard formFz"Could not normalize source addressz'Could not normalize destination addressr@   N)r   r   rY   Znormalize_addressr   rR   r;   r   r   r   r   rH   Z
human_sortjoinr   )r   ZchangedrU   rV   r   r   r	   	normalizez  s:    

zUFWRule.normalizec                 C   s  | r|st  d| |f }| j|jkr2t| dS | j|jkrJt| dS | j|jkrbt| dS | j|jkrzt| dS | j|jkrt| dS | j|jkrt| dS | j|jkrt| dS | j	|j	krt| dS | j
|j
krt| 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~| j|jkr~| j|jkr~td}t| dS | j|jkr| j|jkr| j|jkrtd}t| dS td| j|j| j|j| j|jd }t| d	S )
zCheck 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'rF   zFound exact matchr   z$Found exact match, excepting commentzZFound 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)   r;   )xydbg_msgr   r   r	   rN     sz    

  zUFWRule.matchc                 C   s  dd }| r|st  | |dkr(dS d| | j||jf }|jdkrZtd| d  dS |j| jkrvt|d	  dS | j|jkr|jd
krtd|  dS |jd
kr|| j|jstd|  dS |jdkrv| jdkr| 	| j
rn| j
|j
krd|j
krtd|  dS | j
|j
krd|j
kr| j|jkrtj| j
|j
| jstd| d| j
|j
f   dS n| jdkr| j|jkrtd| d| j|jf   dS ztj|j| j}W n. tk
r   td| d|j   Y dS X |j
|kr,d|j
kr,td| d|j
|f   dS |j
|krd|j
kr| j|jkrtj||j
| jstd| d||j
f   dS | j|jkrtd| d| j
|j
f   dS t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S dS | dD ]N}| |kr< dS d|kr*| d\}}t| t|kr*t| t|kr* dS q*dS )z:Returns True if p is an exact match or within a multi ruler@   rL   TF)rH   rP   )Ztest_pZto_matchrT   ZlowZhighr   r   r	   _match_ports  s     z-UFWRule.fuzzy_dst_match.<locals>._match_portsr   z(No fuzzy match '%s (v6=%s)' '%s (v6=%s)'r   z(direction) z (not incoming)rF   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)'rk   )rl   rN   r   r'   r   r(   r   r   r%   _is_anywherer   r   rY   Z
in_networkZget_ip_from_ifIOError)rm   rn   rp   ro   Zif_ipr   r   r	   fuzzy_dst_match  s|    
(





&zUFWRule.fuzzy_dst_matchc                 C   s   |dks|dkrdS dS )zCheck if address is anywherer:   r   TFr   )r   r^   r   r   r	   rr   N  s    zUFWRule._is_anywherec                 C   s   d}| j dks| jdkrd| j | j| j| jf }| j dkrRd| j| j| j| jf }| jdkrtd| j | j| j| jf }| jdkr| jdkr|d| j 7 }n0| 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 direction_iface|direction
           or
             dport dst sapp src direction_iface|direction
           or
             dapp dst sport src direction_iface|direction

           where direction_iface is of form 'in_eth0', 'out_eth0' or
           'in_eth0 out_eth0' (ie, both interfaces used). If no interfaces are
           specified, then tuple ends with the direction instead.
        r   z%s %s %s %sz %sz in_%sz out_%s)	r    r!   r   r   r   r   r%   r&   r'   )r   Ztuplr   r   r	   get_app_tupleT  s$    



zUFWRule.get_app_tuplec                 C   s   | j dkr4| jdks| jdkr4t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rt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    r;   r   r   rY   Zipv4_only_protocolsZportless_protocolsr   r   )r   Zrule_iptyperU   r   r   r	   verifyv  s,    
zUFWRule.verifyN)r   r   r   r   r   Fr   )r   )r   r   r   r   r
   r   r8   r9   r1   r*   r,   r+   rZ   r[   r-   r.   rd   re   rJ   r/   rg   r0   ri   rN   rt   rr   ru   rv   r   r   r   r	   r   *   s>            
#	C
5

0
	#Cn"r   )r   rB   rQ   Zufw.utilr   r   ZprogramNameZ	state_dirZ	share_dirZ	trans_dirZ
config_dirZ
prefix_dirZiptables_dirZ	do_checksrR   r   r   r   r   r   r	   <module>   s   	