o
    MHd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__#      
zUFWError.__init__c                 C   s
   t | jS r   )reprr   r   r   r   r	   __str__&   r   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| _z,| | | | | | | |d | | | | | | | |	 W d S  tym    w )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   ruler   r   r	   dup_rule[   s&   zUFWRule.dup_rulec                 C   sr  d}| j dkr|d| j  7 }| jdkr|d| j 7 }| jdkr$|d7 }nD|d| j 7 }| jrh|d7 }| jdkrO| jdkrO|d| j 7 }|d7 }|d	| j 7 }n| jdkr\|d| j 7 }n| jdkrh|d	| j 7 }| jd
kry| jdkry|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rd| j }| j	dkr|d| 7 }n'| 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r5d}td}| j
dkr
|d|d| j
 7 }| j
dkr| jdkr|d7 }| jdkr+|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%stcpz --reject-with tcp-resetlimitz -j LIMIT%sz
 -j DROP%sz-m comment --comment ' dapp_z%20,sapp_')r&   r'   r   r    r   r   r   r   r%   r#   r!   r"   recompilesubstrip)r   rule_strlstrr*   	pat_spacer   r   r	   r2   r   sf   












zUFWRule.format_rulec                 C   sj   |  d}|d dks|d dks|d dkr|d | _nd| _d}t|dkr.|d }| | d	S )
zSets action of the ruler=   r   r>   r?   rA   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ntd|s'td|r+t||d|d d	kr;t||d}t|d
krId| _	d}|D ]y}td|rd| _	|d}|D ]}t
|d
k smt
|dkrqt|q_t
|d t
|d
 krt|n4td|rt
|d
k st
|dkrt|ntd|rzt|}W n ty   t|w t||r|dt| 7 }qMt|}qM|}|dkrt|| _dS t|| _dS )z:Sets port and location (destination or source) of the rulezBad port '%s'r   r   r   z^[,:]z[,:]$rD   :   rO   Tr   z	^\d+:\d+$i  r   z^\d+$z
^\w[\w\-]+N)r=   r!   r"   rG   matchr   countrQ   rR   r    intsocketgetservbyname	Exceptionstrr   r   )	r   portlocerr_msgportsrT   pranqr   r   r	   r-      sX   


zUFWRule.set_portc                 C   s0   |t jjdg v r|| _dS td| }t|)zSets protocol of the ruler   zUnsupported protocol '%s'N)r   utilsupported_protocolsr   r=   r   )r   r   r`   r   r   r	   r,      s   
zUFWRule.set_protocolc                 C   s   | j r)| jr| jdks| jdkrd| _| jr%| jdks | jdkr'd| _dS dS dS | jr9| jdks6| jdkr9d| _| jrK| jdksF| jdkrMd| _dS dS 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   rg   )r   r   r   r   r	   set_v6  s   zUFWRule.set_v6c                 C   @   |  }|dkrtj|dstd}t||| _|   dS )zSets source address of ruler   zBad source addressN)rP   r   re   valid_addressr=   r   r   rg   r   addrrT   r`   r   r   r	   r.        zUFWRule.set_srcc                 C   ri   )z Sets destination address of ruler   zBad destination addressN)rP   r   re   rj   r=   r   r   rg   rk   r   r   r	   r/     rm   zUFWRule.set_dstc                 C   s   |dkr|dkrt d}t|dt|v rt d}t|dt|v r,t d}t|t|dks8t|d	kr@t d
}t|tt|dkrPt d}t|tt|dkr`t d}t|tdt|spt d}t||dkry|| _dS || _dS )zSets an interface for ruler   outzBad interface type!z+Bad interface name: reserved character: '!'rU   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   r]   rR   rG   rW   r&   r'   )r   if_typenamer`   r   r   r	   set_interface'  s0   

