
VV                 @   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 Gd 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 d  Z d d   Z d d   Z d	 d
   Z d 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   sa  d t  j j d |  _ | |  _ | |  _ i  } t t  j j |  } t t  j j |  } t	 j
 j | d  | d <t	 j
 j | d  | d <t	 j
 j | d  | d <t	 j
 j | d	  | d
 <t	 j
 j | d  | d <t	 j
 j | d  | d <t	 j
 j t | |  d  | d <t  j j j |  d | | d | d | d g  d g  d g  d g  i |  _ x d d g D] } d } | d k r|  j   r| | 7} n | d k rqgxX d d d g D]G }	 x> d d d g D]- }
 d | |	 |
 f } |  j |	 j |  qWqW|  j d j | d  |  j d j | d   qgWd! d" d# d$ d% d& d' g |  _ d( |  _ d) S)*z!UFWBackendIptables initializationz# z
_comment #zufw/user.rulesruleszufw/before.rulesZbefore_ruleszufw/after.rulesafter_ruleszufw/user6.rulesrules6zufw/before6.rulesZbefore6_ruleszufw/after6.rulesafter6_ruleszufw-initinitiptablesrootdirdatadirbeforeuseraftermisc46ufwinputoutputforwardz%s-%s-logging-%sz-logging-denyz-logging-allowz-mlimitz--limitz3/minutez-jLOGz--log-prefixz[UFW LIMIT BLOCK]N)r   commonZprogramNamecomment_strr   r   r	   
config_dir	state_dirospathjoinbackend
UFWBackend__init__chainsuse_ipv6appendufw_user_limit_logufw_user_limit_log_text)selfdryrunr   r   filesr!   r"   Zverchain_prefixloctargetchain r5   6/usr/lib/python3/dist-packages/ufw/backend_iptables.pyr(       sB    		"!zUFWBackendIptables.__init__c             C   sz   t  d  } |  j d d k r, | d 7} nJ |  j d d k rL | d 7} n* |  j d d k rl | d 7} n
 | d	 7} | S)
