o
    �Fajæ  ã                   @   s„   d 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mZm	Z	 ddl
mZmZmZmZmZmZ ddlZG dd„ dejjƒZdS )z-backend_iptables.py: iptables backend for ufwé    N)ÚUFWErrorÚUFWRule)ÚwarnÚdebugÚmsgÚcmdÚcmd_pipeÚ	_findpathc                   @   s²   e Zd ZdZd+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d„Zd.dd „Zd!d"„ Zd-d#d$„Zd%d&„ Zd'd(„ Zd)d*„ ZdS )/ÚUFWBackendIptableszInstance class for UFWBackendNc                 C   s‚  dt jj d | _|| _|| _i }tt jj|ƒ}tj	 
|d¡|d< tj	 
|d¡|d< tj	 
|d¡|d< tj	 
|d	¡|d
< tj	 
|d¡|d< tj	 
|d¡|d< tj	 
tt jj|ƒd¡|d< t jjj| d||||d� g g g g dœ| _dD ]C}d}|dkr‰|  ¡ r„||7 }n|dkr‰qsdD ]}dD ]}	d|||	f }
| j|  |
¡ q�q‹| jd  |d ¡ | jd  |d ¡ qsg d¢| _d| _dS ) z!UFWBackendIptables initializationz# z
_comment #zufw/user.rulesÚruleszufw/before.rulesÚbefore_ruleszufw/after.rulesÚafter_ruleszufw/user6.rulesÚrules6zufw/before6.rulesÚbefore6_ruleszufw/after6.rulesÚafter6_ruleszufw-initÚinitÚiptables)ÚrootdirÚdatadir)ÚbeforeÚuserÚafterÚmisc)Ú4Ú6Úufwr   )r   r   r   ©ÚinputÚoutputÚforwardz%s-%s-logging-%sr   z-logging-denyz-logging-allow)ú-mÚlimitú--limitz3/minuteú-jÚLOGú--log-prefixz[UFW LIMIT BLOCK]N)r   ÚcommonÚprogramNameÚcomment_strr   r   r	   Ú
config_dirÚosÚpathÚjoinÚ	state_dirÚbackendÚ
UFWBackendÚ__init__ÚchainsÚuse_ipv6ÚappendÚufw_user_limit_logÚufw_user_limit_log_text)ÚselfÚdryrunr   r   Úfilesr)   ÚverÚchain_prefixÚlocÚtargetÚchain© r>   ú6/usr/lib/python3/dist-packages/ufw/backend_iptables.pyr0       sD   ÿÿ
þ

