o
    MHµd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r´d| 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n®t d|¡s't d|¡r+t|ƒ‚| d¡| d¡ d	kr;t|ƒ‚| d¡}t|ƒd
krId| _	d}|D ]y}t d|¡rƒd| _	| d¡}|D ]}t
|ƒd
k smt
|ƒdkrqt|ƒ‚q_t
|d ƒt
|d
 ƒkr‚t|ƒ‚n4t d|¡ršt
|ƒd
k s•t
|ƒdkr™t|ƒ‚nt d|¡r³zt |¡}W n ty²   t|ƒ‚w t|ƒ‚|rÂ|dt|ƒ 7 }qMt|ƒ}qM|}|dkrÔt|ƒ| _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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rÕtdƒ}t|ƒ dS tdƒ| j|j| j|j| j|jdœ }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'rO   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'))Ú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r†d|j
vr†td| ƒ dS | j
|j
kr²d|j
v r²| j|jkr²tj | j
|j
| j¡s²td| d| j
|j
f  ƒ dS n„| jdkrÎ| j|jkrÎt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    	