zGet current policyzNew profiles:Zdefault_application_policyacceptz allowZdropz denyrejectz rejectz skip)_defaults)r.   rstrr5   r5   r6   get_default_application_policyL   s    
z1UFWBackendIptables.get_default_application_policyc             C   s  |  j  s| d k rI | d k rI | d k rI t d  | } t |   | d k r | d k r | d k r t d  | } t |   d	 } | d k r d
 } n | d k r d } d } d } | d k ry" |  j |  j d d | d  Wn t k
 r  Yn Xd } d } n | d k rly" |  j |  j d d | d  Wn t k
 r\  Yn Xd } d } nF y" |  j |  j d d | d  Wn t k
 r  Yn Xd } d } t j d |  } x |  j d |  j d g D] } y t j	 j
 |  }	 Wn t k
 r  Yn X|	 d }
 xV |	 d D]J } | j |  r`t j	 j |
 | j | |   q)t j	 j |
 |  q)Wy t j	 j |	  Wqt k
 r  YqXqWt d  d | d | i } | t d  7} | S)zSets default policy of firewallallowdenyr8   zUnsupported policy '%s'ZincomingZoutgoingroutedz%Unsupported policy for direction '%s'INPUTOUTPUTFORWARD r:   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))r/   r9   r   Zset_defaultr0   	Exceptionrecompiler   util
open_filessearchwrite_to_filesubclose_files)r.   rG   rF   err_msgr4   Zold_log_strZnew_log_strpatffnsfdliner;   r5   r5   r6   set_default_policyZ   sz    	$				!
"	z%UFWBackendIptables.set_default_policyc             C   s<  |  j  r1 d t d  } | d t d  7} | S|  j   d d d d g } g  } g  } | d k r | j d	  d
 d d d g } d
 d d g } n| d k rx9 d d d g D]( } | j d |  | j d |  q Wx? d d d d d g D]( } | j d |  | j d |  q Wx6 d d g D]( } | j d |  | j d |  q-Wx"d d d g D] } | j d |  qiWn| d k rxd d d g D]( } | j d |  | j d |  qWn| d k rsx9 d d d g D]( } | j d |  | j d |  qW|  j d  d! rE| j d"  | j d#  |  j d  d$ r~| j d%  | j d&  n| d' k rx d d d g D]( } | j d( |  | j d) |  qWn | d* k r~x} d d d g D]l } | j d+ |  | j d, |  | j d- |  | j d. |  | j d/ |  | j d0 |  qW| j d1  | j d2  | j d3  | j d4  d5 | } x | D] } d6 | k r| j d6  \ }	 } | d7 |	 7} t |  j g | | d	 |	 g  \ }
 } n# t |  j g | | g  \ }
 } | | 7} | d k r3| d8 7} |
 d9 k rt |   qW| d k sg|  j	   r8| d: 7} x | D] } d6 | k r| j d6  \ }	 } | d7 |	 7} t |  j g | | d	 |	 g  \ }
 } n# t |  j
 g | | g  \ }
 } | | 7} | d k r| d8 7} |
 d9 k rxt |   qxW| S);z'Show current running status of firewallz> zChecking raw iptables
zChecking raw ip6tables
z-nz-vz-xz-Lrawz-tfilterZnatZmanglebuiltinsr@   rB   rA   z	filter:%sZ
PREROUTINGZPOSTROUTINGz	mangle:%szraw:%sznat:%sr   r   r   r   zufw-before-%szufw6-before-%sr   zufw-user-%szufw6-user-%sr   r   zufw-user-limit-acceptzufw-user-limitr   zufw6-user-limit-acceptzufw6-user-limitr   zufw-after-%szufw6-after-%sZ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:
)r/   r9   initcapsr+   capssplitr   r   r   r*   	ip6tables)r.   Z
rules_typeoutargsitemsZitems6cbitrcrD   r5   r5   r6   get_running_raw   s    	

,#


,#

z"UFWBackendIptables.get_running_rawFc       $   	   C   s	  d } |  j  rC d t d  } |  j   r? | d t d  7} | St d  } x d d d g D] } t |  j d	 d
 | d g  \ } } | d k r t d  S| d k r t | d |   |  j   r_ t |  j d	 d | d g  \ } } | d k r_ t | d   q_ Wd } d }	 d }
 |  j |  j } d } i  } xN| D]F} d } i  } d } d } | r| j	 d k s| j
 d k rd } | j   } | | k rt d |  qFn
 d | | <xd d g D]	} d | | <d } d } | d k rP| j } | rD| j	 d k rD| j	 } | j rM| d k rM| d 7} q| j } nS | j } | r| 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 r| j	 d k r| | d | j	 7<| j r| d k r| | 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 | | <| rn| j d k rn| j | j k rn| j | j k rn| | d | j 7<| d k r| | d 7<q| r| j d k r| j | j k r| | d | j 7<nE | j r| j d k r| j d k rd | | k r| | d 7<| j r{| d k rH| j d k rH| | d  | j 7<| d k r| j d k r| | d  | j 7<q| d k r| j d k r| | d  | j 7<| d k r| j d k r| | d  | j 7<qWg  } d } | j s	| j j   d! k rr| j r(| j | j j    | rM| j d! k rM| j | j  t |  d k rrd" d# j |  } | r| d$ | 7} | j j   } | j rd% } | j d& k r| j r| r| rd } d } | j d k rd' | j   } | d( | d d j | j j   | g  | d | | f 7} | rF| | 7} n< | j r\|
 | 7}
 n& | j d! k rx|	 | 7}	 n
 | | 7} | d 7} qFW| 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 rl| | 7} | d k r|	 d k r| t d0  7} |	 d k r| |	 7} | d k r|
 d k r| t d0  7} |
 d k r| |
 7} | } | r}	|  j    \ }  }! t d1 d2 d3  d& |  j!   d! |  j! d  d4 |  j! d d  i }" |  j"   }# t d5  d6 |! d7 |" d8 |# d9 | i St d:  | Sd; S)<zShow ufw managed rulesrC   z> zChecking iptables
zChecking ip6tables
zproblem runningr   r   r   z-Lzufw-user-%sz-n   zStatus: inactiver   z iptables: %s
zufw6-user-%sz
 ip6tablesTFzSkipping found tuple '%s'dstsrcz::/0z (v6)z	0.0.0.0/0any /z (%s)ZAnywherez on %sra   z (%s)z, z[%2d] ZFWDinz # %sz%-26s %-12s%-26s%s%s
z

z     ZToZFromZActionz%-26s %-12s%s
-r\   zDefault: %(in)s (incoming), z%(out)s (outgoing), z%(routed)s (routed)r?   z0Status: active
%(log)s
%(pol)s
%(app)s%(status)slogZpolZappZstatuszStatus: active%sN)#r/   r9   r*   r   r   r   r`   r   r   dappsappget_app_tupler   rk   v6dportrl   sportprotocolr   interface_ininterface_outlogtyperF   lowerr+   lenr%   uppercommentZget_commentactionZget_loglevel_get_default_policyr<   )$r.   verboseZ
show_countra   rQ   rF   rh   Zout6sZstr_outZstr_rter   count	app_rulesrZtmp_strlocationtuplZ
show_protor2   ZportrD   ZattribsZ
attrib_strZdir_strr    Zfull_strZstr_toZstr_fromZ
str_actionZrules_header_fmtZrules_headerlevelZlogging_strZ
policy_strZapp_policy_strr5   r5   r6   
get_status  sT   	
%

					