zUFWBackendIptables.__init__c                 C   sb   t dƒ}| jd dkr|d7 }|S | jd dkr|d7 }|S | jd dkr+|d7 }|S |d	7 }|S )
zGet current policyzNew profiles:Údefault_application_policyÚacceptz allowÚdropz denyÚrejectz rejectz skip)Ú_Údefaults)r6   Úrstrr>   r>   r?   Úget_default_application_policyP   s   ùûþz1UFWBackendIptables.get_default_application_policyc              	   C   s  | j sõ|dkr|dkr|dkrtdƒ| }t|ƒ‚|dkr/|dkr/|dkr/tdƒ| }t|ƒ‚d	}|dkr8d
}n|dkr>d}d}d}|dkrbz|  | jd d| d¡ W n ty\   ‚ w d}d}n;|dkr‚z|  | jd d| d¡ W n ty|   ‚ w d}d}nz|  | jd d| d¡ W n ty˜   ‚ w d}d}t d| ¡}| jd | jd fD ]F}ztj	 
|¡}	W n tyÀ   ‚ w |	d }
|	d D ]}| |¡rÜtj	 |
| ||¡¡ qÉtj	 |
|¡ qÉztj	 |	¡ W q® tyô   ‚ w tdƒ||dœ }|tdƒ7 }|S )zSets default policy of firewallÚallowÚdenyrC   zUnsupported policy '%s'ÚincomingÚoutgoingÚroutedz%Unsupported policy for direction '%s'ÚINPUTÚOUTPUTÚFORWARDÚ rE   zDEFAULT_%s_POLICYz"ACCEPT"z	UFW BLOCKz	UFW ALLOWz"REJECT"z"DROP"r   r   ÚtmpÚorigz5Default %(direction)s policy changed to '%(policy)s'
)Ú	directionÚpolicyz*(be sure to update your rules accordingly))r7   rD   r   Úset_defaultr8   Ú	ExceptionÚreÚcompiler   ÚutilÚ
open_filesÚsearchÚwrite_to_fileÚsubÚclose_files)r6   rT   rS   Úerr_msgr=   Úold_log_strÚnew_log_strÚpatÚfÚfnsÚfdÚlinerF   r>   r>   r?   Úset_default_policy^   sŽ   ÿþÿþÿþÿÿ
ÿÿz%UFWBackendIptables.set_default_policyc                 C   s®  | j rdtdƒ }|dtdƒ 7 }|S |  ¡  g d¢}g }g }|dkr1| d¡ g d¢}g d¢}nü|d	kr{d
D ]}| d| ¡ | d| ¡ q7dD ]}| d| ¡ | d| ¡ qJdD ]}| d| ¡ | d| ¡ q]dD ]	}| d| ¡ qpn²|dkr“dD ]}| d| ¡ | d| ¡ q�nš|dkrÍdD ]}| d| ¡ | d| ¡ q™| jd d r»| d¡ | d¡ | jd d rÌ| d¡ | d¡ n`|d krådD ]}| d!| ¡ | d"| ¡ qÓnH|d#k�r-dD ],}| d$| ¡ | d%| ¡ | d&| ¡ | d'| ¡ | d(| ¡ | d)| ¡ qì| d*¡ | d+¡ | d,¡ | d-¡ d.| }|D ]H}d/|v �rW| d/¡\}	}|d0|	 7 }t| jg| |d|	g ƒ\}
}nt| jg| |g ƒ\}
}||7 }|dk�rq|d17 }|
d2k�rzt|ƒ‚�q3|dk�s†|  	¡ �rÕ|d37 }|D ]H}d/|v �r°| d/¡\}	}|d0|	 7 }t| jg| |d|	g ƒ\}
}nt| j
g| |g ƒ\}
}||7 }|dk�rÊ|d17 }|
d2k�rÓt|ƒ‚�qŒ|S )4z'Show current running status of firewallú> zChecking raw iptables
zChecking raw ip6tables
)ú-nz-vz-xú-LÚrawz-t)ÚfilterÚnatÚmanglerk   )rl   rn   rk   Úbuiltins)rM   rO   rN   z	filter:%s)Ú
PREROUTINGrM   rO   rN   ÚPOSTROUTINGz	mangle:%s)rp   rN   zraw:%s)rp   rq   rN   znat:%sr   )r   r   r   zufw-before-%szufw6-before-%sr   úufw-user-%súufw6-user-%sr!   r   zufw-user-limit-acceptúufw-user-limitr   zufw6-user-limit-acceptúufw6-user-limitr   zufw-after-%szufw6-after-%sÚloggingzufw-before-logging-%szufw6-before-logging-%szufw-user-logging-%szufw6-user-logging-%szufw-after-logging-%szufw6-after-logging-%szufw-logging-allowzufw-logging-denyzufw6-logging-allowzufw6-logging-denyzIPV4 (%s):
ú:z(%s) Ú
r   z

IPV6:
)r7   rD   Úinitcapsr3   ÚcapsÚsplitr   r   r   r2   Ú	ip6tables)r6   Ú
rules_typeÚoutÚargsÚitemsÚitems6ÚcÚbÚiÚtÚrcrQ   r>   r>   r?   Úget_running_raw©   s¬   

ÿþ



€þ





 

ÿ
 

ÿz"UFWBackendIptables.get_running_rawFc           $      C   sˆ  d}| j rdtdƒ }|  ¡ r|dtdƒ 7 }|S tdƒ}dD ]@}t| jdd| d	gƒ\}}|d
kr8tdƒ  S |dkrDt|d|  ƒ‚|  ¡ r_t| jdd| d	gƒ\}}|dkr_t|d ƒ‚qd}d}	d}
| j| j }d
}i }|D �]•}d}i }d}d}|sž|j	dks‰|j
dkržd}| ¡ }||v rštd| ƒ qrd||< dD �]¾}d||< d}d}|dkrÌ|j}|sÈ|j	dkrÈ|j	}|jrÇ|dkrÇ|d7 }n |j}n|j}|så|j
dkrå|j
}|jrä|dkrä|d7 }n|j}|dkrô|dkrô|||< |dk�r„|| dk�r|||< n
||  d| 7  < |�r#|jdk�r#||  d|j 7  < |�r„|dk�rU|j	dk�rU||  d|j	 7  < |j�rM|dk�rM||  d7  < ||  d7  < |dk�r„|j
dk�r„||  d|j
 7  < |j�r||dk�r|||  d7  < ||  d7  < |dk�rã|dk�s“|dk�rÇd||< |�r¹|jdk�r¹|j|jk�r¹|j|jk�r¹||  d|j 7  < |dk�rÆ||  d7  < n;|�râ|jdk�râ|j|jk�râ||  d|j 7  < n|j�r|jdk�r|jdk�rd|| v�r||  d7  < |j�r3|dk�r|jdk�r||  d|j 7  < |dk�r2|jdk�r2||  d|j 7  < q |dk�rI|jdk�rI||  d|j 7  < |dk�r_|jdk�r_||  d|j 7  < q g }d}|j�sp|j ¡ d k�r™|j�r|| |j ¡ ¡ |�r‹|jd k�r‹| |j¡ t|ƒdk�r™d!d" |¡ }|�r¢|d#| 7 }|j ¡ }|j�r­d$}|jd%k�r¿|j�s¿|�s¿|�s¿d}d}|jdk�rÍd&| ¡  }|d'|d d |j ¡ |g¡|d ||f 7 }|�rì||7 }n|j�rõ|
|7 }
n|jd k�r |	|7 }	n||7 }|d
7 }qr|dk�s|	dk�s|
dk�r“d(}|�r!|d)7 }td*ƒ}td+ƒ}td,ƒ}d-}||||f }|�r=|d)7 }||d.t|ƒ d.t|ƒ d.t|ƒ f 7 }||7 }|dk�r_||7 }|dk�ro|	dk�ro|td/ƒ7 }|	dk�rx||	7 }|dk�rˆ|
dk�rˆ|td/ƒ7 }|
dk�r‘||
7 }|}|�r¾|   ¡ \} }!td0ƒ|  !¡ |  !d1¡|  !d2d¡d3œ }"|  "¡ }#td4ƒ|!|"|#|d5œ S td6ƒ| S )7zShow ufw managed rulesrP   rh   zChecking iptables
zChecking ip6tables
úproblem runningr   rj   rr   ri   é   zStatus: inactiver   z iptables: %s
rs   ú
 ip6tablesTFzSkipping found tuple '%s')ÚdstÚsrcr‹   z::/0ú (v6)z	0.0.0.0/0Úanyú ú/z (%sú)rŒ   ÚAnywherez on %sr~   z (%s)z, z[%2d] ÚFWDÚinz # %sz%-26s %-12s%-26s%s%s
z

z     ÚToÚFromÚActionz%-26s %-12s%s
ú-rx   zCDefault: %(in)s (incoming), %(out)s (outgoing), %(routed)s (routed)r   r   )r”   r~   rL   z0Status: active
%(log)s
%(pol)s
%(app)s%(status)s)ÚlogÚpolÚappÚstatuszStatus: active%s)#r7   rD   r2   r   r   r   r|   r   r   ÚdappÚsappÚget_app_tupler   r‹   Úv6ÚdportrŒ   ÚsportÚprotocolr   Úinterface_inÚinterface_outÚlogtyperS   Úlowerr3   Úlenr,   ÚupperÚcommentÚget_commentÚactionÚget_loglevelÚ_get_default_policyrG   )$r6   ÚverboseÚ
show_countr~   r_   rS   r†   Úout6ÚsÚstr_outÚstr_rter   ÚcountÚ	app_rulesÚrÚtmp_strÚlocationÚtuplÚ
show_protor;   ÚportrQ   ÚattribsÚ
attrib_strÚdir_strr(   Úfull_strÚstr_toÚstr_fromÚ
str_actionÚrules_header_fmtÚrules_headerÚlevelÚlogging_strÚ
policy_strÚapp_policy_strr>   r>   r?   Ú
get_status  sz  
ÿ
ÿ€

€€



€€ €€
ÿÿ
ÿü






þÿ


ÿþýÿÿzUFWBackendIptables.get_statusc                 C   s¤   | j rtdtdƒ ƒ dS g }| | jd ¡ | jdur7| jdur7| d¡ | | j¡ | d¡ | | j¡ | d¡ t|ƒ\}}|dkrPtd	| ƒ}t|ƒ‚dS )
zStop the firewallrh   úrunning ufw-initr   Nú	--rootdirú	--datadirz
force-stopr   úproblem running ufw-init
%s)	r7   r   rD   r3   r8   r   r   r   r   ©r6   r   r†   r~   r_   r>   r>   r?   Ústop_firewallë  s   


þz UFWBackendIptables.stop_firewallc                 C   s(  | j rtdtdƒ ƒ dS g }| | jd ¡ | jdur7| jdur7| d¡ | | j¡ | d¡ | | j¡ | d¡ t|ƒ\}}|dkrPtd	| ƒ}t|ƒ‚d
| j	vsa| j	d
 t
| j ¡ ƒvryz|  d¡ W dS  tyx   tdƒ}t|ƒ‚w z|  | j	d
 ¡ W dS  ty“   tdƒ}t|ƒ‚w )zStart the firewallrh   rË   r   NrÌ   rÍ   Ústartr   rÎ   ÚloglevelÚlowzCould not set LOGLEVELzCould not load logging rules)r7   r   rD   r3   r8   r   r   r   r   rE   ÚlistÚ	loglevelsÚkeysÚset_loglevelrV   Úupdate_loggingrÏ   r>   r>   r?   Ústart_firewallý  s8   



þþz!UFWBackendIptables.start_firewallc                 C   s¢   | j rdS |  ¡  d}| j}|rd}| j}dD ]7}|dks!|dkr5|r+| jd d s+q|s5| jd d s5qt|d	d
|d | gƒ\}}|dkrNtdƒ  dS qdS )zCheck if all chains existFr   Úufw6)r   r   r   r!   úlimit-acceptr!   rÛ   r   r   ri   rj   z-user-r   z_need_reload: forcing reloadT)r7   ry   r   r|   rz   r   r   )r6   r    ÚprefixÚexer=   r†   r~   r>   r>   r?   Ú_need_reload  s(   þzUFWBackendIptables._need_reloadc                 C   sú   t dƒ}| jrtdƒ |  ¡ rtdƒ dS dS |  ¡ rwz| jd D ]}|  |d|g¡ |  |d|g¡ q!W n ty@   t|ƒ‚w t	d| j
d g| jd	gƒ\}}|d
krZt|d ƒ‚|  ¡ ryt	d| j
d g| jd	gƒ\}}|d
kr{t|d ƒ‚dS dS dS )zReload firewall rules filerˆ   z> | iptables-restorez> | ip6tables-restorer   ú-Fú-ZÚcatr   ri   r   z	 iptablesr   rŠ   N)rD   r7   r   r2   Ú
is_enabledr1   Ú
_chain_cmdrV   r   r   r8   Úiptables_restoreÚip6tables_restore)r6   r_   r‚   r†   r~   r>   r>   r?   Ú_reload_user_rules:  s:   ÿþÿÿÿíz%UFWBackendIptables._reload_user_rulesc                 C   s8  g }t  d¡}t  d¡}t  d¡}| |¡rK| |¡rA| |¡r.| | d| d|¡¡¡ n	| | d|¡¡ | | d|¡¡ n| | d|¡¡ n| |¡ t  d¡}t  d	¡}	t  d
¡}
d}t|ƒD ]v\}}| |¡rÛ| d|¡ ¡ }| ¡ dkrd}n| ¡ dkrˆd}nd}d||f }|	 |¡s™d| }| d|¡||< | || d| d | |¡¡ | ||
 d| d | | d|¡¡¡ | ||
 d| d | | d| |¡¡¡ qet  d¡}t|ƒD ]4\}}| |¡�r| d|¡}| d| d |¡}| d| d |¡}|||< | ||¡ | ||¡ qå|S ) z5Return list of iptables rules appropriate for sendingz-p all zport z-j (REJECT(_log(-all)?)?)z-p tcp z-j \1 --reject-with tcp-resetz-p udp rP   z(.*)-j ([A-Z]+)_log(-all)?(.*)z-j [A-Z]+_log-allz(-A|-D) ([a-zA-Z0-9\-]+)z'-m limit --limit 3/min --limit-burst 10ú\2rA   ÚALLOWr!   ÚLIMITÚBLOCKz"%s -j LOG --log-prefix "[UFW %s] "z-m conntrack --ctstate NEW z	\1-j \2\4z\1-j z-user-logging-z\1 z\1-j RETURNú\1z	 -j LIMITz+ -m conntrack --ctstate NEW -m recent --setzL -m conntrack --ctstate NEW -m recent --update --seconds 30 --hitcount 6 -j z-user-limitz -j z-user-limit-accept)	rW   rX   r[   r3   r]   Ú	enumerateÚstripr§   Úinsert)r6   ÚfrulerÜ   ÚsuffixÚsnippetsÚ	pat_protoÚpat_portÚ
pat_rejectÚpat_logÚ
pat_logallÚ	pat_chainÚ
limit_argsr„   r²   rT   ÚlstrÚ	pat_limitÚtmp1Útmp2Útmp3r>   r>   r?   Ú_get_rules_from_formattedV  sš   






ÿÿ




ÿ
ÿÿÿÿÿÿþÿÿþ€
ÿþþþ€z,UFWBackendIptables._get_rules_from_formattedc           	      C   sš   g }|   |||¡}t d¡}t|ƒD ]8\}}| | d|¡ ¡ ¡ | |¡rJ||  d¡ ||  | d|¡ dd¡¡ ||  | d|¡ ¡ 7  < q|S )z_Return list of iptables rules appropriate for sending as arguments
           to cmd()
        z(.*) --log-prefix (".* ")(.*)rë   r%   rç   ú"rP   z\3)	rþ   rW   rX   rì   r3   r]   r{   ÚmatchÚreplace)	r6   rï   rÜ   rð   rñ   Ústr_snippetsrb   r„   r²   r>   r>   r?   Ú_get_lists_from_formattedš  s   

€z,UFWBackendIptables._get_lists_from_formattedc                 C   sŠ  | j d g}|  ¡ r| | j d ¡ |D �]­}ztj |¡}W n ty0   tdƒ| }t|ƒ‚w t	 
d¡}t	 
d¡}t	 
d¡}|D �]z}|}	d}
d|v rX| d¡\}	}| ¡ }
| |	¡�r½| d|	¡}t	 d	| ¡ ¡}t|ƒd
k sxt|ƒdkrƒtdƒ| }t|ƒ qBd}d}d}t|ƒdks–t|ƒdk�rtdƒ| }|d  d¡d }d|d v �rd|d v rÝ| |d ¡rÝ| |d ¡rÝ|d  d¡d  d¡d }|d  d¡d  d¡d }n'|d  d¡rî|d  d¡d }n|d  d¡rÿ|d  d¡d }nt|ƒ qBz…|d }d}d|v �rd}| d¡d }t|ƒdk �r7t||d |d |d |d |d |||
ƒ	}n;t||d |d |d |d |d |||
ƒ	}t	 
d¡}|d
 d k�rb| d!|d
 ¡|_|d d k�rr| d!|d ¡|_|dk�r}| d|¡ |dk�rˆ| d"|¡ W n t�y�   td#ƒ| }t|ƒ Y qBw || j d k�r²| d¡ | j |¡ qB| d¡ | j |¡ qB| ¡  qd$S )%z$Read in rules that were added by ufwr   r   zCouldn't open '%s' for readingz^### tuple ###\s*zin_\w+zout_\w+rP   z	 comment=z\s+é   é	   z)Skipping malformed tuple (bad length): %sr”   é   z$Skipping malformed tuple (iface): %séÿÿÿÿrD   r   ú!é   r‰   Úin_Úout_Frw   Té   é   é   é   ú%20r˜   r�   r~   zSkipping malformed tuple: %sN)r8   r2   r3   r   rY   Úopen_file_readrV   rD   r   rW   rX   r{   rí   r   r]   r¨   r   r[   Ú	partitionÚ
startswithr   r�   rž   Úset_interfaceÚset_v6r   r   Úclose)r6   Úrfnsrc   rR   r_   Ú	pat_tupleÚpat_iface_inÚpat_iface_outÚ	orig_linerf   rª   Úhexrº   rQ   ÚwmsgÚdtyper¤   r¥   r¬   r   ÚruleÚ	pat_spaceÚwarn_msgr>   r>   r?   Ú_read_rules¬  s¸   
þ



ÿÿÿþÿÿ
þþ


€ÿü

€
£zUFWBackendIptables._read_rulesc                 C   s&  | j d }|r| j d }t |tj¡std| ƒ}t|ƒ‚ztj |¡}W n t	y-   ‚ w |  
¡  d}| j}|r>d}| j}| jrGtj ¡ }n|d }tj |d¡ tj |d| d	 ¡ tj |d| d
 ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ tj |d| d ¡ |dkrø| jd d �s|dk�r| jd d �rtj |d| d ¡ tj |d| d ¡ tj |d¡ |D �]	}|j}	|j�r3d|j }	|jdk�r@|	d|j 7 }	d}
|jdk�rR|jdk�rR|j}
n0|jdk�rg|jdk�rgd |j|jf }
n|jdk�rx|
d!|j|jf 7 }
n
|
d!|j|jf 7 }
|jdk�rµ|jdk�rµd"|	|j|j|j|j|j|
f }|j dk�r«|d#|j  7 }tj ||d$ ¡ nGt! "d%¡}d&}|j�rÇ| #d'|j¡}d&}|j�rÔ| #d'|j¡}d(|	|j|j|j|j|j|||
f	 }|j dk�ró|d#|j  7 }tj ||d$ ¡ d)}|j�rd*}n|jd+k�rd,}d-||f }d.|| $¡ f }|  %|||¡D ]
}tj ||¡ �q"�q$tj |d/¡ tj |d0¡ z
|  &| j'd1 ¡}W n	 t	�yP   ‚ w |D ]2\}}}t(|ƒd2k�rh|d2 d3k�rh�qS| )|d& ¡�r„tj |d% *|¡ +d4d5¡ +d6d7¡d$ ¡ �qStj |d8¡ |dk�rš| jd d �s§|dk�rë| jd d �rëtj |d9¡ | j'd1 d:k�rÎtj |d;| d< d% *| j,¡ d= | j- d> ¡ tj |d;| d? ¡ tj |d;| d@ ¡ tj |dA¡ tj |dB¡ z| j�rtj .|dC¡ W dDS tj .|¡ W dDS  t	�y   ‚ w )Ez.Write out new rules to file to user chain filer   r   z'%s' is not writabler   rÚ   rQ   z*filter
rw   z-user-input - [0:0]
z-user-output - [0:0]
z-user-forward - [0:0]
z-before-logging-input - [0:0]
z-before-logging-output - [0:0]
z -before-logging-forward - [0:0]
z-user-logging-input - [0:0]
z-user-logging-output - [0:0]
z-user-logging-forward - [0:0]
z-after-logging-input - [0:0]
z-after-logging-output - [0:0]
z-after-logging-forward - [0:0]
z-logging-deny - [0:0]
z-logging-allow - [0:0]
r!   r   r   z-user-limit - [0:0]
z-user-limit-accept - [0:0]
z### RULES ###
zroute:rP   rD   zin_%s!out_%sz%s_%sz#
### tuple ### %s %s %s %s %s %s %sz comment=%srx   r�   r˜   r  z)
### tuple ### %s %s %s %s %s %s %s %s %sr   r   r~   r   ú
%s-user-%sz	-A %s %s
z
### END RULES ###
z
### LOGGING ###
rÒ   r   ú-Dú[z"[z] z] "z### END LOGGING ###
z
### RATE LIMITING ###
Úoffz-A z-user-limit z "z "
z-user-limit -j REJECT
z-user-limit-accept -j ACCEPT
z### END RATE LIMITING ###
zCOMMIT
FN)/r8   r*   ÚaccessÚW_OKrD   r   r   rY   rZ   rV   ry   r   r   r7   ÚsysÚstdoutÚfilenor\   rz   r¬   r   r¦   r¤   r¥   rS   r�   rž   r£   r¡   r‹   r¢   rŒ   rª   rW   rX   r]   Úformat_rulerþ   Ú_get_logging_rulesrE   r¨   r  r,   r  r4   r5   r^   )r6   r    Ú
rules_filer_   rd   r:   r   re   r·   r¬   ÚifacesÚtstrr   r�   rž   Úchain_suffixr=   Úrule_strr²   Úlrules_tr‚   Úqr>   r>   r?   Ú_write_rules  sT  

ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

ÿÿ
ÿÿÿþÿÿÿ€
ÿÿ
þýýýÿÿÿzUFWBackendIptables._write_rulesTc              	   C   sn  |   ¡  d}|jr)|  ¡ stdƒ}t|ƒ‚|jdkr(| jd d s(tdƒ|j S n|jdkr<| jd d s<tdƒ|j S |jrQ|jdkrQ|jd	krQtd
ƒ}t|ƒ‚g }d}d}| j	}|j
}	|jrv| jdk rs|jdkso|jdkrstdƒS | j}|	dk s€|	t|ƒkrŠtdƒ|	 }t|ƒ‚|	dkr™|jr™tdƒ}t|ƒ‚|	t|ƒkr©tdƒ|	 }t|ƒ‚z| ¡  W n ty·   ‚ w d}
d}d}d}|D ]±}z| ¡  W n tyÒ   ‚ w |j|j|j|jf}|
|	k�r|d dkró|d dkró|
dk�s|d dk�r|d dk�s||k�rd}| | ¡ ¡ d}n|	d7 }	|}|
d7 }
t ||¡}|dk �r+|d7 }|dk�rD|�sD|�sDd}|j�sC| | ¡ ¡ qÂ|dk�rV|j�rV|jdk�rVd}qÂ|dk �rn|j�sn|�snd}d}| | ¡ ¡ qÂ| |¡ qÂ|�r‹|dk�rŠtdƒ}|j�rˆ|d7 }|S n?|�s™|j�s™| | ¡ ¡ |�s²|j�r²| j�s²tdƒ}|j�r°|d7 }|S |�rÊ|j�sÊ|�sÊtdƒ}|j�rÈ|d7 }|S |j�rÒ|| _n|| _	z|  |j¡ W n t�yæ   ‚  t�y÷   tdƒ}t|ƒ Y nw tdƒ}|j�rtdƒ}|  ¡ �r5| j�s5d}|�s|  |j¡�s|�rPd}|�r(|tdƒ7 }n|td ƒ7 }|j�r6|d7 }|�rIz|  ¡  W nR t�yH   ‚ w |td!ƒ7 }nB|�r‚|j�r‚d"}td#ƒ}|j�re|d7 }|�r{z|  ¡  W n	 t�yw   ‚ w d}n|td!ƒ7 }n|�s’|�s’|j�s’d$}td%ƒ}|dk�r5| j}d&}|j�r©| j }d'}|d7 }d(}|j!�r²d)}n|j"d*k�rºd+}d,||f }td-ƒ}t#|d.|d/gƒ\}}|dk�r×t|ƒ‚d0||| $¡ f }t% &d1¡}|  '|||¡D ]H}t#|g| ƒ\}}|dk�rt(|t)j*ƒ t|ƒ |d$k�r3| +d2 ,|¡¡�r3| -d3d2 ,|¡¡}t#|d"|d4d5gƒ\}}|dk�r3t.d6| ƒ �qì|S )7aX  Updates firewall with rule by:
        * appending the rule to the chain if new rule and firewall enabled
        * deleting the rule from the chain if found and firewall enabled
        * inserting the rule if possible and firewall enabled
        * updating user rules file
        * reloading the user rules file if rule is modified
        rP   z)Adding IPv6 rule failed: IPv6 not enabledr!   r   z#Skipping unsupported IPv6 '%s' ruler   z#Skipping unsupported IPv4 '%s' ruleÚudpÚtcpz/Must specify 'tcp' or 'udp' with multiple portsFz1.4z:Skipping IPv6 application rule. Need at least iptables 1.4r   zInvalid position '%d'z Cannot specify insert and deletez#Cannot insert rule at position '%d'r‰   )rP   rP   rP   rP   r	  r  Téþÿÿÿz Skipping inserting existing ruler�   z"Could not delete non-existent rulezSkipping adding existing rulezCouldn't update rules filezRules updatedzRules updated (v6)zRule insertedzRule updatedz (skipped reloading firewall)r$  zRule deletedú-Az
Rule addedr   rÚ   r   r   r~   r   r#  ú!Could not update running firewallrj   ri   z%s %s %sz(-A +)(ufw6?-user-[a-z\-]+)(.*)r�   rç   r#   ÚRETURNzFAILOK: -D %s -j RETURN)/ry   r    r2   rD   r   r¬   rz   Úmultir£   r   ÚpositionÚiptables_versionr�   rž   r   r¨   ÚremoveÚ	normalizerV   r‹   rŒ   r3   Údup_ruler   r   rª   r7   r5  râ   rÞ   ræ   r   r|   r   rS   r   r,  rW   rX   r  r   r)  Ústderrr[   r,   r]   r   )r6   r  Úallow_reloadrF   r_   ÚnewrulesÚfoundÚmodifiedr   r=  rµ   ÚinsertedÚmatchesÚlastr·   ÚcurrentÚretÚflagrÝ   r:   r1  r=   r†   r~   r2  rõ   r²   r‚   r>   r>   r?   Úset_ruleº  sZ  
€
ÿÿ
"

€
üþÿÿ


þ

€zUFWBackendIptables.set_rulec           
      C   st   g }g }|r
| j }n| j}| ¡ }| |¡ | ¡  | ¡ }|D ]}| ¡ }| ¡  | ¡ }	|	|kr7| |¡ q |S )z@Return a list of UFWRules from the system based on template rule)r   r   rA  r  r@  rŸ   r3   )
r6   Útemplater    r   r¶   Únormrº   r·   rQ   Ú	tmp_tupler>   r>   r?   Úget_app_rules_from_system¢  s"   

€z,UFWBackendIptables.get_app_rules_from_systemc                 C   s\   | j }| d¡r| j}t|g| ƒ\}}|dkr,td| ƒ}|r(td| ƒ dS t|ƒ‚dS )zPerform command on chainrÚ   r   zCould not perform '%s'zFAILOK: N)r   r  r|   r   rD   r   r   )r6   r=   r   Úfail_okrÝ   r†   r~   r_   r>   r>   r?   rã   º  s   
ûzUFWBackendIptables._chain_cmdc           	   	   C   sx  | j rdS |  ¡  g }z|  |¡}W n ty   ‚ w z| jdd� | jdd� W n ty1   ‚  tyA   tdƒ}t|ƒ Y nw |  ¡ sHdS tdƒ}| jd | jd  | jd	  | jd
  D ]}z|  	|d|dg¡ W q` tyx   t|ƒ‚w z$| jd | jd	  | jd
  D ]}|  	|d|g¡ |  	|d|g¡ q‰W n ty¨   t|ƒ‚w |D ]B\}}}d}t