zUFWRule.set_interfacec                 C   s>   t |dkrtdt |std| }t|t|| _dS )zSets the position of the rulez-1z^[0-9]+z,Insert position '%s' is not a valid positionN)r]   rG   rW   r=   r   rY   r$   )r   numr`   r   r   r	   set_positionW  s   zUFWRule.set_positionc                 C   sB   |  dks|  dks|dkr|  | _dS td| }t|)zSets logtype of the rulelogzlog-allr   zInvalid log type '%s'N)rP   r%   r=   r   )r   r%   r`   r   r   r	   rS   a  s
   zUFWRule.set_logtypec                 C   s.   |dks|dkr|| _ dS td| }t|)zSets direction of the ruler   rn   zUnsupported direction '%s'N)r(   r=   r   )r   r(   r`   r   r   r	   r0   j  s   
zUFWRule.set_directionc                 C   s   t j| jS )zGet decoded comment of the rule)r   re   
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	   r1   v  s   
zUFWRule.set_commentc                 C   s   d}| j r(ztj| j | j\| _ }W n ty"   td}t|w |r(|| _| j	rNztj| j	| j\| _	}W n tyH   td}t|w |rN|| _| j
rc| j
d}tj| d|| _
| jrz| jd}tj| d|| _dS dS )z&Normalize src and dst to standard formFz"Could not normalize source addressz'Could not normalize destination addressrD   N)r   r   re   normalize_addressr   r\   r=   r   r   r   r   rQ   
human_sortjoinr   )r   changedr`   ra   r   r   r	   	normalizez  s@   

zUFWRule.normalizec                 C   s  | r|st  d| |f }| j|jkrt| dS | j|jkr%t| dS | j|jkr1t| dS | j|jkr=t| dS | j|jkrIt| dS | j|jkrUt| dS | j|jkrat| dS | j	|j	krmt| dS | j
|j
kryt| dS | j|jkrt| dS | j|jkrt| dS | j|jkrt| dS | j|jkr| j|jkr| j|jkrt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'rO   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'))xayaxlylxcyc)
ValueErrorr   r   r   r   r   r   r   r!   r"   r&   r'   r(   r)   r#   r%   r*   r=   )xydbg_msgr   r   r	   rW     sr   zUFWRule.matchc                 C   s  dd }| r|st  | |dkrdS d| | j||jf }|jdkr-td| d  dS |j| jkr;t|d	  dS | j|jkrN|jd
krNtd|  dS |jd
krb|| j|jsbtd|  dS |jdkr| jdkrs| 	| j
rsn| j
|j
krd|j
vrtd|  dS | j
|j
krd|j
v 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y   td| d|j   Y dS w |j
|kr
d|j
vr
td| d|j
|f   dS |j
|kr7d|j
v r7| j|jkr7tj||j
| js7td| d||j
f   dS | j|jkrNt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| v sd| v r| |krdS dS | dD ]'}| |kr dS d|v 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 rulerD   rU   TF)rQ   rY   )test_pto_matchr^   low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)rO   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)'r   )r   rW   r   r(   r   r)   r   r   r&   _is_anywherer   r   re   
in_networkget_ip_from_ifIOError)r   r   r   r   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   rl   r   r   r	   r   N  s   zUFWRule._is_anywherec                 C   s   d}| j dks| jdkred| j | j| j| jf }| j dkr)d| j| j| j| jf }| jdkr:d| j | j| j| jf }| jdkrM| jdkrM|d| j 7 }|S | jdkrY|d| j 7 }| jdkre|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   tuplr   r   r	   get_app_tupleT  s&   



zUFWRule.get_app_tuplec                 C   s   | j dkr| jdks| jdkrtd| j  }t|| j tjjv r0|dkr0td| j  }t|| j tjjv rL| j	dksA| j
dkrNtd| j  }t|dS 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   re   ipv4_only_protocolsportless_protocolsr   r   )r   rule_iptyper`   r   r   r	   verifyv  s(   
zUFWRule.verifyN)r   r   r   r   r   Fr   )r   )r   r   r   r   r
   r   r9   r;   r2   r+   r-   r,   rg   rh   r.   r/   rt   rv   rS   r0   ry   r1   r~   rW   r   r   r   r   r   r   r   r	   r   *   s:    
#	C
5

0
	#Cn"r   )r   rG   rZ   ufw.utilr   r   programName	state_dir	share_dir	trans_dir
config_dir
prefix_diriptables_dir	do_checksr\   r   r   r   r   r   r	   <module>   s    	