$'				
	
$





	zUFWBackendIptables.get_statusc             C   s   |  j  r  t d t d   n g  } | j |  j d  |  j d k	 r |  j d k	 r | j d  | j |  j  | j d  | j |  j  | j d  t |  \ } } | d k r t d	 |  } t |   d S)
zStop the firewallz> zrunning ufw-initr   Nz	--rootdirz	--datadirz
force-stopr   zproblem running ufw-init
%s)	r/   r   r9   r+   r0   r   r   r   r   )r.   rb   rh   ra   rQ   r5   r5   r6   stop_firewall  s    	z UFWBackendIptables.stop_firewallc             C   s  |  j  r  t d t d   npg  } | j |  j d  |  j d k	 r |  j d k	 r | j d  | j |  j  | j d  | j |  j  | j d  t |  \ } } | d k r t d	 |  } t |   d
 |  j	 k s
|  j	 d
 t
 |  j j    k rKy |  j d  Wqt k
 rGt d  } t |   YqXnE y |  j |  j	 d
  Wn* t k
 rt d  } t |   Yn Xd S)zStart the firewallz> zrunning ufw-initr   Nz	--rootdirz	--datadirstartr   zproblem running ufw-init
%sloglevellowzCould not set LOGLEVELzCould not load logging rules)r/   r   r9   r+   r0   r   r   r   r   r:   list	loglevelskeysZset_loglevelrH   update_logging)r.   rb   rh   ra   rQ   r5   r5   r6   start_firewall  s4    	"z!UFWBackendIptables.start_firewallc             C   s   |  j  r d S|  j   d } |  j } | r; d } |  j } x d d d d d g D] } | d k so | d k r | r |  j d d	 r qQ n | r |  j d d
 r qQ t | d d | d | g  \ } } | d k rQ t d  d SqQ Wd S)zCheck if all chains existFr   ufw6r   r   r   r   zlimit-acceptr   r   z-nz-Lz-user-r   z_need_reload: forcing reloadT)r/   r]   r   r`   r^   r   r   )r.   rw   prefixexer4   rh   ra   r5   r5   r6   _need_reload  s&    	
		&
zUFWBackendIptables._need_reloadc             C   sK  t  d  } |  j r8 t d  |  j   rGt d  n|  j   rGyH xA |  j d D]2 } |  j | d | g  |  j | d | g  qU WWn t k
 r t |   Yn Xt	 d |  j
 d g |  j d	 g  \ } } | d
 k r t | d   |  j   rGt	 d |  j
 d g |  j d	 g  \ } } | d
 k rGt | d   d S)zReload firewall rules filezproblem runningz> | iptables-restorez> | ip6tables-restorer   z-Fz-Zcatr   z-nr   z	 iptablesr   z
 ip6tablesN)r9   r/   r   r*   
is_enabledr)   
_chain_cmdrH   r   r   r0   Ziptables_restoreZip6tables_restore)r.   rQ   rd   rh   ra   r5   r5   r6   _reload_user_rules6  s*    	
z%UFWBackendIptables._reload_user_rulesc             C   s#  g  } t  j d  } t  j d  } t  j d  } | j |  r | j |  r | j |  r | j | j d | j d |    n | j | j d |   | j | j d |   q | j | j d |   n | j |  t  j d  } t  j d	  }	 t  j d
  }
 d } xPt |  D]B\ } } | j |  r&| j d |  j   } | j   d k rtd } n! | j   d k rd } n d } d | | f } |	 j |  sd | } | j d |  | | <| j | | j d | d | |   | j | |
 j d | d | | j d |    | j | |
 j d | d | | j d | |    q&Wt  j d  } x t |  D] \ } } | j |  r| j d |  } | j d d d | d |  } | j d | d  |  } | | | <| j | |  | j | |  qW| 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 rC   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 10z\2r7   ZALLOWr   ZLIMITZ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 RETURNz\1z	 -j LIMITz+ -m conntrack --ctstate NEW -m recent --setz% -m conntrack --ctstate NEW -m recentz# --update --seconds 30 --hitcount 6z -j z-user-limitz-user-limit-accept)	rI   rJ   rM   r+   rO   	enumeratestripr~   insert)r.   fruler   suffixsnippetsZ	pat_protoZpat_portZ
pat_rejectpat_logZ
pat_logallZ	pat_chain
limit_argsrf   r   rG   ZlstrZ	pat_limitZtmp1Ztmp2Ztmp3r5   r5   r6   _get_rules_from_formattedR  sh    			

			
z,UFWBackendIptables._get_rules_from_formattedc       	      C   s   g  } |  j  | | |  } t j d  } x t |  D] \ } } | j | j d |  j    | j |  r7 | | j d  | | j | j d |  j d d   | | | j d |  j   7<q7 W| S)z_Return list of iptables rules appropriate for sending as arguments
           to cmd()
        z(.*) --log-prefix (".* ")(.*)z\1z--log-prefixz\2"rC   z\3)	r   rI   rJ   r   r+   rO   r_   matchreplace)	r.   r   r   r   r   Zstr_snippetsrR   rf   r   r5   r5   r6   _get_lists_from_formatted  s    )$z,UFWBackendIptables._get_lists_from_formattedc             C   s  |  j  d g } |  j   r0 | j |  j  d  x| D]y} y t j j |  } Wn. t k
 r t d  | } t |   Yn Xt	 j
 d  } t	 j
 d  } t	 j
 d  } x| D]} | }	 d }
 d | k r | j d  \ }	 } | j   }
 | j |	  r | j d |	  } t	 j d	 | j    } t |  d
 k  sTt |  d k rtt d  | } t |  q q d } d } d } t |  d k st |  d k rt d  | } | d$ j d  d } d | d% k rd | d& k rb| j | d'  rb| j | d(  rb| d) j d  d j d  d } | d* j d  d j d  d } ng | d+ j d  r| d, j d  d } n: | d- j d  r| d. j d  d } n t |  q yW| d } d } d | k rd } | j d  d } t |  d k  rNt | | d | d | d | d | d | | |
 	 } n t | | d | d | d | d | d | | |
 	 } t	 j
 d  } | d
 d k r| j d  | d
  | _ | d d k r| j d  | d  | _ | d k r| j d |  | d k r| j d! |  Wn/ t k
 rQt d"  | } t |  w Yn X| |  j  d k r| j d  |  j j |  q | j d  |  j j |  q W| j   q7 Wd# 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+rC   z	 comment=z\s+   	   z)Skipping malformed tuple (bad length): %srq      z$Skipping malformed tuple (iface): %srj   r9   r   !   Zin_Zout_Fr[   T            z%20rr   rn   ra   zSkipping malformed tuple: %sNr   r   r   r   r   r   r   r   r   r   )r0   r*   r+   r   rK   Zopen_file_readrH   r9   r   rI   rJ   r_   r   r   rO   r   r   rM   	partition
startswithr   rt   ru   Zset_interfaceset_v6r   r   close)r.   ZrfnsrS   rE   rQ   Z	pat_tupleZpat_iface_inZpat_iface_outZ	orig_linerV   r   hexr   rD   ZwmsgZdtyper{   r|   r   r   rule	pat_spacewarn_msgr5   r5   r6   _read_rules  s    $	
$	$'

		
zUFWBackendIptables._read_rulesc             C   s  |  j  d } | r  |  j  d } t j | t j  sQ t d |  } t |   y t j j |  } Wn t	 k
 r~   Yn X|  j
   d } |  j } | r d } |  j } |  j r t j j   } n
 | d } t j j | d  t j j | d | d	  t j j | d | d
  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  t j j | d | d  | d k r||  j d d s| d k r|  j d d rt j j | d | d  t j j | d | d  t j j | d  x| D]} | j }	 | j rd | j }	 | j d k r.|	 d | j 7}	 d }
 | j d k r^| j d k r^| j }
 n} | j d k r| j d k rd  | j | j f }
 nF | j d k r|
 d! | j | j f 7}
 n |
 d! | j | j f 7}
 | j d k ra| j d k rad" |	 | j | j | j | j | j |
 f } | j  d k rG| d# | j  7} t j j | | d$  n t! j" d%  } d& } | j r| j# d' | j  } d& } | j r| j# d' | j  } d( |	 | j | j | j | j | j | | |
 f	 } | j  d k r| d# | j  7} t j j | | d$  d) } | j r;d* } n | j d+ k rPd, } d- | | f } d. | | j$   f } x0 |  j% | | |  D] } t j j | |  qWqWt j j | d/  t j j | d0  y |  j& |  j' d1  } Wn t	 k
 r  Yn Xx | D] \ } } } t( |  d2 k r@| d2 d3 k r@q| j) | d&  rt j j | d% j* |  j+ d4 d5  j+ d6 d7  d$  qWt j j | d8  | d k r|  j d d s| d k r|  j d d rt j j | d9  |  j' d1 d: k r<t j j | d; | d< d% j* |  j,  d= |  j- d>  t j j | d; | d?  t j j | d; | d@  t j j | dA  t j j | dB  y3 |  j rt j j. | dC  n t j j. |  Wn t	 k
 r  Yn XdD S)Ez.Write out new rules to file to user chain filer   r   z'%s' is not writabler   r   rD   z*filter
r[   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:rC   r9   zin_%s!out_%sz%s_%sz#
### tuple ### %s %s %s %s %s %s %sz comment=%sr\   rn   rr   z%20z)
### tuple ### %s %s %s %s %s %s %s %s %sr   r   ra   r   z
%s-user-%sz	-A %s %s
z
### END RULES ###
z
### LOGGING ###
r   r   z-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)/r0   r#   accessW_OKr9   r   r   rK   rL   rH   r]   r   r   r/   sysstdoutfilenorN   r^   r   r   r}   r{   r|   rF   rt   ru   rz   rx   rk   ry   rl   r   rI   rJ   rO   format_ruler   _get_logging_rulesr:   r   r   r%   r   r,   r-   rP   )r.   rw   Z
rules_filerQ   rT   r1   r   rU   r   r   ZifacesZtstrr   rt   ru   chain_suffixr4   rule_strr   Zlrules_trd   qr5   r5   r6   _write_rules  s   
			
		!
		!		"$.	zUFWBackendIptables._write_rulesTc             C   s*  |  j    d } | j rr |  j   s= t d  } t |   | j d k r |  j d d r t d  | j Sn2 | j d k r |  j d d r t d  | j S| j r | j d k r | j d	 k r t d
  } t |   g  } d } d } |  j	 } | j
 }	 | j rP|  j d k  rG| j d k s=| j d k rGt d  S|  j } |	 d k  sn|	 t |  k rt d  |	 } t |   |	 d k r| j rt d  } t |   |	 t |  k rt d  |	 } t |   y | j   Wn t k
 r
  Yn Xd }
 d } d } d5 } x| D]} y | j   Wn t k
 rU  Yn X| 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 } | j | j    d6 } n
 |	 d 7}	 | } |
 d 7}
 t j | |  } | d k  r<| d 7} | d k r{| r{| r{d } | j s| j | j    q*| d7 k r| j r| j d k rd } q*| d k  r| j r| rd } d } | j | j    q*| j |  q*W| r0| d k rt d  } | j r)| d 7} | Sn | rT| j rT| j | j    | r| j r|  j rt d  } | j r| d 7} | S| r| j r| rt d  } | j r| d 7} | S| j r| |  _ n	 | |  _	 y |  j | j  Wn< t k
 r  Yn( t k
 r;t d  } t |  Yn Xt d  } | j r]t d  } |  j   r&|  j r&d } | s|  j | j  s| rd } | r| t d  7} n | t d  7} | j r| d 7} | ry |  j   Wqt k
 r  YqXqi| t d  7} nN | r?| j r?d  } t d!  } n* | ri| ri| j rid" } t d#  } | d k r&|  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 |   d. | | | j$   f } t% j& d/  } x |  j' | | |  D] } t# | g |  \ } } | d k rt( | t) j*  t |  | d" k rc| j+ d0 j, |   rc| j- d1 d0 j, |   } t# | d  | d2 d3 g  \ } } | d k rct. d4 |  qcW| S)8aX  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
        rC   z)Adding IPv6 rule failed: IPv6 not enabledr   r   z#Skipping unsupported IPv6 '%s' ruler   z#Skipping unsupported IPv4 '%s' ruleZudpZ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'rj   r   r   Tz Skipping inserting existing rulez (v6)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)z-DzRule deletedz-Az
Rule addedr   r   r   r   ra   r   z
%s-user-%sz!Could not update running firewallz-Lz-nz%s %s %sz(-A +)(ufw6?-user-[a-z\-]+)(.*)rn   z\2z-jRETURNzFAILOK: -D %s -j RETURN)rC   rC   rC   rC   )rC   rC   rC   rC   )/r]   rw   r*   r9   r   r   r^   Zmultirz   r   positionZiptables_versionrt   ru   r   r   remove	normalizerH   rk   rl   r+   dup_ruler   r   r   r/   r   r   r   r   r   r`   r   rF   r   r   rI   rJ   r   r   r   stderrrM   r%   rO   r   )r.   r   Zallow_reloadr;   rQ   ZnewrulesfoundZmodifiedr   r   r   ZinsertedZmatchesZlastr   ZcurrentZretZflagr   r1   r   r4   rh   ra   r   r   r   rd   r5   r5   r6   set_rule  s4   

	!!'			
	, 	


	$		
	
	
				
			
		