|ƒdkrÀ|d dkrÀd}z"|dkrÚt
|ƒdkrÚ| j	|dg|dd…  dd� |  	|||¡ W q« tyí   t|ƒ‚w dD ]I}| jd d rþ|dk�s| jd d �r9|dk�r9| j	|d|g| j | jd g dd� | jd dk�r9| j	|d|g| j | jd g dd� qðdS )z#Update loglevel of running firewallNF)r    Tz&Couldn't update rules file for loggingr:  r   r   r   r   rj   ri   rß   rà   r   r$  Údelete_firstr‰   )rR  )rt   ru   r!   r   rt   r   ru   r�   rÒ   r&  ú-I)r7   ry   r-  rV   r5  r   rD   râ   r1   rã   r¨   rz   r4   r5   rE   )	r6   rÆ   Úrules_tr_   r‚   r·   r4  rR  r=   r>   r>   r?   rØ   Ç  s”   ÿþÿÿÿÿýÿÿÿ
ÿ
þýÿ
þý€øz!UFWBackendIptables.update_loggingc           	      C   s¼  g }|t | j ¡ ƒvrtdƒ| }t|ƒ‚|dkr/| jd D ]}| |d|ddgdg¡ q|S | jd D ]}| |d|ddgd	g¡ q4g d
¢}| j| | jd k�rg }| j| | jd k r`|}| jd D ]I}dD ]D}| |¡r­|  |¡dks~|  |¡dkr‘d}| |d|ddd|g| d	g¡ qi| j| | jd kr­d}| |d|ddd|g| d	g¡ qiqeg }| j| | jd k r½|}| jd D ]S}| d¡rÌd}n9| d¡�rd}| j| | jd k rñ| |d|ddddddg| d	g¡ n| |d|ddddddddg
| d	g¡ | |d|ddd|g| d	g¡ qÂ| j| | jd k�r\g }| j| | jd k �r0|}| j| | jd k �rAg d¢| }d }| jd! D ]}| |d|ddd|g| d	g¡ �qH|S )"z%Get rules for specified logging levelzInvalid log level '%s'r&  r   rT  r#   r;  rS  r$  rP   )r    r!   r"   z3/minz--limit-burstÚ10rÓ   Úhighr   r   rC   rI   z[UFW BLOCK] r9  r$   r%   Úmediumz[UFW ALLOW] r   rH   r    Ú	conntrackú	--ctstateÚINVALIDz[UFW AUDIT INVALID] Úfull)r    rY  rZ  ÚNEWz[UFW AUDIT] r   )	rÔ   rÕ   rÖ   rD   r   r1   r3   Úendswithr®   )	r6   rÆ   rU  r_   r‚   rø   Úlargsr…   rÜ   r>   r>   r?   r-    s²   
ÿþþÿþþ€ö
þþþüûûÿÿÿÿÿ
ÿz%UFWBackendIptables._get_logging_rulesc              
   C   sÈ  d}t tjj| jƒ}g }| jD ]2}| j|  d¡sq| | j| ¡ tj	 
|dtj	 | j| ¡¡}tj	 |¡sAtdƒ| }t|ƒ‚qt d¡}|D ]}d||f }tj	 |¡ratdƒ| }t|ƒ‚qI|D ]}d||f }|tdƒtj	 |¡|d	œ 7 }t ||¡ qd|D ]]}d||f }t tj	 
|dtj	 |¡¡tj	 |¡¡ t ||¡ zt |¡}	|	tj }
W n tyÅ   td
ƒ| }t|ƒ Y q„w |
tj@ rÔ|tdƒ| 7 }q„|
tj@ rá|tdƒ| 7 }q„|S )zReset the firewallrP   z.rulesr   zCould not find '%s'. Abortingz%Y%m%d_%H%M%Sz%s.%sz'%s' already exists. Abortingz"Backing up '%(old)s' to '%(new)s'
)ÚoldÚnewzCouldn't stat '%s'zWARN: '%s' is world writablezWARN: '%s' is world readable)r	   r   r&   Ú	share_dirr   r8   r^  r3   r*   r+   r,   ÚbasenameÚisfilerD   r   ÚtimeÚstrftimeÚexistsÚrenameÚshutilÚcopyÚdirnameÚcopymodeÚstatÚST_MODErV   r   ÚS_IWOTHÚS_IROTH)r6   Úresrb  Úallfilesr„   Úfnr_   Úextr`  ÚstatinfoÚmoder!  r>   r>   r?   Úresetk  sb   

ÿþ
þÿ
ÿ
þ
ý

€zUFWBackendIptables.reset)NN)FF)F)T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r0   rG   rg   r‡   rÊ   rÐ   rÙ   rÞ   ræ   rþ   r  r"  r5  rM  rQ  rã   rØ   r-  rw  r>   r>   r>   r?   r
      s0    
0K
] f!D
e 
* i
JZr
   )r{  r*   rW   ri  rm  r)  re  Ú
ufw.commonr   r   Úufw.utilr   r   r   r   r   r	   Úufw.backendr   r.   r/   r
   r>   r>   r>   r?   Ú<module>   s     