$!zUFWBackendIptables.set_rulec       
      C   s   g  } g  } | r |  j  } n	 |  j } | j   } | j |  | j   | j   } xI | D]A } | j   } | j   | j   }	 |	 | k r] | j |  q] W| S)z@Return a list of UFWRules from the system based on template rule)r   r   r   r   r   rv   r+   )
r.   templaterw   r   r   Znormr   r   rD   Z	tmp_tupler5   r5   r6   get_app_rules_from_system  s     	

z,UFWBackendIptables.get_app_rules_from_systemc             C   s}   |  j  } | j d  r! |  j } t | g |  \ } } | d k ry t d |  } | rm t d |  n t |   d S)zPerform command on chainr   r   zCould not perform '%s'zFAILOK: N)r   r   r`   r   r9   r   r   )r.   r4   rb   fail_okr   rh   ra   rQ   r5   r5   r6   r     s    		zUFWBackendIptables._chain_cmdc       	   %   C   sL  |  j  r d S|  j   g  } y |  j |  } Wn t k
 rG   Yn Xy$ |  j d d  |  j d d  Wn< t k
 r   Yn( t k
 r t d  } t |  Yn X|  j   s d St d  } xt |  j d |  j d |  j d	 |  j d
 D]D } y |  j	 | d | d g  Wq t k
 r9t |   Yq Xq Wy^ xW |  j d |  j d	 |  j d
 D]2 } |  j	 | d | g  |  j	 | d | g  qeWWn t k
 rt |   Yn Xx | D] \ } } } d } t
 |  d k r| d d k rd } y\ | d k rIt
 |  d k rI|  j	 | d g | d d  d d |  j	 | | |  Wqt k
 r}t |   YqXqWx d d g D] } |  j d d r| d k s|  j d d r| d k r|  j	 | d | g |  j |  j d g d d |  j d d k r|  j	 | d | g |  j |  j d g d d qWd S)z#Update loglevel of running firewallNrw   FTz&Couldn't update rules file for loggingz!Could not update running firewallr   r   r   r   z-Lz-nz-Fz-Zr   z-Ddelete_firstrj   r   zufw-user-limitzufw6-user-limitr   r   r   rn   r   r   z-I)r/   r]   r   rH   r   r   r9   r   r)   r   r   r^   r,   r-   r:   )	r.   r   rules_trQ   rd   r   r   r   r4   r5   r5   r6   r     sl    	
2"'		z!UFWBackendIptables.update_loggingc       	      C   s  g  } | t  |  j j    k r= t d  | } t |   | d k r x7 |  j d D]( } | j | d | d d g d g  qW W| Sx7 |  j d D]( } | j | d | d d g d	 g  q Wd
 d d d d d g } |  j | |  j d k r#g  } |  j | |  j d k  r| } x |  j d D] } x d d d g D] } | j |  r=|  j |  d k s||  j |  d k rd } | j | d | d d d | g | d	 g  q=|  j | |  j d k r=d } | j | d | d d d | g | d	 g  q=Wq'Wg  } |  j | |  j d k  r+| } x |  j d D] } | j d  rWd } n | j d  rd } |  j | |  j d k  r| j | d | d
 d  d! d" d d g | d	 g  n8 | j | d | d
 d  d! d" d d d d# g
 | d	 g  | j | d | d d d | g | d	 g  q9W|  j | |  j d k rg  } |  j | |  j d$ k  rc| } |  j | |  j d k  rd
 d  d! d% g | } d& } xA |  j d' D]2 } | j | d | d d d | g | d	 g  qW| S)(z%Get rules for specified logging levelzInvalid log level '%s'r   r   z-Iz-jr   r   z-DrC   z-mr   z--limitz3/minz--limit-burstZ10r   Zhighr   r   r   r   r8   r>   z[UFW BLOCK] z-Ar   z--log-prefixZmediumz[UFW ALLOW] r   r=   Z	conntrackz	--ctstateZINVALIDz[UFW AUDIT INVALID] ZfullZNEWz[UFW AUDIT] r   )	r   r   r   r9   r   r)   r+   endswithr   )	r.   r   r   rQ   rd   r   Zlargsrg   r   r5   r5   r6   r     sx    &&			z%UFWBackendIptables._get_logging_rulesc             C   s  d } t  t j j |  j  } g  } x |  j D] } |  j | j d  sM q. | j |  j |  t j	 j
 | d t j	 j |  j |   } t j	 j |  s. t d  | } t |   q. Wt j d  } xL | D]D } d | | f } t j	 j |  r t d  | } t |   q WxZ | D]R } d | | f } | t d  d	 t j	 j |  d
 | i 7} t j | |  q#Wx | D] } d | | f } t j t j	 j
 | d t j	 j |   t j	 j |   t j | |  y  t j |  }	 |	 t j }
 Wn/ t k
 r1t d  | } t |  wYn X|
 t j @rV| t d  | 7} q|
 t j @r| t d  | 7} qW| S)zReset the firewallrC   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   r0   r   r+   r#   r$   r%   basenameisfiler9   r   timeZstrftimeexistsrenameshutilcopydirnameZcopymodestatST_MODErH   r   S_IWOTHS_IROTH)r.   resr   Zallfilesrf   fnrQ   Zextr   Zstatinfomoder   r5   r5   r6   resetY  sR     
zUFWBackendIptables.reset)__name__
__module____qualname____doc__r(   r<   rW   ri   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r5   r5   r5   r6   r
      s(   ,K]!DeJZr
   )r   r#   rI   r   r   r   r   Z
ufw.commonr   r   Zufw.utilr   r   r   r   r   r	   Zufw.backendr   r&   r'   r
   r5   r5   r5   r6   <module>   s   .